Як визначити дублікати картинок за допомогою PHP - Сайт - У Крайнього

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

визначити

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

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

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

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

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

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

картинок

ImageMagick

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

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

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

gd2 та libpuzzle

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

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

допомогою

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

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

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

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

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

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

сайт

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

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

Як це працює

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

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

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

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

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

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

Не заважають (відстань Хеммінга = 0) Заважають (відстань Хеммінга - у дужках)
Змінене ім'я файлуКроп (34)*
Формат (JPEG, PNG, GIF)Поворот 90° (32)**
Оптимізація Google PageSpeedДзеркальне відображення (36)
Ресайз із збереженням пропорцій та безЗміна положення кривих у RGB-каналах (18)
Зміна колірної гами та чіткості
*залежить від величини кропнутої області. При відрізанні від картинки маленької рамки завтовшки кілька пікселів, відстань Хеммінга буде нульовим, отже подібність — 100%. Але чим відчутніша кроп — тим більша відстань — тим менше шансів виявити дублікат. Про пошук кропних дублікатів через перцептивні хеші можна почитати тут.

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