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

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

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

Рассказать друзьям
author.jpg

Платная консультация по вопросам 1500 руб/час

Прочитали статью и остались вопросы? Меня зовут Валерий и я её автор. С радостью объясню Вам в скайпе все затруднительные моменты, которые остались за рамками статьи!

Подробнее ...

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


Комментарии   

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

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

Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Leroy
0 # Leroy 30.08.2012 07: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>';


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

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

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

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


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