В процессе разбора картинок wallpapers появилась задача убрать дубликаты.
Нетривиальная задача. Правда?
Но оказалось не все так сложно. Сейчас объясню.
Вот две картинки:
На вид они абсолютно одинаковы, имеют одинаковый размер.
Но, если посчитать хеш, то он будет разный, а утилита для сравнения картинок покажет, что они значительно отличаются:
Как говорит старая мудрость: "Черт прячется в деталях". Так и здесь, видимо одна картинка получена из другой с помощью отличных друг от друга преобразований. Чтобы убрать лишние детали нужно увеличить размер пикселя, или, что тоже самое отмасштабировать картинки в маленький размер.
Что при этом произойдет?
Программа масштабирования, чтобы сохранить картинку картинкой при объединении пикселей возьмет средние значения цветов, яркости и контрастности. Во время этой операции шум внесенный в картинку будет с высокой вероятностью удален.
Я отмасштабировал картинки до ширины в 30 пикселей, а в блоге увеличил, чтобы показать, что из этого получается:
Теперь сравним их опять:
Вуаля! А не какая не виола.
Теперь, вооружившись этими знаниями не составляет труда написать простенький скрипт по удалению дубликатов изображений.
Очень важно:
- Очень важно правильно выбрать количество пикселей в картинках, которые будут сравниваться. Если, как я указал в примере, ужимать до 30 пикселей в ширину, то вероятность ложных срабатываний достаточно велика. Опытным путем установлено, что 100 пикселей в ширину - оптимальный размер для выявления дубликатов.
- Скрипт, который я написал относится к категории brute force, На ноутбуке Thinkpad x220 с процессором i7 2620 на обработку 1600 картинок требуется около 15 часов.
Полезные ссылки:
- ImageMagick
- Perceptual Image Diff
- Habrhabr. «Выглядит похоже». Как работает перцептивный хэш.
- Habrhabr. Алгоритм быстрого нахождения похожих изображений.
- Habrhabr. Сравнение изображений и генерация картинки отличий на Ruby.
- Near Duplicate Image Detection: min-Hash and tf-idf Weighting.
- Partition Min-Hash for Partial Duplicate Image Discovery
- DigiKam:How to export duplicates list?