突出显示图像之间的差异

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

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

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

我还假设您正在使用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); 

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

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

将1600×860 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")); 

一些灵感......