Автоматизированная классификация каталогов по цветам

Привет всем, В каталогах часто необходимо классифицировать объекты по цветам. Это могут быть товары, предметы искусства, художественные фото, да что угодно — важно что пользователи хотят находить только красные, только синие, синие с красным объекты каталога и т.п.Исходим из того, что в текстовых описаниях объектов отсутствуют упоминания цветов — классифицировать нужно на основе изображений.a425a3d7818944058dc86a2befded5dd.jpgОбъектов в каталоге достаточно много (>1.000.000), ручная классификация станет в копейку, займет много времени и качество под вопросом. Привлечь профессионалов с правильно поставленным цветовосприятием на такой объем будет проблематично (художник и дня не усидит за такой работой), а случайные люди дадут «случайный» результат — известно, каждый видит цвета по разному, а рутинность работы будет способствовать значительным погрешностям вследствие замыленности взгляда. К тому же хотелось бы выделить не просто один цвет, а N доминантных, в порядке убывания доминанты.

В общем, сразу понятно — на эту работенку неплохо бы взять хорошего дроида, смышлённого и симпотишного как C-3PO. Открывайте статью, будем конструировать.3b1ed7141453482b8939f42be11b62a4.jpg

Выбор цветовой схемыСначала нужно определить базовый набор цветов/оттенков и тонов — наш классификатор цветовой схемы. Обычно это небольшой список — несколько десятков. Цветовая модель в общем-то зависит от того, о чем каталог, какие цвета там доминируют. Какие-то наиболее важные диапазоны можно детализировать оттенками (например — оранжевый, коричневый, бежевый и т.п.).Мы для данной статьи возьмем самую простую модель — КОЖЗГСФ. В практических задачах скорей всего придется добавить суррогатные тона — черный, белый, серый, промежуточные цвета, а также характеристики насыщенности. Но задача эта уже прикладная, зависит от того, что за объекты в каталоге — нужно будет помедитировать над цветовым кругом. Для целей нашей статьи КОЖЗГСФ вполне достаточно.В нашей программе каждый объект должен получить классификацию от 1 до 3 значений из набора КОЖЗГСФ.Мат. подготовка 1. В статье нет исходников на каком-либо языке, только алгоритмическое описание. Впрочем, закодировать и отладить это за полдня-день не составит труда в любом подходящем фреймворке — Java/PHP/.NET и т.п… Важно конечно, чтобы выбранный фреймворк содержал библиотеки работы с изображениями, как минимум нужно уметь загрузить изображение из распространенных форматов растровых изображений, затем преобразовать его в массив RGB-пикселей. Итак, вы выбрали некий удобный фреймворк, идем дальше.2. Алгоритм предполагает попиксельную обработку, поэтому надо бы привести пиксельный размер изображений к какому-нибудь разумному максимуму — скажем, не более 500 пикселей по ширине и высоте. Сделать это можно непосредственно в программе классификации, сразу после загрузки изображения, либо же взять GIMP/BIMP и запустить пакетный scale.3. Если объекты на изображениях сняты на фоне чего-либо еще — нужно подумать как устранить фон. Хорошо, если фон на всех изображениях одноцветный, равномерный — тогда его несложно убрать парой функций непосредственно в создаваемой программе, либо опять же берем GIMP/BIMP.Иногда проблемы фона нет — когда объекты занимают целиком всё изображение, скажем, образцы тканей, обоев, сканы рисунков, художественные фото.Иногда проблему фона можно и проигнорировать — добавится еще один-два доминантных цвета, точность поиска будет ниже. По месту в общем будет видней, сколько стоит эта шкурка, а сколько ее выделка.Преобразование в HSL Форматы цветовой кодировки HSV и HSL являются по сравнению с RGB менее распространенным, но намного более естественным для понимания цвета.Кто не знает деталей — добро пожаловать сюда — в статье по этой ссылке также будут описаны важные для нас принципы и формулы конвертации из RGB в HSL, а немного поискав несложно найти рабочие исходники такой конвертации почти что на любом языке.Также нам нужно определить диапазоны значения тона (H) для каждого цвета из нашей цветовой модели.В формате HSL значение H выражается в градусах от 0 до 360 угла на цветовом круге, который соответствует данному тону. Взглянув на круг, получаем следующие диапазоны RANGES88140c0c322e4395a685ccbc62f3ff1a.jpgСобственно, алгоритм 1. Заготавливаем массив для подсчета доминанты: int ARR[] = new ARR[6], где КОЖЗГСФ соответствует цифре от 0 до 6.2. Формируем из картинки пиксельный массив, каждый элемент которого содержит цвет пикселя rgb (r, g, b).3. Циклим по массиву3.1. Конвертируем цвет пикселя из rgb (r, g, b) в HSL (H, S, L)3.2. Берем значение H пикселя, определяем в какой диапазон RANGES оно попадает (например в диапазон Ж), инкрементируем значение массива ARR с соответствующим индексом (ARR[2]++ в случае с Ж).Таким образом по завершении цикла получим статистику частоты использования каждого из цветов нашей схемы.4. Выбираем доминантные цвета на основании накопленной статистики, например — в результате цикла получили массив ARR[1010,1200,1505,102,45,33,350], или8cfc90e8f4074b3cb2baaf44be774a0e.jpg5. Подсчитываем общее количество пикселей, например путем сложения всех элементов массива.6. Выбираем из массива от 1 до 3 элемента с максимальными значения, но при этом чтобы значение элемента превышало минимальный порог (5–7% от общего количества пикселей — отсекаем незначительные, то есть мало используемые на картинке цвета), индексы этих элементов определяют наши доминантные цвета.Еще один пример с одним доминантным цветом: 6fe661e875ad41faafad57c6f47fc03b.jpgЕще пара слов Алгоритм упрощен для максимально простого его понимания. В реальности конечно всё будет не так безоблачно.В первую очередь нужно определиться с цветовой схемой, подходящей к вашей задаче классификации.В реальной схеме будут присутствовать промежуточные цвета, оттенки и насыщенность (зеленый светлый, темный, …), в этом случае берем массив ARR размерностью побольше, а при определении диапазонов и в цикле обработки пикселей задействуем компоненты S и L модели HSL.

© Habrahabr.ru