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;

    }

float 配列に変換:

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

怠惰なための brightRGB と 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 に答える