«Различий» изображения с помощью ImageMagick

179

Как я могу получить разницу между двумя изображениями? У меня есть оригинальное изображение. Кто-то написал точную копию оригинального изображения. Теперь мне нужно сравнить оригинал с написанным на изображении и извлечь только текст в формате изображения.

Пример: у меня есть фотография дома. Кто-то взял копию и написал «Привет!» на копии. Я хочу как-то сравнить две картинки, снять дом и остаться с изображением слов «Привет!».

Это возможно с ImageMagick? Я знаю, что есть способы получить статистическую разницу между изображениями, но это не то, что я ищу.

Джастин Ноэль
источник
8
Попробуйте этот раздел руководства по использованию ImageMagick!
Бенуа
1
Я знаю, что этот вопрос касается ImageMagick, но мне просто нужно было включить ссылку на Resemble.js для «причинного» поисковика, который может быть после агностического решения.
brichins
Кто-нибудь знает инструмент, который будет сравнивать 2 изображения путем вычитания пикселей второго изображения из первого? Я бы предпочел не писать свои собственные.
MarcusJ
Imagemagick 7 имеет перцептивный хэш, метод, использующий инвариантные моменты изображения. это приятно в том смысле, что он хеширует то же самое даже после вращения, искажения бочки, изменения размера, изменения гаммы, введения шума, водяных знаков ...
v.oddou
1
@ v.oddou, спасибо. Я прочитал документы и сделал еще несколько тестов. Похоже, что он плохо работает с линейными чертежами, которые очень малонаселены и имеют чрезвычайно низкую плотность пикселей. Похоже, плотность пикселей - это ключ в PHASH, определяющий сходство.
BReddy

Ответы:

321

Мои собственные любимые эти два:

 compare image1 image2 -compose src diff.png
 compare image1 image2 -compose src diff.pdf

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

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

Коротко и сладко.

Обратите внимание, что ваши изображения не обязательно должны быть одного типа. Вы даже можете смешивать JPEG, TIFF, PNG - при одном условии: изображения должны быть одинакового размера (размер изображения в пикселях). Выходной формат определяется расширением выходного имени файла.

Если по какой-то причине вам требуется более высокое разрешение, чем разрешение по умолчанию (72 dpi), просто добавьте соответствующий -densityпараметр:

 compare -density 300 image1 image2 -compose src diff.jpeg

Иллюстрированные примеры

Вот несколько иллюстраций результатов для вариантов вышеуказанной команды. Примечание: два сравниваемых файла были даже файлами PDF , поэтому он работает и с ними (если они являются одностраничными)!


Слева: изображение с текстом.       Центр: исходное изображение.       Справа: различия (= текст) в красных пикселях. Только красные разностные пиксели;  идентичные пиксели белого цвета

compare \
        porsche-with-scratch.pdf  porsche-original.pdf \
       -compose src \
        diff-compose-default.pdf

Это та же команда, которую я предложил ранее выше.


Слева: изображение с текстом.       Центр: исходное изображение.       Справа: различия в «зеленых» пикселях. Только Seagreen разница пикселей;  идентичные пиксели белого цвета

compare \
        porsche-with-scratch.pdf  porsche-original.pdf \
       -compose src \
       -highlight-color seagreen \
        diff-compose-default.pdf

Эта команда добавляет параметр, чтобы сделать пиксели разницы «seagreen» вместо красного по умолчанию.


Слева: изображение с текстом       центра: Оригинал изображения       Справа: Голубые дифференциалы (. Но ж определенный контекст фон) Только синяя разница пикселей;  первое из сравниваемых изображений в качестве осветленного фонал

compare \
        porsche-with-scratch.pdf  porsche-original.pdf \
       -highlight-color blue \
        diff-compose-default.pdf

Эта команда удаляет -compose srcдеталь - результатом является поведение по умолчанию, в compareкотором в качестве светлого фона сохраняется первое из двух рассеянных изображений. (На этот раз с добавленным параметром, чтобы пиксели diff отображались синим цветом.)

Курт Пфайфл
источник
Я не могу понять, откуда это сравнение Cli? Это часть имиджевого кирпича? доступно на окнах?
Кришном
2
@Krishnom: нет такого понятия, как «имидж-кирпич». Вы имеете в виду ImageMagick?
Курт Пфайфл
2
@Krishnom: вопрос явно задан о решении ImageMagick. Часть программного пакета ImageMagick v6.x имела отдельный инструмент CLI 'compare'. Для v7.x ImageMagick вы должны запустить 'magick compare'вместо этого.
Курт Пфайфл
Виноват. Спасибо за исправление этого (imagebrick -> imageMagick). Я дам ему попробовать. Я также ищу инструмент для сравнения объемных изображений.
Еще
@Krishnom: я не знаю, что такое «объемное изображение». Но я все же держу пари, что набор инструментов ImageMagick может делать то, что вы хотите.
Курт Пфайфл
53

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

convert '(' file1.png -flatten -grayscale Rec709Luminance ')' \
        '(' file2.png -flatten -grayscale Rec709Luminance ')' \
        '(' -clone 0-1 -compose darken -composite ')' \
        -channel RGB -combine diff.png

Идея заключается в следующем: конвертировать file1.pngи file2.pngв оттенки серого. Затем нарисуйте первый как красный канал полученного изображения, а второй как зеленый канал. Синий канал формируется из этих двух с использованием darkenоператора compose, что по сути означает получение минимума.

Таким образом, вещи, которые белые на обоих изображениях, остаются белыми. Вещи, которые являются черными на обоих изображениях, остаются черными. Вещи, которые белые на первом изображении, но черные во втором становятся красными, а вещи, которые белые во втором, но черные в первом, становятся зелеными.

В результате вы получите изображение с цветовой кодировкой, в котором вы можете легко связать зеленый с первым входом и красный со вторым. Вот пример, в котором я использую это для сравнения вывода из LaTeX с выводом из KaTeX (прежде чем я исправил некоторую ошибку, чтобы сделать это лучше):

введите описание изображения здесь

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

MVG
источник
2
Ницца! Мне нужно было какое-то взаимодействие, поэтому я скопировал ваш метод в Gimp. Для справки: 1) загрузить изображения в виде слоев, 2) цвет -> обесцветить оба слоя, 3) удалить альфа-каналы из обоих слоев на вкладке «Слои», 4) выбрать каналы G + B на одном слое, выбрать все и очистить каналы с черным цветом, то же самое с каналами R + B на втором слое, 4) установите режим экрана для верхнего слоя на вкладке Слои.
Матей Шмид
1
@Palmstrom: Спасибо! Первоначально я сравнивал эти изображения с помощью Gimp, но я делал это, используя режим слоя «Извлечение зерна» непосредственно на входных изображениях, поэтому общие области заканчивали серым, тогда как различие было бы черным в одном направлении и белым в другом , Труднее читать, но быстрее генерировать, и он может содержать информацию о цвете. Я полагаю, что вы бы лучше соответствовали моей команде, если бы вы использовали «только затемнение» вместо «экрана» и закрашивали неиспользуемые каналы белым, а не черным.
MvG
1
Некоторые входные данные PDF по какой-то причине приводят к инвертированному изображению после преобразования в оттенках серого. Использование -colorspace grayвместо того, чтобы -grayscale Rec709Luminanceисправить это, но это портит композицию. Добавьте -respect-parenthesesв качестве первого варианта, чтобы convertпозаботиться об этом.
Брехт Мачиэльс
Вот скрипт для визуального отображения двух PDF-страниц постранично с помощью этого метода: gist.github.com/brechtm/891de9f72516c1b2cbc1 . Он выводит один JPG для каждой страницы PDF-файлов в pdfdiffкаталоге и дополнительно печатает номера страниц, которые отличаются между двумя PDF-файлами.
Брехт Мачиэльс
1
В ImageMagick v6.7.7-10, кажется -grayscale, не поддерживается, мне пришлось использовать, -colorspace grayкак предложено
@BrechtMachiels