Як визначити дублікати картинок за допомогою php, savepearlharbor

У будь-якому проекті людський фактор ніхто не відміняв, і якщо користувачі самостійно вантажать картинки на сайт - появи дублікатів не уникнути. Коли доходить до тисяч файлів, на очах усього не переглянути, а повторювані картинки мало того що нікому не потрібні, так ще й займають місце, витрачають ресурс і в кінці кінців гальмують роботу.

Як визначити дублікати картинок за допомогою php, savepearlharbor

Тому рано чи пізно постає питання автоматизації процесу пошуку повторів, і тут ми розглянемо основні, а також спробуємо в справі.

Порівняння файлів через функцію hash

Одним із способів визначення дублікатів є порівняння файлів шляхом генерації хеш-значення з вмісту заданого файлу.

Простий приклад обчислення хешу зображення:

Результат виглядає приблизно так: bff8b4bc8b5c1c1d5b3211dfb21d1e76

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

Як визначити дублікати картинок за допомогою php, savepearlharbor

ImageMagick

Функція обробки зображень Imagick :: compareImages повертає масив, який містить відтворене зображення і різницю між зображеннями.

Приклад використання при порівнянні двох зображень:

В результаті дві порівнювані картинки ліпляться в одну, на якій видно відмінності.
Також можна отримати числове вираження відмінностей по кожному параметру (приклад з Оф.сайт):

gd2 і libpuzzle

Для швидкого пошуку дублікатів необхідно встановити бібліотеки gd2 і libpuzzle.

Libpuzzle створена для швидкого пошуку візуальної схожості зображень (GIF. PNG. JPEG). Спочатку растрова картинка розбивається на блоки - автоматично відкидаються рамки, що не несуть особливо значимої інформації. Різниця між суміжними блоками формує вектор - це так звана підпис картинки. Схожість картинок визначається відстанню між двома такими векторами. Тому зазвичай зміна кольору, ресайз або стиск не впливають на результати, що видаються libpuzzle.

Як визначити дублікати картинок за допомогою php, savepearlharbor

Libpuzzle досить проста у використанні. Обчислення підпису для двох зображень:

Обчислення відстані між підписами:

Перевірка зображень на схожість:

Стиснення підписів для зберігання в базі даних:

перцептивний хеш

Найімовірніше, найточніший спосіб знаходження дублікатів - порівняння файлів через перцептивний хеш. Перевірка на схожість проводиться шляхом підрахунку кількості відмінних позицій між двома хешамі, яку Хеммінга. Чим відстань менше - тим більше збіг.

Як визначити дублікати картинок за допомогою php, savepearlharbor

Установка для UNIX платформ виглядає так:

Спробувати на ділі можна через i.onthe.io/phash. Завантаження зображень через інтерфейс і на виході показник «однаковості».

Як це працює

Отримуємо хеш першого зображення:

Отримуємо хеш другого зображення:

Отримуємо відстань Хеммінга між двома зображеннями:

Ми виконали майже всі можливі маніпуляції з однією і тією ж фотографією, щоб перевірити - які зміни заважають визначати дублікати через pHash, а які - ні.
Наприклад, при дзеркальному відображенні - картинка залишається невпізнаної.
Зате з квітами можна гратися скільки завгодно - на результат порівняння це не вплине.
Чого не можна сказати про маніпуляції з RGB-каналами, Джона знову не дізналися. хоч і відстань Хеммінга для такого випадку набагато менше.

Решта результатів виглядають так:

Чи не заважають (відстань Хеммінга = 0)

Заважають (відстань Хеммінга - в дужках)

Зміна колірної гами і чіткості

* Залежить від величини кропнутой області. При відрізанні від картинки маленької рамки товщиною в кілька пікселів, відстань Хеммінга буде нульовим, отже схожість - 100%. Але чим відчутніше кроп - тим більше відстань - тим менше шансів виявити дублікат. Про пошук кропнутих дублікатів через перцептивні хеші можна почитати тут.

** те ж саме, що і з кропом. При повороті на пару градусів відстань незначне, але чим більше кут нахилу - тим сильніше відмінність.

  1. Для порівняння картинок використовуйте ImageMagick. а для пошуку повністю ідентичних - порівняння через хеш.
  2. Щоб знаходити незначно змінені зображення - використовуйте бібліотеку libpuzzle.
  3. Порівняння через перцептивний хеш - одне з найбільш надійних, можна спробувати тут.

Схожі статті