У будь-якому проекті людський фактор ніхто не відміняв, і якщо користувачі самостійно вантажать картинки на сайт - появи дублікатів не уникнути. Коли доходить до тисяч файлів, на очах усього не переглянути, а повторювані картинки мало того що нікому не потрібні, так ще й займають місце, витрачають ресурс і в кінці кінців гальмують роботу.
Тому рано чи пізно постає питання автоматизації процесу пошуку повторів, і тут ми розглянемо основні, а також спробуємо в справі.
Порівняння файлів через функцію hash
Одним із способів визначення дублікатів є порівняння файлів шляхом генерації хеш-значення з вмісту заданого файлу.
Простий приклад обчислення хешу зображення:
Результат виглядає приблизно так: bff8b4bc8b5c1c1d5b3211dfb21d1e76
Якщо хеш-кодування двох зображень збігаються - зображення однакові.
Метод далеко не найточніший, так як працює тільки для ідентичних картинок, при найменшому розходженні - толку нуль.
ImageMagick
Функція обробки зображень Imagick :: compareImages повертає масив, який містить відтворене зображення і різницю між зображеннями.
Приклад використання при порівнянні двох зображень:
В результаті дві порівнювані картинки ліпляться в одну, на якій видно відмінності.
Також можна отримати числове вираження відмінностей по кожному параметру (приклад з Оф.сайт):
gd2 і libpuzzle
Для швидкого пошуку дублікатів необхідно встановити бібліотеки gd2 і libpuzzle.
Libpuzzle створена для швидкого пошуку візуальної схожості зображень (GIF. PNG. JPEG). Спочатку растрова картинка розбивається на блоки - автоматично відкидаються рамки, що не несуть особливо значимої інформації. Різниця між суміжними блоками формує вектор - це так звана підпис картинки. Схожість картинок визначається відстанню між двома такими векторами. Тому зазвичай зміна кольору, ресайз або стиск не впливають на результати, що видаються libpuzzle.
Libpuzzle досить проста у використанні. Обчислення підпису для двох зображень:
Обчислення відстані між підписами:
Перевірка зображень на схожість:
Стиснення підписів для зберігання в базі даних:
перцептивний хеш
Найімовірніше, найточніший спосіб знаходження дублікатів - порівняння файлів через перцептивний хеш. Перевірка на схожість проводиться шляхом підрахунку кількості відмінних позицій між двома хешамі, яку Хеммінга. Чим відстань менше - тим більше збіг.
Установка для UNIX платформ виглядає так:
Спробувати на ділі можна через i.onthe.io/phash. Завантаження зображень через інтерфейс і на виході показник «однаковості».
Як це працює
Отримуємо хеш першого зображення:
Отримуємо хеш другого зображення:
Отримуємо відстань Хеммінга між двома зображеннями:
Ми виконали майже всі можливі маніпуляції з однією і тією ж фотографією, щоб перевірити - які зміни заважають визначати дублікати через pHash, а які - ні.
Наприклад, при дзеркальному відображенні - картинка залишається невпізнаної.
Зате з квітами можна гратися скільки завгодно - на результат порівняння це не вплине.
Чого не можна сказати про маніпуляції з RGB-каналами, Джона знову не дізналися. хоч і відстань Хеммінга для такого випадку набагато менше.
Решта результатів виглядають так:
Чи не заважають (відстань Хеммінга = 0)
Заважають (відстань Хеммінга - в дужках)
Зміна колірної гами і чіткості
* Залежить від величини кропнутой області. При відрізанні від картинки маленької рамки товщиною в кілька пікселів, відстань Хеммінга буде нульовим, отже схожість - 100%. Але чим відчутніше кроп - тим більше відстань - тим менше шансів виявити дублікат. Про пошук кропнутих дублікатів через перцептивні хеші можна почитати тут.
** те ж саме, що і з кропом. При повороті на пару градусів відстань незначне, але чим більше кут нахилу - тим сильніше відмінність.
- Для порівняння картинок використовуйте ImageMagick. а для пошуку повністю ідентичних - порівняння через хеш.
- Щоб знаходити незначно змінені зображення - використовуйте бібліотеку libpuzzle.
- Порівняння через перцептивний хеш - одне з найбільш надійних, можна спробувати тут.