使用JTransform-Java对缓冲图像进行DCT



我正在尝试使用JTransform获取缓冲区图像的DCT。当我可视化转换时,它目前看起来是这样的http://tinypic.com/r/2vcxhzo/8

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

    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变换,但它给出的输出与链接中所示的相同。

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

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

}

最新更新