我有 2 个主图像,我想将一组其他图像与它们进行比较。 我所做的是计算这两个图像的字节数组,然后将这两个图像与当前正在处理的图像进行比较。这是 2 张主图:
File upper = new File("sweater.jpg");
byte [] upperPart = Files.readAllBytes(upper.toPath());
File lower = new File("pants.jpg");
byte [] lowerPart = Files.readAllBytes(lower.toPath());
然后在处理目录中所有图像的循环中,我执行以下操作:
byte [] currentImage = Files.readAllBytes(f.toPath());
float differenceUpper = 0;
float differenceLower = 0;
for (int i=0;i< currentImage.length;i++) {
differenceUpper += (upperPart[i] - currentImage[i])^2;
differenceLower += (lowerPart[i] - currentImage[i])^2;
}
float euclideanDistanceUpper = (float) Math.sqrt(differenceUpper);
float euclideanDistanceLower = (float) Math.sqrt(differenceLower);
if (euclideanDistanceUpper < euclideanDistanceLower){
filename = filename + "Upper";
} else {
filename = filename + "Lower";
}
但是,使用 UpperImage 计算欧氏距离效果很好,但与 lowerImage 相比则不起作用。出现以下错误:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 55881
at org.apache.commons.io.ShapeRecognition.main(ShapeRecognition.java:54)
图像大小都是相同的,所以我真的不明白为什么它适用于上部而不适用于下部。有什么提示吗?谢谢!
更新 所以基本上问题是即使图像大小相同,生成的字节数组大小也不同。
最佳答案
关于分辨率,图像的尺寸可能相同(例如,它们可能都是 800x600 像素)。但您不是在比较图像,而是文件。而且……无论如何,以这种方式比较图像是没有意义的。两个大小为 800x600 的 JPG 图像文件的大小可能为 10 KB 或 50 KB。这取决于图像内容和压缩级别。
您(最有可能...)想要做的是比较图像的像素。因此,您必须使用ImageIO
读取图像,并对JPG文件解码以获得实际的像素数据。
您可以使用以下方式阅读图像
BufferedImage upper = ImageIO.read(new File("upper.jpg"));
BufferedImage lower = ImageIO.read(new File("lower.jpg"));
然后,要比较图像,您必须计算像素的差异。这并非小事。对于像素来说,没有通用的、普遍适用的“距离度量”。一种简单的方法可能是迭代两个图像的像素,并计算类似的内容
int argb0 = image0.getRGB(x, y);
int argb1 = image1.getRGB(x, y);
int a0 = (argb0 >> 24) & 0xFF;
int r0 = (argb0 >> 16) & 0xFF;
int g0 = (argb0 >> 8) & 0xFF;
int b0 = (argb0 ) & 0xFF;
int a1 = (argb1 >> 24) & 0xFF;
int r1 = (argb1 >> 16) & 0xFF;
int g1 = (argb1 >> 8) & 0xFF;
int b1 = (argb1 ) & 0xFF;
int aDiff = Math.abs(a1 - a0);
int rDiff = Math.abs(r1 - r0);
int gDiff = Math.abs(g1 - g0);
int bDiff = Math.abs(b1 - b0);
获取红色、绿色、蓝色和 Alpha channel 的差异,并将这些差异加在一起以获得稍后计算平方根的值。
<小时/>旁注:您计算了
differenceUpper += (upperPart[i] - currentImage[i])^2;
但请注意,^2
并不计算幂,正如您所期望的那样。您可以使用 Math.pow(difference, 2) ,但最好是类似的东西
differenceSum += difference * difference;
关于java - 计算2字节数组的欧氏距离java,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29078392/