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