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

Java 将彩色图像转换为数组[i][j],java,image,matlab,image-processing,cross-correlation,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实现出了什么问题 我还有一个

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

我的程序运行得很好,但当我试图在MATLAB中验证我的结果时,不幸的是,我没有得到与Java实现相同的结果

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

Img1 = rgb2gray(imread('image1.png'));
Img2 = rgb2gray(imread('image2.png'));
corr2(Img1, Img2);
这是我的Java实现的一部分。为了更好地理解,删除了一些类:

我不确定我的Java实现出了什么问题


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

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

如果您查看Java代码,您将在
readImage
方法中以字节流的形式读取图像。对于PNG,有一些涉及的标题,例如图像的大小和每个像素有多少颜色位。您不仅要获取图像数据(顺便说一句,它是使用LZW版本压缩的,因此您甚至不需要读取原始图像数据),而且还要获取在相关代码中收集的额外信息

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

因此,您需要更改
readImage
方法以接收
buffereImage
对象,或者像在
readImage
方法中的相关方法一样重新读取数据。完成此操作后,使用
buffereImage
方法访问RGB像素。FWIW,如果你在图像中读取灰度,那么每个通道都应该给你相同的强度,这样你就可以单独操作一个通道。不管是哪一个。。。。但要确保你在灰度图像上做相关。当你选择颜色时,它是不明确的,因为目前还没有关于如何做到这一点的标准

使用
BufferedImage
,您可以使用
getRGB
方法在列
x
和行
y
处获得所需的像素
x
从左到右遍历,而
y
从上到下遍历。调用
getRGB
时,它将以ARGB格式返回单个32位整数。每个通道为8位。因此,前8位(MSB)是alpha值,第二8位是红色,第三8位是绿色,最后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
,它会执行加权和,对通道进行不同的加权。权重由定义(对于那些想了解我是如何知道这一点的人,可以查看
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) );
           }
}
publicstaticvoidreadimage(BufferedImage-img,int-array[][],int-nrows,int-ncols){
对于(int i=0;i>16&0xFF;
int绿色=rgb>>8&0xFF;
蓝色整数=rgb&0xFF;
数组[i][j]=(int)(0.299*((双)红)+0.587*((双)绿)+
0.114*((双)蓝));
}
}

这应该会给你你想要的

您确实需要在问题中添加Java代码和Matlab代码。请编辑您的问题并添加此信息(不要将其添加到评论或链接中)现在更清楚了吗?@user3475463:如果您在RGB和灰度图像上计算腐蚀一次,则不能期望相同的输出。您的代码似乎不完整,我找不到
computeCorrelationCovertifier
的定义哦,对不起,我弄错了。。ComputeCorrelationConference和ComputeCorrelation是相同的,CorrelationUtils是具有ComputeCorrelationFirst方法的java类,感谢您的回答:)因此,现在我应该将图像转换为灰度,然后使用BuffereImage对象更改我的readImage方法。。我应该改变我的计算相关方法吗?如果我要处理灰度图像,就不需要使用getRGB来访问像素了?不客气。如果正确读取像素,则无需更改相关方法中的任何内容。您需要使用getRGB访问像素数据,因为这是获取图像数据的唯一方法。不过,您需要从像素数据中屏蔽出所需的通道。我将编辑我的答案以向您展示。非常感谢:D在我等待的时候,我编写了这段代码,但现在我将尝试您的示例。我仍然不明白的是,如果我在