使用JTransform - Java的缓冲图像的DCT

时间:2015-03-28 17:15:43

标签: java image-processing

我试图使用JTransform获取bufferedImage的DCT。当我将变换可视化时,它目前看起来像http://tinypic.com/r/2vcxhzo/8

为了使用Jtransform,我需要将BufferedImage转换为2d双数组。我尝试了两种不同的方法将bufferedImage更改为双数组

    public double[][] convertTo2DArray(BufferedImage image) {

        final byte[] pixels = ((DataBufferByte) image.getRaster()
        .getDataBuffer()).getData();
        final int width = image.getWidth();
        final int height = image.getHeight();

        double[][] result = new double[height][width];

        final boolean hasAlphaChannel = image.getAlphaRaster() != null;
        if (hasAlphaChannel) {
           final int pixelLength = 4;
           for (int pixel = 0, row = 0, col = 0; pixel < pixels.length; pixel += pixelLength) {
               int argb = 0;
               argb += (((int) pixels[pixel] & 0xff) << 24); // alpha
               argb += ((int) pixels[pixel + 1] & 0xff); // blue
               argb += (((int) pixels[pixel + 2] & 0xff) << 8); // green
               argb += (((int) pixels[pixel + 3] & 0xff) << 16); // red
               result[row][col] = argb;
               col++;
            if (col == width) {
                col = 0;
                row++;
            }
        }
       } else {
          final int pixelLength = 3;
          for (int pixel = 0, row = 0, col = 0; pixel < pixels.length; pixel += pixelLength) {
            int argb = 0;
            argb += -16777216; // 255 alpha
            argb += ((int) pixels[pixel] & 0xff); // blue
            argb += (((int) pixels[pixel + 1] & 0xff) << 8); // green
            argb += (((int) pixels[pixel + 2] & 0xff) << 16); // red
            result[row][col] = argb;
            col++;
            if (col == width) {
                col = 0;
                row++;
            }
        }
    }

    return result;
}

我也试过

private double[][] bufferedImageToArray(BufferedImage image) {
    int h = image.getHeight();
    int w = image.getWidth();
    int[][] array = new int[h][w];
    double[][] result;    

    for (int count = 0; count < h; count++) {
        for (int loop = 0; loop < w; loop++) {

            int gray = image.getRGB(loop, count) & 0xFF;

            // add values to array
            array[count][loop] = gray;
        }
    }
    result = toDoubleArray(array);
    return result;
}

我已将变换实现为

public double[][] applyDCT(double[][] image) {

    DoubleDCT_2D transform = new DoubleDCT_2D(image.length, image[0].length);

    transform.forward(image, true);

    return image;
}

我尝试使用OpenCV的dct转换,但它提供了与链接中显示的相同的输出。

1 个答案:

答案 0 :(得分:0)

类似的东西(为了简单起见,我只保留了蓝色通道)。它显示了结果图像左上角的能量压缩。

import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Image;
import java.awt.Transparency;
import java.awt.image.BufferedImage;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;

public class TestDCT
{
  public static void main(String[] args)
  {
    ImageIcon icon = new ImageIcon(args[0]);
    Image image = icon.getImage();
    int w = image.getWidth(null);
    int h = image.getHeight(null);
    GraphicsDevice gs = GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices()[0];
    GraphicsConfiguration gc = gs.getDefaultConfiguration();
    BufferedImage img = gc.createCompatibleImage(w, h, Transparency.OPAQUE);
    img.getGraphics().drawImage(image, 0, 0, null);
    int[] rgb1 = new int[w*h];
    img.getRaster().getDataElements(0, 0, w, h, rgb1);
    double[] array = new double[w*h];

    for (int i=0; i<w*h; i++)
       array[i] = (double) (rgb1[i] & 0xFF);

    org.jtransforms.dct.DoubleDCT_2D tr = new org.jtransforms.dct.DoubleDCT_2D(w, h);
    tr.forward(array, true);

    for (int i=0; i<w*h; i++)
    {
       // Grey levels
       int val= Math.min((int) (array[i]+128), 255);
       rgb1[i] = (val <<16) | (val << 8) | val;
    }

    img.getRaster().setDataElements(0, 0, w, h, rgb1);
    icon = new ImageIcon(img);
    JFrame frame = new JFrame("FFT");
    frame.setBounds(20, 30, w, h);
    frame.add(new JLabel(icon));
    frame.setVisible(true);
  }

}