2

我要做的是计算图像的 2D DCT,Java然后将结果保存回文件。

读取文件:

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

谁能告诉我我做错了什么?或者,也许我在这里不明白什么?

4

1 回答 1

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和draw方法:

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);
}

我知道,我有点晚了,但我只是为我的程序做了所有这些。所以,让它在这里为那些从谷歌搜索到这里的人。

于 2013-09-27T21:51:22.180 回答