35
\$\begingroup\$

For example, for a recent conversation about JPEG compression I wanted to compare pixel for pixel what changed between two JPEGs (one with compression level 100, and one with compression level 95).

How do I generate good visual maps of what changed without tedious custom software programing?

\$\endgroup\$
1
  • 3
    \$\begingroup\$ Not submitting this as an answer as it's probably not a viable solution for photos, but GitHub (a programmer's site) has some interesting ways of comparing images: github.com/cameronmcefee/Image-Diff-View-Modes/commit/… Try clicking "2-up", "Swipe", "Onion Skin" and "Difference". \$\endgroup\$
    – Henrik N
    May 6, 2011 at 12:19

6 Answers 6

42
\$\begingroup\$

Photoshop + Layers FTW. (Yes, you can also use the Gimp, or any other editing software with the same functions.)

Start with your base image, in the case above, I used the jpeg quality 100 image.

  1. create a new layer atop it
  2. paste the second image into that layer
  3. set the layer style to "difference" (see left pink arrow in 1st image below)
  4. create an effect layer atop that (Layer>New Adjustment Layer>Threshold)
  5. set the effect to threshold (see right pink arrow in 1st image below)
  6. set the threshold value to 1

In the resulting image, any pixel that is any any way different between the two images will be white. You can adjust it to allow things to be "a little different" by altering the threshold value.

Example showing a LOT of difference between jpeg 92 and 100 from Lightroom. comparing jpeg 92 and 100 from LR with Photoshop layers

Example showing no difference at all between 95 and 100. comparing jpeg 95 and 100 from LR with Photoshop layers

Not that's just showing a binary "changed or not", what if you wanted more detail on how much it changed, say by color channel?

  1. replace the threshold adjustment layer with a curves adjustment layer.
  2. edit the curve
  3. turn on show clipping
  4. grab the input white handle below the lower right corner and drag it over to the left, as far as you can go
  5. slowly move back to the right until you don't see any clipping (the preview image is all black)
  6. turn clipping back off and save the curve change

The brighter the resulting pixels, the more they're different in that color. The downside though is you end up with a lot of grey mud... so sometimes it's easier to just threshold it to see where differences are. That's why I build both and toggle which one is visible.

more descriptive view of the difference

\$\endgroup\$
1
  • \$\begingroup\$ Newb question, but how to do you do step 4, "create an effect layer atop that"? Can't find it anywhere. It's also 7 years later and I'm using the latest version for perrhaps they've changed the name also? \$\endgroup\$ May 4, 2018 at 23:02
18
\$\begingroup\$

All image processing packages should make this easy. I'll show you how to do it in Mathematica, if you have access to this system. Mathematica is a programming language, but it's really easy to do these kinds of manipulations, so if you have access to it (e.g. through a university site license), I recommend you give it a go!

First, import the image:

img = Import["http://farm1.staticflickr.com/62/171463865_36ee36f70e.jpg"]

Recompress it using JPEG compression

img2 = ImportString@ExportString[img, "JPEG", "CompressionLevel" -> 0.35]

Mathematica graphics

Now take the difference of pixel values, converting them first to floating point numbers to ensure that negative values are preserved.

diff = ImageSubtract[Image[img, "Real"], Image[img2, "Real"]]

Mathematica graphics

Not much is visible on the difference image (the difference is tiny), and negative values are clipped to black. So let's rescale all values to fill the whole dynamic range (the minimum will be scaled to 0, the maximum to 1):

ImageAdjust[diff]

Mathematica graphics

ImageDifference gives the absolute difference of the two images, and produces no negative numbers. This is the operation you are more likely to find in image processing packages, especially GUI ones (Photoshop, GIMP).

ImageDifference[img, img2]

Mathematica graphics

We can also take a single RGB channel, for example the red one, and visualize the positive and negative differences using 'opposing' colours:

ArrayPlot[0.5 + ImageData[First@ColorSeparate[diff, "Red"]], 
 ColorFunction -> "RedGreenSplit", ColorFunctionScaling -> False]

Mathematica graphics

Here's the same thing, with the differences amplified 5 times. The JPEG artefacts are more recognizable now.

ArrayPlot[0.5 + 5 ImageData[First@ColorSeparate[diff, "Red"]], 
 ColorFunction -> "RedGreenSplit", ColorFunctionScaling -> False]

Mathematica graphics

The advantage of using a programming language is that we can easily automate this and see how the difference changes for "compression levels" between 0.1 and 1.0:

Grid@Partition[Table[
   ArrayPlot[
    0.5 + ImageData[
      First@ColorSeparate[
        ImageSubtract[Image[img, "Real"], 
         Image[ImportString@
           ExportString[img, "JPEG", "CompressionLevel" -> c], 
          "Real"]], "Red"]], ColorFunction -> "RedGreenSplit", 
    ColorFunctionScaling -> False],
   {c, 0.1, 1, 0.1}
   ], 5]

Mathematica graphics

\$\endgroup\$
1
  • \$\begingroup\$ Its always good to see a scripted/automated option! :) \$\endgroup\$
    – jrista
    Aug 8, 2012 at 18:22
15
\$\begingroup\$

If you use Photoshop, here's how I'd do it:

Put the two jpegs in the same psd file, in two separate layers. They should overlap exactly, since their dimensions are the same. (which one goes on top doesn't matter).

Set the layer blending mode to "Difference." You'd see a mostly black result. Depends on the quality difference between the two original layers you may see more or less of the noise.

enter image description here

\$\endgroup\$
8
  • \$\begingroup\$ Difference alone doesn't really help much when you're left with a big black void like that. :) \$\endgroup\$
    – cabbey
    May 6, 2011 at 7:15
  • \$\begingroup\$ @cabbey sure, comparing 100% to 95% you most likely will get a solid black. But that's what your question was asking isn't it? In your owner answer, you're changing the values from the originals being compared, which makes them no longer having the original compression settings. \$\endgroup\$
    – Jin
    May 6, 2011 at 7:20
  • \$\begingroup\$ You get virtually solid black on just about any comparison, because the differences are so small. The threshold/curve layer after the difference doesn't do anything to the compression settings, it just aids the visualization of the lower bounds of that black soup that difference prepared. (I'm not 100% sure what you meant by that, so I could be heading off in a different direction there....) \$\endgroup\$
    – cabbey
    May 6, 2011 at 7:31
  • \$\begingroup\$ @cabbey if you're asking for a pure bit-wise operation of the difference between the 2 images, then "Difference" blending mode alone gives you that. When you adjust threshold/curve, though the result is more obvious to the naked eye, but it's not an accurate representation of what has changed. When do you that, you're not longer comparing a 100% to a 95%. \$\endgroup\$
    – Jin
    May 6, 2011 at 7:36
  • \$\begingroup\$ Sure you are. The level of compression stopped mattering the second photoshop loaded the image from disk into it's internal buffers, it is now an uncompressed pixel array in memory... if those pixels got there because the image had a square blob there or because they are an artifact of the compression level is not relevant. \$\endgroup\$
    – cabbey
    May 6, 2011 at 7:42
7
\$\begingroup\$

You can use Imagemagick command line tools.

composite imagesrc1.jpg imagesrc2.jpg -compose difference diffs.jpg

will provide the absolute value of differences for each RGB channel.

\$\endgroup\$
1
\$\begingroup\$
  1. Open one of the images in GIMP or Photoshop.
  2. Add the second image as a new layer on top of the first one.
  3. Set the blend mode of the top layer to "Difference"

In the resulting image the black parts show where the original images are identical and anything lighter shows differences.

\$\endgroup\$
2
  • \$\begingroup\$ Difference alone doesn't really help much when you're left with a big black void like that. :) \$\endgroup\$
    – cabbey
    May 6, 2011 at 7:15
  • \$\begingroup\$ You can always adjust the levels on the resulting image. Whenever I've used this technique I've had pictures different enough to be able to see the changes :) \$\endgroup\$
    – Dan
    May 6, 2011 at 10:27
1
\$\begingroup\$

GitHub has some interesting image diff tools built into it on the web, as described here and demonstrated in this demo.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.