突出显示图像之间的差异

时间:2014-07-29 18:34:08

标签: java image image-processing pixel pixels

我应修改此图像比较代码以突出显示/指出两个图像之间的差异。有没有办法修改此代码,以突出显示图像的差异。如果没有任何关于如何去做的建议将不胜感激。

 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 i = 0; i < height1; i++) {
                for (int j = 0; j < width1; j++) {
                    int rgb1 = img1.getRGB(j, i);
                    int rgb2 = img2.getRGB(j, i);
                    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;
            return (p * 100.0);

2 个答案:

答案 0 :(得分:17)

这个解决方案对我有用。它强调了差异,并且在我尝试的方法中具有最佳性能。 (假设:图像大小相同。此方法尚未使用透明胶片进行测试。)

将1600x860 PNG图像进行50次比较的平均时间(在同一台机器上):

  • JDK7~178毫秒
  • JDK8~139毫秒

有没有人有更好/更快的解决方案?

public static BufferedImage getDifferenceImage(BufferedImage img1, BufferedImage img2) {
    // convert images to pixel arrays...
    final int w = img1.getWidth(),
            h = img1.getHeight(), 
            highlight = Color.MAGENTA.getRGB();
    final int[] p1 = img1.getRGB(0, 0, w, h, null, 0, w);
    final int[] p2 = img2.getRGB(0, 0, w, h, null, 0, w);
    // compare img1 to img2, pixel by pixel. If different, highlight img1's pixel...
    for (int i = 0; i < p1.length; i++) {
        if (p1[i] != p2[i]) {
            p1[i] = highlight;
        }
    }
    // save img1's pixels to a new BufferedImage, and return it...
    // (May require TYPE_INT_ARGB)
    final BufferedImage out = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
    out.setRGB(0, 0, w, h, p1, 0, w);
    return out;
}

<强>用法:

import javax.imageio.ImageIO;
import java.io.File;

ImageIO.write(
        getDifferenceImage(
                ImageIO.read(new File("a.png")),
                ImageIO.read(new File("b.png"))),
        "png",
        new File("output.png"));

Some inspiration...

答案 1 :(得分:9)

我要做的是将每个像素设置为一个图像中的一个像素与另一个图像中的相应像素之间的差异。原始代码中计算的差异基于L1 norm。这也称为sum of absolute differences。在任何情况下,编写一个可以接收两个图像的方法,并返回相同大小的图像,将每个位置设置为在最终图像中共享相同位置的每对像素的差异。基本上,这将为您提供哪些像素不同的指示。像素越白,这两个相应位置之间的差异就越大。

我也会假设您正在使用BufferedImage类,因为使用了getRGB()方法,并且您正在进行位移以访问各个频道。换句话说,制作一个如下所示的方法:

public static BufferedImage getDifferenceImage(BufferedImage img1, BufferedImage img2) {
    int width1 = img1.getWidth(); // Change - getWidth() and getHeight() for BufferedImage
    int width2 = img2.getWidth(); // take no arguments
    int height1 = img1.getHeight();
    int height2 = img2.getHeight();
    if ((width1 != width2) || (height1 != height2)) {
        System.err.println("Error: Images dimensions mismatch");
        System.exit(1);
    }

    // NEW - Create output Buffered image of type RGB
    BufferedImage outImg = new BufferedImage(width1, height1, BufferedImage.TYPE_INT_RGB);

    // Modified - Changed to int as pixels are ints
    int diff;
    int result; // Stores output pixel
    for (int i = 0; i < height1; i++) {
        for (int j = 0; j < width1; j++) {
            int rgb1 = img1.getRGB(j, i);
            int rgb2 = img2.getRGB(j, i);
            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); // Change
            diff += Math.abs(g1 - g2);
            diff += Math.abs(b1 - b2);
            diff /= 3; // Change - Ensure result is between 0 - 255
            // Make the difference image gray scale
            // The RGB components are all the same
            result = (diff << 16) | (diff << 8) | diff;
            outImg.setRGB(j, i, result); // Set result
        }
    }

    // Now return
    return outImg;
}

要调用此方法,只需执行以下操作:

outImg = getDifferenceImage(img1, img2);

这假设您在班级的方法中调用此方法。玩得开心,祝你好运!