Инструмент командной строки, чтобы проверить, являются ли два изображения одинаковыми графически

Мне нужен инструмент командной строки, который сравнивает 2 изображения и говорит, одинаково ли их содержимое, независимо от кодировки, т.е. одно может быть *.bmp, а другое может быть *.png, при условии, что вся их ширина, высота и все соответствующие пиксели одинаковы.

  • Требуется точное графическое сходство
  • Потеря сжатия, даже если она почти незаметна, делает изображение другим.
  • Та же альфа-прозрачность также важна
  • EXIF/и т.д. не имеет значения
Просто чтобы уточнить, метаданные (например, EXIF ) не имеют значения, верно?
@CristianCiupitu Да, просто изображения отображаются одинаково на любом фоне (т.е. альфа-прозрачность - это разница).

Ответы (7)

С помощью ImageMagick ( apt-get install imagemagick) вы можете сравнивать изображения независимо от кодировки и метаданных следующим образом:

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

Обратите внимание, что изображения, которые были закодированы со сжатием с потерями, такими как JPEG (*.jpg), имеют тонкие, часто невидимые изменения.

См. также Примеры ImageMagick: подписи изображений .

Строго говоря, нужно сравнивать и цветовую модель, и масштабирование значений пикселей тоже. Они могут не входить в метаданные изображения.

Отличный ответ. Просто чтобы уточнить: это будет печатать конкатенированные контрольные суммы для каждого изображения в формате images. Затем нужно проверить, совпадают ли эти контрольные суммы.
Не работает при сравнении двух визуально идентичных PNG, один из которых представляет собой палитру ( 8-bit colormap), а другой — полный RGBA ( 8-bit/color RGBA). Они не показывают никакой разницы с ImageMagick: compare -dissimilarity-threshold 1 palette.png rgba.png difference.pngно эти контрольные суммы разные.
@int_ua Спасибо! Вы хотите внести изменения, чтобы добавить его в качестве примечания в конец? (Или я должен)
Пожалуйста, сделайте это, возможно, добавьте ссылку на другой ответ, который сработал в моем случае: softwarerecs.stackexchange.com/a/42004/71752

Если у вас есть MATLAB, вы можете использовать:

% 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

Лично я использую его с PNG и BMP, но он должен работать для любого формата, поддерживаемого imread.

Если вам нужно запустить его на машине, на которой нет Matlab, вы можете превратить его в функцию и скомпилировать, чтобы сделать его CLI.

Если у вас нет Matlab, его будет легко портировать на любой язык высокого уровня с приличной библиотекой изображений, такой как Python Imaging Library (PIL).

Связанный: Как узнать, загружаю ли я дубликаты изображений?

Разве не > 0.95было бы лучше == 1компенсировать артефакты сжатия в случае сжатия с потерями?
@vsz Я не пробовал, но звучит разумно.
@vsz На самом деле спрашивающий хочет точно такого же графического изображения, так что == 1это правильно.

Статус выхода ImageMagick compare -metric AEне равен нулю, если хотя бы один цвет пикселя отличается.

Допустим, у вас есть папка с именем before, которая содержит исходные изображения, и папка, afterкоторая должна содержать визуально идентичные изображения с тем же именем файла. Используя ImageMagickcompare , вы можете сделать это:

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;
Насколько вы знаете, это работает с изображениями биоформата, такими как .TIF или .NDPI?
Я нашел свой ответ здесь: imagemagick.org/script/formats.php . Итак, первый шаг — который, в конце концов, также достаточно быстр для моих целей — это преобразовать в маленький png и сравнить их.

findimagedupes — находит визуально похожие или повторяющиеся изображения

findimagedupes — это утилита командной строки, которая выполняет грубое «визуальное сравнение» двух изображений. Это позволяет сравнивать два изображения или целое дерево изображений и определять, являются ли они похожими или идентичными. На распространенных типах изображений точность findimagedupes составляет около 98%.

К сожалению, это не работает для моего случая, поскольку он сообщает о визуально похожих (но не одинаковых) изображениях как о дубликатах. Мне нужно, чтобы он проверял результаты автоматических тестов, поэтому нужно точное сходство, а не просто сходство.

В конце концов я создал небольшую программу Qt, которую я назвал imgdiff, которая принимает 2 имени файла и выполняет попиксельное сравнение. Он распечатает сообщение об ошибке, если они различаются, и завершится с 1, или молча выйдет с 0, если они одинаковы.

Пример использования:

imgdiff img1.png img2.bmp

Ссылка на проект Google Code — https://code.google.com/p/imgdiff/ .

Попробуйте dupeguru отсюда: https://dupeguru.voltaicideas.net/ . В режиме «Изображение» он проверяет похожие изображения, даже если они имеют разные размеры, имеет пороговое значение, создает группы похожих файлов, выбирая самый большой файл в качестве основного, но также может быть установлен другой файл для справки. Умеет перемещать файлы по какому-либо пути или в корзину или полностью их удалять. Он кроссплатформенный.

Еще одним интересным инструментом, который также можно использовать для различных операций слияния, является WinMerge: https://winmerge.org/ . У этого есть интересная функция, которая выделяет области различий в изображениях, но может сравнивать до трех файлов одновременно или три пути, которые содержат файлы, но сравнивает только файлы с одинаковым именем, если они найдены на этих путях. Это хорошо для синхронизации папок. Это только для Windows, отлично работает в Wine, но есть версия QT, которая, похоже, находится на ранней стадии: https://github.com/OzzieIsaacs/winmerge-qt .

Можете ли вы добавить подробности о соответствующих функциях такого программного обеспечения?

Возможно, потребуется настройка для правильной обработки альфа-канала, но преобразование в ppm и контрольная сумма, похоже, работают:

#!/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\}//'