Java 图像比较 class - 添加偏移量
Java image comparing class - add offset
我在网上找到了这个 Java class 并且一直用它来比较图像。但是我想给它添加一个偏移量。因此,例如,如果两张图片的相似度为 99% 或 98%,我希望它 return 为真。
public int compareImage(File fileA, File fileB) {
try {
// take buffer data from botm image files //
BufferedImage biA = ImageIO.read(fileA);
DataBuffer dbA = biA.getData().getDataBuffer();
int sizeA = dbA.getSize();
BufferedImage biB = ImageIO.read(fileB);
DataBuffer dbB = biB.getData().getDataBuffer();
int sizeB = dbB.getSize();
// compare data-buffer objects //
if (sizeA == sizeB) {
for (int i = 0; i < sizeA; i++) {
if (dbA.getElem(i) != dbB.getElem(i)) {
return false;
}
}
return true;
} else {
return false;
}
} catch (Exception e) {
System.out.println("Failed to compare image files ...");
return 0;
}
}
最好的方法是什么?
要查看它们是 99% 还是 98% 相似,您必须比较所有像素,而不是在 dbA.getElem(i) != dbB.getElem(i)
的第一个实例中返回 false
试试计数器:
int total = 0;
int is_silimar = 0;
for (int i = 0; i < sizeA; i++) {
total++;
if (dbA.getElem(i) == dbB.getElem(i)) { //change it to ==
is_similar ++;
}
}
//don't return anything yet
然后,当 is_similar/total
为 98% 或 99%
时,您可以 return true
编辑:如果您想在图像尺寸也不同时测试用例,请将 sizeA 更改为 min(sizeA, sizeB)。
图像相似性有很多方法,其中一些需要高级 AI 算法。这个维基百科 post 提供逐像素的颜色距离图像比较(但它仅适用于相同大小的图像)。我只是从上面 link.
复制粘贴 Java 实现
*请注意,如果您想要绝对像素相等(而不是单个像素上的颜色距离),您应该只保留一个具有不同像素的计数器并且不需要距离检查。
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import java.io.IOException;
import java.net.URL;
public class ImgDiffPercent
{
public static void main(String args[])
{
BufferedImage img1 = null;
BufferedImage img2 = null;
try {
URL url1 = new URL("http://rosettacode.org/mw/images/3/3c/Lenna50.jpg");
URL url2 = new URL("http://rosettacode.org/mw/images/b/b6/Lenna100.jpg");
img1 = ImageIO.read(url1);
img2 = ImageIO.read(url2);
} catch (IOException e) {
e.printStackTrace();
}
int width1 = img1.getWidth(null);
int width2 = img2.getWidth(null);
int height1 = img1.getHeight(null);
int height2 = img2.getHeight(null);
if ((width1 != width2) || (height1 != height2)) {
System.err.println("Error: Images dimensions mismatch");
System.exit(1);
}
long diff = 0;
for (int y = 0; y < height1; y++) {
for (int x = 0; x < width1; x++) {
int rgb1 = img1.getRGB(x, y);
int rgb2 = img2.getRGB(x, y);
int r1 = (rgb1 >> 16) & 0xff;
int g1 = (rgb1 >> 8) & 0xff;
int b1 = (rgb1 ) & 0xff;
int r2 = (rgb2 >> 16) & 0xff;
int g2 = (rgb2 >> 8) & 0xff;
int b2 = (rgb2 ) & 0xff;
diff += Math.abs(r1 - r2);
diff += Math.abs(g1 - g2);
diff += Math.abs(b1 - b2);
}
}
double n = width1 * height1 * 3;
double p = diff / n / 255.0;
System.out.println("diff percent: " + (p * 100.0));
}
}
我在网上找到了这个 Java class 并且一直用它来比较图像。但是我想给它添加一个偏移量。因此,例如,如果两张图片的相似度为 99% 或 98%,我希望它 return 为真。
public int compareImage(File fileA, File fileB) {
try {
// take buffer data from botm image files //
BufferedImage biA = ImageIO.read(fileA);
DataBuffer dbA = biA.getData().getDataBuffer();
int sizeA = dbA.getSize();
BufferedImage biB = ImageIO.read(fileB);
DataBuffer dbB = biB.getData().getDataBuffer();
int sizeB = dbB.getSize();
// compare data-buffer objects //
if (sizeA == sizeB) {
for (int i = 0; i < sizeA; i++) {
if (dbA.getElem(i) != dbB.getElem(i)) {
return false;
}
}
return true;
} else {
return false;
}
} catch (Exception e) {
System.out.println("Failed to compare image files ...");
return 0;
}
}
最好的方法是什么?
要查看它们是 99% 还是 98% 相似,您必须比较所有像素,而不是在 dbA.getElem(i) != dbB.getElem(i)
试试计数器:
int total = 0;
int is_silimar = 0;
for (int i = 0; i < sizeA; i++) {
total++;
if (dbA.getElem(i) == dbB.getElem(i)) { //change it to ==
is_similar ++;
}
}
//don't return anything yet
然后,当 is_similar/total
为 98% 或 99%
return true
编辑:如果您想在图像尺寸也不同时测试用例,请将 sizeA 更改为 min(sizeA, sizeB)。
图像相似性有很多方法,其中一些需要高级 AI 算法。这个维基百科 post 提供逐像素的颜色距离图像比较(但它仅适用于相同大小的图像)。我只是从上面 link.
复制粘贴 Java 实现*请注意,如果您想要绝对像素相等(而不是单个像素上的颜色距离),您应该只保留一个具有不同像素的计数器并且不需要距离检查。
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import java.io.IOException;
import java.net.URL;
public class ImgDiffPercent
{
public static void main(String args[])
{
BufferedImage img1 = null;
BufferedImage img2 = null;
try {
URL url1 = new URL("http://rosettacode.org/mw/images/3/3c/Lenna50.jpg");
URL url2 = new URL("http://rosettacode.org/mw/images/b/b6/Lenna100.jpg");
img1 = ImageIO.read(url1);
img2 = ImageIO.read(url2);
} catch (IOException e) {
e.printStackTrace();
}
int width1 = img1.getWidth(null);
int width2 = img2.getWidth(null);
int height1 = img1.getHeight(null);
int height2 = img2.getHeight(null);
if ((width1 != width2) || (height1 != height2)) {
System.err.println("Error: Images dimensions mismatch");
System.exit(1);
}
long diff = 0;
for (int y = 0; y < height1; y++) {
for (int x = 0; x < width1; x++) {
int rgb1 = img1.getRGB(x, y);
int rgb2 = img2.getRGB(x, y);
int r1 = (rgb1 >> 16) & 0xff;
int g1 = (rgb1 >> 8) & 0xff;
int b1 = (rgb1 ) & 0xff;
int r2 = (rgb2 >> 16) & 0xff;
int g2 = (rgb2 >> 8) & 0xff;
int b2 = (rgb2 ) & 0xff;
diff += Math.abs(r1 - r2);
diff += Math.abs(g1 - g2);
diff += Math.abs(b1 - b2);
}
}
double n = width1 * height1 * 3;
double p = diff / n / 255.0;
System.out.println("diff percent: " + (p * 100.0));
}
}