Можем ли мы программно сравнивать разные изображения одинаковых разрешений?

Есть ли хороший и надежный способ сравнить изображения одного формата и того же разрешения и получить разницу между ними?

В лучшем случае я ищу некоторое числовое представление изображения, которое можно сравнить, потому что мне приходится сравнивать много изображений.

Ответ 1

Вы можете использовать команду ImageMagick compare для этого.

(Если вы успешно выполнили командную строку, вы можете перейти к использованию одного из API-интерфейсов ImageMagick: они доступны, среди прочих, для C ('MagickWand'), C++ (' Магический ++ '), Java (' JMagick '), LISP (' L-Magick '), .NET (' Magick.NET '), Perl (' PerlMagick '), PHP (' IMagick '), Python (' PythonMagick ') и Ruby (' RMagick '). - Затем реализуйте соответствующие функции в своем приложении.)

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

Разницу можно вернуть по-разному:

  • Создайте визуальное представление различий, где пиксель с дельтами каким-то образом выделен в дельта-изображении.

  • Создайте текстовое и/или статистическое представление различий, где вывод - это одно или несколько чисел, или просто количество пикселей, которые являются разными, или какая-либо другая метрика.


Пример

Вот четыре примера изображений, которые можно сравнить. Они кажутся одинаково выглядящими, имеют размер 322x429 пикселей, но есть несколько более тонких различий в раскраске и формате: верхний правый - это JPEG, остальные три - PNG:

GBax7.pngD9IAV.jpg

ZuKQM.pngMYdUW.png

Визуальные сравнения

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

compare                              \
  http://i.stack.imgur.com/GBax7.png \
  http://i.stack.imgur.com/D9IAV.jpg \
  delta1.pdf

Это сравнивает PNG с JPEG и создает PDF в качестве вывода. Для визуального впечатления от этого выхода см. Изображение ниже слева (так как PDF файлы не отображаются здесь, я прибегал к созданию PNG и вместо этого использовал это для отображения).

Что сделала эта самая простая из всех команд ImageMagick compare?

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

(Я мог бы добавить -highlight-color blue и -lowlight-color yellow или любые другие определения цвета, если бы я не хотел, чтобы красная подсветка по умолчанию)

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

Легко: добавьте в командную строку фактор "пух"!

compare                              \
  http://i.stack.imgur.com/GBax7.png \
  http://i.stack.imgur.com/D9IAV.jpg \
 -fuzz 2.5%                          \
  delta2.png

OM6V1.pnghKAXB.png

При запуске без дополнительных аргументов первая (самая простая) команда сравнения, ImageMagick молча добавила спецификацию своего метода сравнения по умолчанию, который называется -compose src-over.

Конечно, мы можем переопределить это и использовать другой режим композиции. Как узнать о доступных режимах композиции? Команда convert -list compose перечислит их для нас! Вот полный список - он содержит 67 разных в моей системе:

Atop Blend Blur Bumpmap ChangeMask Очистить ColorBurn ColorDodge Раскрасить CopyBlack CopyBlue CopyCyan КопироватьGreen Copy CopyMagenta CopyOpacity CopyRed CopyYellow Darken DarkenIntensity DivideDst DivideSrc Dst Разница Разложите Distolve Distort DstAtop DstIn DstOut DstOver Исключение HardLight HardMix Hue In Lighten LightenIntensity LinearBurn LinearDodge LinearLight Luminize Mathematics MinusDst MinusSrc Modulate ModulusAdd ModulusSubtract Multiply None Out Overlay Over PegtopLight PinLight Plus Замените насыщенный экран SoftLight Src SrcAtop SrcIn SrcOut SrcOver VividLight Xor

Попробуйте каждый из них:

for i in $(convert -list compose|tr "\n" " "); do \
  compare                                         \
     http://i.stack.imgur.com/GBax7.png           \
     http://i.stack.imgur.com/D9IAV.jpg           \
    -compose ${i}                                 \
     delta-${i}.png ;                             \
done

Конечно, было бы слишком много, чтобы показать каждое результирующее дельта-изображение. Самые интересные из них ниже:

  • верхний левый -compose Difference
  • верхний правый -compose DivideSrc
  • центр слева - -compose CopyBlue
  • center right - -compose MinusDst
  • внизу слева -compose Hue
  • внизу справа -compose LightenIntensity

Примечание: если вы поменяете порядок двух сравниваемых изображений, две результирующие дельта могут быть значительно разными двумя!

TtIiR.pngrrJZG.png

ybksB.pngRKGwl.png

yao61.png <Т411 >

Теперь вы уже можете начать свои собственные эксперименты с визуального сравнения двух похожих изображений.

Метрические результаты

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

compare                               \
  -metric rmse                        \
   http://i.stack.imgur.com/GBax7.png \
   http://i.stack.imgur.com/D9IAV.jpg \
   null:

rmse является аббревиатурой для среднеквадратичной ошибки. Результат приведенных выше изображений показывает:

 1339.53 (0.02044)

Сколько различных метрических методов поддерживается?

Следующая команда перечисляет все доступные методы сравнительных показателей для данной системы, для текущей версии ImageMagick:

compare -list metric 

В моей записной книжке:

AE Fuzz MAE MEPP MSE NCC PAE PHASH PSNR RMSE

Значения этих сокращений:

AE     absolute error count, number of different pixels (`-fuzz` effected)
FUZZ   mean color distance
MAE    mean absolute error (normalized), average channel error distance
MEPP   mean error per pixel (normalized mean error, normalized peak error)
MSE    mean error squared, average of the channel error squared
NCC    normalized cross correlation
PAE    peak absolute (normalized peak absolute)
PHASH  perceptual hash
PSNR   peak signal to noise ratio
RMSE   root mean squared (normalized root mean squared)

Интересная (и относительно недавняя) метрика phash ( "перцептивный хэш" ). Это единственный, который не требует одинаковых размеров для двух сравниваемых изображений. Это действительно лучшая "метрика", чтобы сузить похожие изображения (или, по крайней мере, надежно исключить эти пары изображений, которые выглядят совсем по-другому), не глядя "на них", в командной строке и программно.

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

for i in $(compare -list metric); do     \
    compare                              \
     -metric $i                          \
      http://i.stack.imgur.com/GBax7.png \
      http://i.stack.imgur.com/GBax7.png \
      null:                              \
done

Это результат:

AE    :   0
Fuzz  :   0 (0)
MAE   :   0 (0)
MEPP  :   0 (0, 0)
MSE   :   0 (0)
NCC   :   1.00001
PAE   :   0 (0)
PHASH :   0
PSNR  :   inf
RMSE :    0 (0)

Как вы можете видеть, каждый метод метрики возвращает 0, кроме двух: PSNR возвращает infinity, а NCC возвращает 1.00001.

Запустите эту же команду и сравните чистый белый патч размером 100x100 пикселей с чистым черным:

for i in $(compare -list metric); do \
  compare                            \
     -metric $i                      \
     -size 100x100                   \
      xc:white                       \
      xc:black                       \
      null:                          \
done

Это возвращает следующий результат:

AE    :   10000
Fuzz  :   65535 (1)
MAE   :   65535 (1)
MEPP  :   1.96605e+09 (1.00003, 1)
MSE   :   65535 (1)
NCC   :   0
PAE   :   65535 (1)
PHASH :   417.941
PSNR  :   0
RMSE  :   65535 (1)

Показатель AE как и ожидалось: 10000 пикселей (от -size 100x100) различны. Большинство других результатов также легко понять, если вы читаете и оцениваете, что означают соответствующие значения метрик....

Наконец, рассмотрим вывод каждой доступной метрики при сравнении двух верхних изображений (PNG и JPEG):

for i in $(compare -list metric); do     \
    compare -metric $i                   \
      http://i.stack.imgur.com/GBax7.png \
      http://i.stack.imgur.com/D9IAV.jpg \
      null:                              \
done

AE    :   74200
Fuzz  :   1339.53 (0.02044)
MAE   :   499.997 (0.00762946)
MEPP  :   2.07206e+08 (0.000417654, 0.435294)
MSE   :   27.3801 (0.000417793)
NCC   :   0.99709
PAE   :   28527 (0.435294)
PHASH :   0.745389
PSNR  :   33.7904
RMSE  :   1339.53 (0.02044)

Теперь выберите свой показатель!: -)