21

I need a command line tool that compares 2 images and says if their contents are the same, regardless of encoding - i.e. one might be a *.bmp and the other might be a *.png, so long as all their width, height and all the corresponding pixels are the same.

  • Exact graphical sameness is needed
  • Compression loss, even if nearly invisible, makes a different image
  • Same alpha-transparency is also important
  • EXIF/etc irrelevant
  • 1
    Just to clarify, the metadata (e.g. EXIF) is not relevant, right? – Cristian Ciupitu Jul 13 '14 at 18:40
  • 1
    @CristianCiupitu Yes, just that the images display the same on any background (i.e. alpha-transparency is a difference). – sashoalm Jul 14 '14 at 9:01
16

With ImageMagick (apt-get install imagemagick), you can compare images independent of encoding and metadata like this:

identify -quiet -format "%#" images...

Note that images that have been encoded with lossy compression like JPEG (*.jpg) have subtle, often invisible changes.

See also ImageMagick Examples: Image Signatures.

Strictly speaking, you need to compare the color model, and scaling of pixel values, too. They may not be part of the metadata in the image.

| improve this answer | |
  • 2
    Great answer. Just to clarify though: this will print concatenated checksums for each image in images. Then you need to check whether these checksums are the same. – Clément Jul 10 '16 at 14:52
6

If you have MATLAB, you can use:

% Reading images as array to variable 'a' & 'b'. 
a = imread('MIMICDatacollection.bmp'); 
b = imread('MIMICDatacollection.png'); 

% Flatten multidimensional arrays to 1D
c=a(:);
d=b(:);

% Perform comparison
if length(c) ~= length(d)
    disp('The images do not have the same size') 
else
    e = corr2(c,d);           
    if e==1 
        disp('The images are same')
    else 
        disp('The images are not same') 
    end; 
end

Personally, I use it with PNG and BMP, but it should work for any format supported by imread.

If you need to run it on a machine that doesn't have Matlab, you can turn it into a function and compile it to make it CLI.

If you don't have Matlab that should be easy to port in any high-level language with a decent imaging library, such as Python Imaging Library (PIL).

Related: How can I tell if I am downloading/saving duplicate images?

| improve this answer | |
  • 2
    Wouldn't something like > 0.95 be better than == 1 to compensate for compression artifacts in case of lossy compression? – vsz Jul 14 '14 at 3:12
  • @vsz I haven't tried it but that sounds reasonable. – Franck Dernoncourt Jul 14 '14 at 3:29
  • @vsz Actually asker wants exactly the same graphically, so == 1 is correct. – Nicolas Raoul Jul 17 '14 at 5:43
3

findimagedupes - Finds visually similar or duplicate images

findimagedupes is a commandline utility which performs a rough "visual diff" to two images. This allows you to compare two images or a whole tree of images and determine if any are similar or identical. On common image types, findimagedupes seems to be around 98% accurate.

| improve this answer | |
  • 5
    Unfortunately doesn't work for my case as it reports visually similar (but not same) images as duplicates. I need it verify results of automated tests, so exact sameness is needed, not just similarity. – sashoalm Jul 13 '14 at 14:29
3

I eventually created a small Qt program that I called imgdiff, which takes 2 filenames and performs a pixel-by-pixel comparison. It will print out an error message if they differ and exit with 1, or silently exit with 0 if they are the same.

Example usage would be:

imgdiff img1.png img2.bmp

Link to the Google Code project - https://code.google.com/p/imgdiff/.

| improve this answer | |
1

Try dupeguru from here: https://dupeguru.voltaicideas.net/. In Picture mode it checks for similar images, even though they have different sizes, it has a threshold setting, creates groups of similar files, choosing the biggest file as main, but can be set another file for reference too. Is able to move files to some path or to the recycle bin or delete them completely. It is cross-platform.

Another interesting tool, that can be used for various merge operations too, is WinMerge: https://winmerge.org/. This has an interesting feature that highlights the difference areas in the images, but is able to compare up to three files at once, or three paths that contain files, but it compares the files having the same name only, if found on those paths. This is good for folder syncing. This is Windows only, runs fine in Wine, but there is a QT version available that seems to be in an early stage: https://github.com/OzzieIsaacs/winmerge-qt.

| improve this answer | |
  • Can you add details on the relevant features of such software? – Alejandro Jul 6 at 20:38
0

Let’s say you have a folder named before which contains original images, and a folder after which should contain visually identical images with the same file name. Using ImageMagick’s compare, you can do this:

for file in before/*.png; do
    result=$(compare -metric AE "${file}" "${file/before/after}" /tmp/diff.png 2>&1);
    if [ "${result}" != '0' ]; then
        echo "${result} incorrect pixels in ${file}";
    fi;
done;
| improve this answer | |
0

Might need tweaking to handle alpha channel appropriately but converting to ppm and checksumming seems to work:

#!/bin/bash

find "${@:-.}" -type f -print |\
while IFS= read -r file; do
    hash=$(convert 2>&- "${file}" -strip ppm:- | md5sum) 
    # we get this hash if convert fails and produces no output
    [ "$hash" = 'd41d8cd98f00b204e9800998ecf8427e  -' ] \
    || echo "$hash ${file}"
done |\
sort | uniq -w32 --all-repeated=separate | sed 's/^.\{36\}//'
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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