Сортировки фотографий по содержанию - задача совсем не тривиальная, и в большей мере играет роль качество распознавания содержания, с которым Вам нужно отсортировать изображение. Конечно о системе интеллектуального распознавания изображения речи не идет, но получить инструмент, с которым можно было бы сортировать более менее похожие фото, вполне реально. К примеру фотосет Джессики Альбы, который каким-то образом смешался с 1000 фото других актрис. Часто отличить такой фотосет от остальных можно по набору цветов, которые доминируют в фото, так как съемки обычно ведутся в одних и тех же декорациях, и лишь модель меняет позу. Этому занятию и посвящен данный пост.

Вы наверное видели в Яндекс картинках поиск по цвету. Как было бы здорово если бы у Вас была возможность сортировать фото таким же образом на своем сайте.

В результате долгих поисков я нашел великолепный скрипт поиска доминирующих цветов в изображении. На сайте phpclasses.org еще много всего интересного, но, к сожалению, скачать с него этот скрипт без регистрации не получится. А эта самая регистрация на нем ужасно долгое и нудное дело. Поэтому те, кому лень мешают убеждения регистрироваться, могут скачать тут.

Работать со скриптом просто:

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 реализован поиск картинок по доминирующему цвету. Данный скрипт позволяет сделать то же самое на своем сайте. Разумеется делать реал тайм поиск слишком медленно, поэтому фото следует индексировать заранее, к примеру при добавлении, и сохранять данные  в базе. Думаю Ваши пользователи оценят такую удобную "фичу" в поиске по сайту или сортировке изображений.

Другое несомненное применение данного скрипта - это сравнение двух фотографий на их схожесть, ведь скрипт дает своеобразный хеш фотографии. Сравнив два хеша и допустив небольшую погрешность, можно судить, что две фотографии содержат одни и те же данные. При этом фотографии разного разрешения, но с одинаковым содержанием также легко выявляются. Самое банальное применение - это проверка на то, что данная фотография уже есть на сайте и ее закачка не требуется.

Кому не совсем понятно, что делает данный скрипт могут потрогать его руками здесь, а исходный код примера можете взять тут 

Оставлять комментарии могут только зарегистрированные пользователи

Комментарии  

Наскалин
# Наскалин 17.11.2011 06:22
Денис!! Спасибище!!! :))
iSche
# iSche 20.03.2012 21:45
Интересно, спасибо. А как насчет .ico
howard
# howard 30.08.2012 06:08
А как сделать, чтобы цвета выводились таблицей с заданным размером ячеек?

Вот как на скрине:

Leroy
# Leroy 30.08.2012 11:42
$colors = $img->getImageColor('b.jpg', 10, 5);
echo '<table><tr>';
foreach($colors as $color=>$counts){
echo '<td style="width:20px; background-color:#'.$color.'">&nbsp;</td>';
}
echo '</tr></table>';


Набрал прямо тут, так что возможно есть косяки, но думаю смысл понятен
Сергей
# Сергей 18.09.2013 18:41
Спасибо за статью!!! А как можно получить массив именно такого вида array('#fff'=>345,'#000'=>34), по примеру выводит array('fff'=>345,'000'=>34) - без символа "#", помогите пожалуйста...
Leroy
# Leroy 18.09.2013 20:42
$colors2 = array();
foreach($colors as $color=>$count)
$colors2['#'.$color]=$count;
Сергей
# Сергей 22.09.2013 18:17
Спасибо огромное!!! Выручили..))
Tatty
# Tatty 01.03.2014 02:15
Всё вроде клёво. Но вот фото:

Основной цвет - #B1B2B6

А скрипт его вообще не определяет, а выводит главный как - #9999CC

Получается что с данным фото не работает?
well-wisher
# well-wisher 30.01.2015 17:35
"Самое банальное применение - это проверка на то, что данная фотография уже есть на сайте и ее закачка не требуется."
я делал такое на сайте wpapers.ru, вот пример http://wpapers.ru/colors/333333/ подбора картинок по цвету
в админке так же дубли ищутся
Valeriy Chupurnov
# Valeriy Chupurnov 31.01.2015 21:20
Да, тоже делал поиск по цвету на одном сайте. К сожалению данный алгоритм работает не всегда верно. Поэтому пришлось найти еще 3 алгоритма. Могу выложить если кому интересно
marcolus
# marcolus 02.04.2015 22:29
Цитирую Valeriy Chupurnov:
Да, тоже делал поиск по цвету на одном сайте. К сожалению данный алгоритм работает не всегда верно. Поэтому пришлось найти еще 3 алгоритма. Могу выложить если кому интересно


Выложите, пожалуйста.
Дмитрий Гавриш
# Дмитрий Гавриш 20.07.2015 02:55
Еще можно получить палитру цветов или же только один основной цвет картинки на этом сайте: http://www.imgonline.com.ua/get-dominant-colors.php
Stitch
# Stitch 02.03.2016 10:35
Дмитрий, а вы своим скриптом для расчета цвета не поделитесь, а то приведенный выше дает очень далекий от ожидаемоего (и вашего) результат...
Мксим
# Мксим 13.11.2016 23:06
Чего -то не работает пример)
Olevpa
# Olevpa 17.02.2018 01:00
То что искал. Благодарю