将彩色图像转换为数组[i] [j]

时间:2014-05-13 08:49:03

标签: java image matlab image-processing cross-correlation

我想使用Java计算两个图像之间的归一化互相关。

我的程序工作正常但是当我尝试在MATLAB中验证我的结果时,遗憾的是我没有得到与Java实现相同的结果。

这是我在MATLAB中执行的代码:

Img1 = rgb2gray(imread('image1.png'));
Img2 = rgb2gray(imread('image2.png'));
corr2(Img1, Img2);

这是我的Java实现的一部分。为了更好地理解,删除了一些类:

我不确定我的Java实现有什么问题。

我还有另一个问题。在MATLAB中,我必须在使用corr2之前将图像转换为灰度。我是否需要在Java中执行相同的操作?

1 个答案:

答案 0 :(得分:1)

之所以不相同,是因为您没有考虑PNG文件中的标题。

如果您查看Java代码,则会在readImage方法中将图像作为字节流读取。对于PNG,涉及标题,例如图像的大小和每个像素的颜色位数。您不仅要抓取图像数据(顺便说一下,使用LZW版本进行压缩,以便您甚至不读取原始图像数据),而且还要抓取相关代码中收集的额外信息。 。

令人困惑的是,您正在使用相关代码开头的BufferedImage类型读取图像,以获取行和列。为什么在readImage方法中切换到使用字节流?

因此,您需要更改readImage方法以接收BufferedImage对象,或重新读取您在readImage方法中的关联方法中所做的数据。完成后,使用BufferedImage方法访问RGB像素。 FWIW,如果你在图像中读取灰度,那么每个通道应该给你相同的强度,这样你就可以单独在一个通道上操作。无关紧要......但要确保你在灰度图像上做相关。当你去上色时,它是模棱两可的,因为目前没有设定标准如何做到这一点。

使用BufferedImage,您可以使用getRGB方法在列x和行y获取所需的像素。 x从左到右遍历,而y从上到下遍历。当您调用getRGB时,它将以ARGB格式返回单个32位整数。每个通道为8位。因此,前8位(MSB)是alpha值,后8位是红色,第3位是绿色,最后8位是蓝色。根据您想要的频道,您需要进行位移和掩盖您不需要的位来获得所需的值。

举个例子:

int rgb = img.getRGB(x, y);
int alpha = rgb >> 24 & 0xFF;
int red = rgb >> 16 & 0xFF;
int green = rgb >> 8 & 0xFF;
int blue = rgb & 0xFF;    

对于alpha值,您需要向右移动24位以使其向下移动到LSB位置,然后使用0xFF进行屏蔽以仅获得表示alpha值的8位。同样地,您可以对红色,绿色和蓝色通道执行相同操作。由于彩色图像的相关性相当不合适,因此我们可以在readImage方法中将图像转换为灰度。因此,在运行此方法之前无需转换图像。我们将在方法本身内做到这一点,为您省去一些麻烦。

如果你看看MATLAB如何执行rgb2gray,它会执行一个加权和,以不同的方式对通道进行加权。权重由SMPTE Rec. 601 standard定义(对于那些想知道我如何知道这一点的人,你可以看一下rgb2gray的来源并读出他们转换矩阵的第一行这些系数基本上是601标准的定义。

以前版本的MATLAB简单地将所有频道相加,除以3并发言。我不知道您使用的是哪个版本的MATLAB,但为了安全起见,我将使用最新的转换。

public static void readImage(BufferedImage img, int array[][], int nrows, int ncols) {
      for (int i = 0; i < nrows; i++)
           for (int j = 0; j < ncols; j++) {
                int rgb = img.getRGB(j, i);
                int red = rgb >> 16 & 0xFF;
                int green = rgb >> 8 & 0xFF;
                int blue = rgb & 0xFF;
                array[i][j] = (int) (0.299*((double)red) + 0.587*((double)green) + 
                               0.114*((double)blue) );
           }
}

这应该有希望给你你想要的东西!