Highlight differences between images

There is a comparison code for this image. I have to change to highlight / indicate the difference between the two images. Is there a way to modify this code to emphasize differences in images. If there were no suggestions on how to do this, we will be very grateful.

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); 
+6
source share
2 answers

I would put each pixel in the difference between one pixel in one image and the corresponding pixel in another image. The difference that is calculated in your source code is based on L 1 norm . This is also called the sum of the absolute differences . In any case, write a method that will be used in your two images, and return an image of the same size that sets each location to a difference for each pair of pixels that have the same location in the final image. Basically, this will give you an idea of ​​which pixels are different. The whiter the pixel, the greater the difference between these two corresponding locations.

I also assume that you are using the BufferedImage class, as the getRGB() methods are used, and you shift the bit to access individual channels. In other words, create a method that looks like this:

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

To call this method, simply do:

 outImg = getDifferenceImage(img1, img2); 

This assumes that you are calling this as part of the method of your class. Good luck and good luck!

+9
source

This solution helped me. It highlights the differences and has the best performance from the methods I tried. (Assumptions: Images are the same size. This method has not been tested on transparencies.)

Average time to compare PNG images 1600x860 50 times (on one computer):

  • JDK7 ~ 178 milliseconds
  • JDK8 ~ 139 milliseconds

Does anyone have a better / quick solution?

 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 pixel... for (int i = 0; i < p1.length; i++) { if (p1[i] != p2[i]) { p1[i] = highlight; } } // save img1 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; } 

Application:

 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 ...

+15
source

Source: https://habr.com/ru/post/973060/


All Articles