4 и 1 способ найти затесавшийся дубликат

от автора

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

Потому рано или поздно встает вопрос автоматизации процесса поиска повторов, и тут мы рассмотрим основные, а так же попробуем в деле.

Сравнение файлов через создание hash

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

Простой пример вычисления хеша изображения:

<?php imagecreatefrompng('image.png'); echo hash_file('md5', 'image.png'); ?> 

Результат выглядит примерно так: bff8b4bc8b5c1c1d5b3211dfb21d1e76
Если хеши двух изображений совпадают – изображения одинаковые.

ImageMagick

Функция обработки изображений Imagick::compareImages возвращает массив, который содержит восстановленное изображение и разницу между изображениями.

Пример использования при сравненни двух изображений:

<?php header("Content-Type: image/png"); $image1 = new imagick("image1.png"); $image2 = new imagick("image2.png"); $result = $image1->compareImages($image2, Imagick::METRIC_MEANSQUAREERROR); $result[0]->setImageFormat("png");  echo $result[0]; ?> 

PHP библиотеки

Для быстрого поиска дубликатов необходимо установить библиотеки gd2 и libpuzzle.

Установка gd2 и рестарт сервера apache:

sudo apt-get install php5-gd && sudo service apache2 restart 

Установка libpuzzle:

sudo apt-get install libpuzzle-php 

Libpuzzle создана для быстрого поиска визуального сходства изображений (GIF, PNG, JPG). Библиотека будет работать даже если изображения были слегка изменены (ресайз, сжатие, изменения цвета). Libpuzzle довольно проста в использовании:

Вычисление подписи для двух ихображений:

$cvec1 = puzzle_fill_cvec_from_file('img1.jpg'); $cvec2 = puzzle_fill_cvec_from_file('img2.jpg'); 

Вычисление расстояния между подписями:

$d = puzzle_vector_normalized_distance($cvec1, $cvec2); 

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

if ($d < PUZZLE_CVEC_SIMILARITY_LOWER_THRESHOLD) {   echo "Pictures are looking similar\n"; } else {   echo "Pictures are different, distance=$d\n"; } 

Сжатие подписей для хранения в базе данных:

$compress_cvec1 = puzzle_compress_cvec($cvec1); $compress_cvec2 = puzzle_compress_cvec($cvec2); 

pHash

Вот и добрались до самого точного способа нахождения дубликатов — сравнение файлов через перцептивный хеш. Проверка на схожесть проводится путем подсчета количества отличающихся позиций между двумя хешами, это расстояние Хэмминга. Чем расстояние меньше — тем больше совпадение. Отличается от первого способа тем, что указывает не только на одинаковость/неодинаковость, но и на степень различия.
Этот метод рассчитан на поиск частичных или полных дубликатов, но также найдет незначительно отредактированные картинки – с измененной яркостью, цветовой гаммой и т.д. Подробнее об этом принципе можно прочитать в неплохом переводе.
Попробовать на деле можно через /инструмент/. Загрузка изображений через интерфейс и на выдаче результаты перцептивных хешей и показатель «одинаковости».
Мы сравнили бла-бла…

ссылка на оригинал статьи http://habrahabr.ru/post/259543/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *