Как определить преобладающий цвет в изображении
Сортировки фотографий по содержанию - задача совсем не тривиальная, и в большей мере играет роль качество распознавания содержания, с которым Вам нужно отсортировать изображение. Конечно о системе интеллектуального распознавания изображения речи не идет, но получить инструмент, с которым можно было бы сортировать более менее похожие фото, вполне реально. К примеру фотосет Джессики Альбы, который каким-то образом смешался с 1000 фото других актрис. Часто отличить такой фотосет от остальных можно по набору цветов, которые доминируют в фото, так как съемки обычно ведутся в одних и тех же декорациях, и лишь модель меняет позу. Этому занятию и посвящен данный пост.
Вы наверное видели в Яндекс картинках поиск по цвету. Как было бы здорово если бы у Вас была возможность сортировать фото таким же образом на своем сайте.
В результате долгих поисков я нашел великолепный скрипт поиска доминирующих цветов в изображении.
Работать со скриптом просто:
require_once "getImageColor.php";// подключаем файл со скриптом $img = new GeneratorImageColorPalette(); $colors = $img->getImageColor('../Джессика Альба/wallpapers/446d83b66ae6e290d6c61cb86061d9db.jpg', 10, $image_granularity = 5); print_r($colors);
В результате скрипт выведет 10 самых популярных в изображении цветов. Собственно все сделает функция GeneratorImageColorPalette::getImageColor($imageFile_URL, $numColors, $image_granularity = 5). Она имеет 3 входных параметра:
$imageFile_URL - адрес изображения;
$numColors - количество цветов на выходе;
$image_granularity - шаг сетки, по которой производится статистика.
Считаю, что все предельно понятно насчет первых двух параметров. Третий параметр более важен. Он напрямую влияет на скорость работы скрипта. Чем больше его величина, тем быстрее будет работать скрипт. По умолчанию он равен 5, но реально в изображении цвет меняется не так часто и можно поставить цифру побольше. Дело в том, что скрипт просто перебирает пикселы изображения с шагом $image_granularity в изображения. Примерно так:
for($x = 0; $x < $size[0]; $x += $image_granularity){ for($y = 0; $y < $size[1]; $y += $image_granularity){ $thisColor = imagecolorat($img, $x, $y);
Данный скрипт возвращает лишь массив с наиболее часто встречающимися цветами, это не совсем удобно при сортировке изображений, так как неизвестно количественное соотношение доминирующих цветов. Поэтому, если вы желаете, чтобы скрипт возвращал массив вида array('#fff'=>345,'#000'=>34), то замените строчку
return array_slice(array_keys($colors), 0, $numColors);
на
return array_slice($colors, 0, $numColors,true);
Вот и все, результирующий массив содержит в порядке возрастания цвета и количество точек встреченных с данным цветом.
Применение скрипта может быть самым разнообразным. У Yandex и Google реализован поиск картинок по доминирующему цвету. Данный скрипт позволяет сделать то же самое на своем сайте. Разумеется делать реал тайм поиск слишком медленно, поэтому фото следует индексировать заранее, к примеру при добавлении, и сохранять данные в базе. Думаю Ваши пользователи оценят такую удобную "фичу" в поиске по сайту или сортировке изображений.
Другое несомненное применение данного скрипта - это сравнение двух фотографий на их схожесть, ведь скрипт дает своеобразный хеш фотографии. Сравнив два хеша и допустив небольшую погрешность, можно судить, что две фотографии содержат одни и те же данные. При этом фотографии разного разрешения, но с одинаковым содержанием также легко выявляются. Самое банальное применение - это проверка на то, что данная фотография уже есть на сайте и ее закачка не требуется.
Исходный код примера можете взять тут