"Відрізнити" зображення за допомогою ImageMagick


178

Як я можу отримати різницю між двома зображеннями? У мене є оригінальне зображення. Хтось написав точний дублікат оригінального зображення. Тепер мені потрібно порівняти оригінал із написаним на зображенні та витягнути лише запис у форматі зображення.

Приклад: У мене є зображення будинку. Хтось взяв копію і написав "Привіт!" на копії. Я хочу якось порівняти дві картинки, прибрати будинок і залишити зображенням слова "Привіт!".

Чи можливо це за допомогою ImageMagick? Я знаю, що є способи отримати статистичну різницю між зображеннями, але це не те, що я шукаю.


8
Спробуйте цей розділ посібника з використання ImageMagick!
Бенуа

1
Я знаю, що це питання стосується ImageMagick, але я просто повинен був включити посилання на Rezzle.js для "причинного" пошуку, який може виявитися після агностичного рішення.
бричін

Хтось знає про інструмент, який буде порівнювати 2 зображення, віднімаючи пікселі другого зображення, від першого? Я вважаю за краще не писати свого.
MarcusJ

Imagemagick 7 має перцептивний хеш, методику використання інваріантних моментів зображення. приємно в тому сенсі, що він має те ж саме, навіть після обертання, спотворення ствола, зміни розміру, зміни гами, введення шуму, водяних знаків ...
v.oddou

1
@ v.oddou, Дякую Я прочитав документи і зробив ще кілька тестів. Схоже, це погано спрацьовує з лінійними малюнками, які є дуже рідко заселеними та надзвичайно низькою щільністю пікселів. Схоже, щільність пікселів - це ключ до PHASH, що визначає подібність.
BReddy

Відповіді:


320

Мої власні улюблені такі:

 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 , тому він працює і з ними (доки вони є 1-пейджерами)!


Зліва: Зображення з текстом       Центр: Оригінальне зображення       Право: Відмінності (= текст) у червоних пікселях. Червоні різницеві пікселі;  однакові пікселі білого кольору

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

Це та сама команда, яку я запропонував раніше.


Зліва: Зображення з текстом       Центр: Оригінальне зображення       Вправо: Відмінності пікселів 'морської зелені'. Тільки різниця пікселів морської зелені;  однакові пікселі білого кольору

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

Ця команда додає параметр, щоб зробити різницю пікселів 'seagreen' замість червоного за замовчуванням.


Зліва: Зображення з текстом       Центр: Оригінальне зображення       Вправо: Синій розрізняється (але з деяким контекстом) Сині різницеві пікселі;  Перший із порівняних зображень як освітлений фонl

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

Ця команда видаляє -compose srcчастину - в результаті поведінка за замовчуванням compareзберігає як освітлений фон перший з 2-х розрізнених зображень. (Цього разу із доданим параметром, щоб пікселі різниці відображалися синім кольором.)


Я не в змозі зрозуміти, звідки взявся цей порівняльний кліп? Це частина imagebrick? доступний на windows?
Кришном

2
@Krishnom: Немає такого поняття, як "imagebrick". Ви маєте на увазі 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для того, щоб побачити, де щось змінилося, а потім скориставшись вище, щоб дізнатися, як це змінилося.


2
Приємно! Мені потрібна була якась взаємодія, тому я тиражував ваш метод у Gimp. Для довідки: 1) завантажуйте зображення у вигляді шарів, 2) Колір -> Обезжирюйте обидва шари, 3) видаліть альфа-канали з обох шарів на вкладці "Шари", 4) виберіть канали G + B на одному шарі, виберіть усі та очистіть канали з чорним кольором, те ж саме з каналами R + B на другому шарі, 4) встановіть режим "Екран" для верхнього шару на вкладці "Шари".
Матей Шмід

1
@Palmstrom: Дякую! Спочатку я сам робив ці порівняння зображень, використовуючи Gimp, але я це робив, використовуючи режим шару "витяг зерна" безпосередньо на вхідних зображеннях, тому загальні ділянки в кінцевому підсумку ставали б сірими, в той час як відмінність була б чорною в одному напрямку, а білою - в іншій. . Важко читати, але швидше генерувати, і він може містити кольорову інформацію. Я думаю, ви б ще більше відповідали моїй команді, якби ви використовували "тільки темніти" замість "екрану", а кольори невикористаних каналів використовували білий, а не чорний.
MvG

1
Деякі вхідні файли PDF чомусь призводять до перевернутого зображення після перетворення сірого масштабу. Використовуючи -colorspace grayзамість -grayscale Rec709Luminanceвиправлень це, але це псує композицію. Додайте -respect-parenthesesяк перший варіант, щоб convertподбати про це.
Brecht Machiels

Ось сценарій, який візуально відрізняє два PDF-файли по одному за допомогою цього методу: gist.github.com/brechtm/891de9f72516c1b2cbc1 . Він виводить один JPG для кожної сторінки PDF-файлів у pdfdiffкаталозі та додатково друкує номери сторінок, які відрізняються між двома PDF-файлами.
Brecht Machiels

1
У ImageMagick v6.7.7-10, схоже, -grayscaleце не підтримується, мені довелося використовувати так, -colorspace grayяк запропонував
@BrechtMachiels
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.