2012-05-29 48 views
2

我想要做的是在Java中計算圖像的2D DCT,然後將結果保存迴文件。使用jTransforms的PNG的DCT2 012Transforms

讀文件:

coverImage = readImg(coverPath); 
private BufferedImage readImg(String path) { 

     BufferedImage destination = null; 

     try { 

      destination = ImageIO.read(new File(path)); 

     } catch (IOException e) { 

      e.printStackTrace(); 

     } 

     return destination; 

    } 

轉換爲浮動陣列:

cover = convertToFloatArray(coverImage); 
private float[] convertToFloatArray(BufferedImage source) { 

     securedImage = (WritableRaster) source.getData(); 

     float[] floatArray = new float[source.getHeight() * source.getWidth()]; 
     floatArray = securedImage.getPixels(0, 0, source.getWidth(), source.getHeight(), floatArray); 

     return floatArray; 

    } 

運行DCT:

runDCT(cover, coverImage.getHeight(), coverImage.getWidth()); 
private void runDCT(float[] floatArray, int rows, int cols) { 

     dct = new FloatDCT_2D(rows, cols); 

     dct.forward(floatArray, false); 

     securedImage.setPixels(0, 0, cols, rows, floatArray); 

    } 

然後將其保存爲圖像:

convertDctToImage(securedImage, coverImage.getHeight(), coverImage.getWidth()); 
private void convertDctToImage(WritableRaster secured, int rows, int cols) { 

     coverImage.setData(secured); 

     File file = new File(securedPath); 
     try { 
      ImageIO.write(coverImage, "png", file); 
     } catch (IOException ex) { 
      Logger.getLogger(DCT2D.class.getName()).log(Level.SEVERE, null, ex); 
     } 

    } 

但我得到的是:http://kyle.pl/up/2012/05/29/dct_stack.png

有誰能告訴我我做錯了什麼嗎?或者,也許我在這裏不明白什麼?

回答

0

這是一段代碼,爲我的作品:

//reading image 
BufferedImage image = javax.imageio.ImageIO.read(new File(filename)); 

//width * 2, because DoubleFFT_2D needs 2x more space - for Real and Imaginary parts of complex numbers 
double[][] brightness = new double[img.getHeight()][img.getWidth() * 2]; 

//convert colored image to grayscale (brightness of each pixel) 
for (int y = 0; y < image.getHeight(); y++) { 
    raster.getDataElements(0, y, image.getWidth(), 1, dataElements); 
    for (int x = 0; x < image.getWidth(); x++) { 
     //notice x and y swapped - it's JTransforms format of arrays 
     brightness[y][x] = brightnessRGB(dataElements[x]); 
    } 
} 

//do FT (not FFT, because FFT is only* for images with width and height being 2**N) 
//DoubleFFT_2D writes data to the same array - to brightness 
new DoubleFFT_2D(img.getHeight(), img.getWidth()).realForwardFull(brightness); 

//visualising frequency domain 
BufferedImage fd = new BufferedImage(img.getWidth(), img.getHeight(), BufferedImage.TYPE_INT_RGB); 
outRaster = fd.getRaster(); 
for (int y = 0; y < img.getHeight(); y++) { 
    for (int x = 0; x < img.getWidth(); x++) { 
     //we calculate complex number vector length (sqrt(Re**2 + Im**2)). But these lengths are to big to 
     //fit in 0 - 255 scale of colors. So I divide it on 223. Instead of "223", you may want to choose 
     //another factor, wich would make you frequency domain look best 
     int power = (int) (Math.sqrt(Math.pow(brightness[y][2 * x], 2) + Math.pow(brightness[y][2 * x + 1], 2))/223); 
     power = power > 255 ? 255 : power; 
     //draw a grayscale color on image "fd" 
     fd.setRGB(x, y, new Color(c, c, c).getRGB()); 
    } 
} 

draw(fd); 

生成的圖像看起來應該像在中間大黑色空間與白色斑點在所有四個角落。通常人們將FD可視化,零頻出現在圖像的中心。所以,如果你需要經典的FD(一個,看起來像明星的現實生活中的圖片),您需要升級「fd.setRGB(X,Y ......」了一下:

int w2 = img.getWidth()/2; 
int h2 = img.getHeight()/2; 
int newX = x + w2 >= img.getWidth() ? x - w2 : x + w2; 
int newY = y + h2 >= img.getHeight() ? y - h2 : y + h2; 

fd.setRGB(newX, newY, new Color(power, power, power).getRGB()); 

brightnessRGB和繪製方法懶惰:。

public static int brightnessRGB(int rgb) { 
    int r = (rgb >> 16) & 0xff; 
    int g = (rgb >> 8) & 0xff; 
    int b = rgb & 0xff; 
    return (r+g+b)/3; 
} 
private static void draw(BufferedImage img) { 
    JLabel picLabel = new JLabel(new ImageIcon(img)); 
    JPanel jPanelMain = new JPanel(); 
    jPanelMain.add(picLabel); 
    JFrame jFrame = new JFrame(); 
    jFrame.add(jPanelMain); 
    jFrame.pack(); 
    jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    jFrame.setVisible(true); 
} 

我知道,我是有點晚了,但我只是做了所有該爲我的程序,所以,讓它在這裏爲那些,誰就會從谷歌上搜索到這裏