0,0
рейтинг
18 января 2012 в 18:55

Разработка → Определение доминирующих тонов на изображении из песочницы

Предыстория


Очень давно, когда мои познания в PHP были на уровне мат операций и вывода результатов, а нашел очень полезный класс, написанный Kalpeh Gamit, его сайт уже давно недоступен, поэтому, к сожалению контакты оставить не могу. Класс распространяется под именем GetImageColor и лицензией GPL 2.0.

Пользовался я этим классом частенько. Он принимает в качестве входного параметра изображение (только в формате JPEG, но за минуту дополняется всеми остальными), количество возвращаемых цветов и шаг обработки. Скрипт считывает цвет с фотографии с заданным шагом и заносит его в массив цветов. Итоговый массив отсортирован по вхождениям цветов и возвращается только заданное количество цветов.


Очень удобный скрипт для многих задач. Лично мне он нужен был в первой версии Фотокиоска, с помощью скрипта я определял однотоновые фотографии и не позволял их загружать на сервер (слишком темные, засвеченные итд). Позже в LetPrint я применял его для определения заполненности листа и цветности.

Сегодня увидел статью на Хабре: habrahabr.ru/blogs/web_design/136343


Заинтересовало вот что. У изображения выбраны не просто часто встречающиеся цвета, а доминирующие или контрастные тона. Вспомнив, что выдал бы тот класс, я понял, что необходимо другое решение.


Решение


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

Следующий этап – это попытка добиться сглаживания. Нужен алгоритм, который обрабатывал бы массив с имеющимися цветами, выбирал бы в нем схожие цвета и находил сглаженный цвет, и так до тех пор, пока не были бы выделены 5 основных.

Написать такой алгоритм было не трудно, но вот поиск похожих меня немного затормозил. Хотя я долго и не разбирался с ним, все же кустарное решение легко нашел.

Наш цвет состоит из трех компонент: R+G+B. Все эти значения от 0 до 255. Цвета 250,100,100 и 240,90,90 – подобны, но второй темнее первого, но тем не менее они подобны. Цвет 245,100,100 тоже подобен первым двум, но в меньшей степени. Собственно вот здесь и начинается погрешность. Первые два цвета подобны, но подобны и 255,255,255 и 0,0,0 и это сразу же отбрасывает черно-белые фотографии. Также из-за подобности первых двух и третьего, отбрасываются оттенки. Но мы готовы к таким жертвам.

Число подобия – |R-G|.|R-B|.|B-G|, также для внесения подобных оттенков сама разность тоже подвергается обработке dif = round(round(|R-G|/pogr)*pogr). Коэффициэнтом pogr мы вносим погрешность. К примеру, если pogr = 10, то цвета 254,180,35 и 234,163,19 подобны. Чем больше погрешность, тем больше подобных оттенков мы объеденим.

После необходимо учитывая вес цвета, сгладить массив в единый цвет. Имеем массив подобных цветов. У каждого 2 параметра – цвет и количество вхождений. Собственно сглаженный цвет будет состоять из R = СУММ(Ri*mi)/СУММ(mi), где mi — количество вхождений этого цвета, также и с остальными составляющими G и B. Это значит, что раз черный и белый у нас подобны, то в результате работы алгоритма мы получим серый, который может и не присутствовать на картинке, но который будет полностью отражать смешение черного и белого.

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

Результат


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

Попробовать алгоритм в действии можно тут: blog.assorium.ru/jpeg
Сервер у меня слабый, поэтому попрошу сильно на него не давить. Ограничения: изображения в формате JPEG и весом не более 500 КБ.

Альтернативные методы решения


Самый простой способ решения этой задачи, это каталог тонов. Я где-то уже наталкивался на него. Там предлагались самый часто используемые и приятные тона. Каталог насчитывал несколько тысяч цветов, что вполне бы хватило для этого скрипта. Обработка в принципе остается той же, но при сглаживании в окончательный массив добавляется цвет из каталога, который подобен текущим и так до тех пор, пока не останется несколько цветов. Преимущество метода очевидно, Вы получите цвет, который сам по себе хорош и не будет резать глаз и при этом еще и будет отражать суть на картинке.

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

UPD_1 Среди загруженных фотографий немало обнаженных женщин. Зачем кому-то узнавать тона обнаженного тела?
UPD_2 4utep нашел готовое решение, но с помощью HSV и определенного набора цветов. ссылка
Push_Ok подсказал «формулу цветового отличия» утвержденную CIE. Возможно она улучшит определение подобных. Пока я не определял насколько. ссылка
UPD_3 За сутки было загружено более 1500 картинок. Спасибо хабраюзерам за эпичные картинки прошедших трех месяцев и немалое количество эротики. Среди картинок даже попались экземпляры, просящие инвайт. Очень меня обрадовал мой хостер. Сайт не упал ни разу и не тормозил.
Спартак Каграманян @Assorium
карма
37,0
рейтинг 0,0
Пользователь
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Спецпроект

Самое читаемое Разработка

Комментарии (35)

  • НЛО прилетело и опубликовало эту надпись здесь
    • +1
      К сожалению мне на выбор даны только «Информационная безопасность» и «Песочница».
      • +6
        а вы попробуйте вступить ещё в какие-то блоги :)
      • НЛО прилетело и опубликовало эту надпись здесь
        • +5
          Благодарю, ребят! Сейчас все исправлю
          • +4
            Скорее, не «Веб-дизайн», а «Алгоритмы», судя по статье.
            • +1
              вообще, пора бы уже создать блог типа «computer science»
  • +2
    Поддерживаю. Сначала думал, что статья о стеганографии средствами картинки, но нет…

    Вам как раз стоило бы это опубликовать в Веб-дизайне
  • НЛО прилетело и опубликовало эту надпись здесь
  • +2
    картинки не грузятся :(
    • 0
      Были залиты на HabraStorage. Куда перезалить?
      • 0
        Хабрасторадж вполне ок. Проверьте просто последние две картинки. Возможно, просто непраивльные урлы.
  • 0
    В opere 11.5 win7 не работает, цвета не отображаются почему-то, в хроме окей всё.
    • 0
      Использована табличная верстка. Скорее всего Opera не поддерживает стиль background-color у тега td.
      • +1
        Табличная вёрстка — смерть :)
        • НЛО прилетело и опубликовало эту надпись здесь
        • 0
          фанатизм — точно смерть
      • +1
        Разглючка проста. Задайте высоту внутренней таблицы в пикселях, а не в процентах.
      • 0
        Да, и подглючивает на этой картинке.
        blog.assorium.ru/jpeg/img/1326912152.jpg

        Ни серйо воды, ни чёрного отражения, ни белого пёрышка… Три «травяных» тона и два промежуточных.
        • 0
          Спасибо за ликбез. Opera
          Насчет изображения. Я описывал эту проблему в одном из комментариев и в статье. Белый, черный и серый он воспринимает как похожие цвета, а с увеличением погрешности, также в похожие набиваются и тона, соответственно крайне темно-зеленый тоже попадет в подобные.
          В принципе по этому изображению он выдал нормальный результат, кроме конечно отсутствия белого оттенка. Это решается только поиском по контрастности.
  • 0
    Выводит один раз из десяти. К тому же, самые контрастные цвета не использует:
    image
    • 0
      Я описал в статье, что используется сглаживание у подобных. В данном случае белый и темный подобные и в итоге по моему алгоритму они сглаживаются в серый, где его яркость определяется весом подобных цветов.
  • 0
    Клёво!
    Вообще интересная тема. Cool story: я себе делал небольшое расширение для Фотошопа, которое сдвигало цвета по-всякому, проблема оказалась только в том, что цвета одного h, s или v отличаются по яркости. И я пытался сделать суперформулу сглаживания между переходами, но так ничего и не вышло.
  • +2
    Вот еще один вариант решения задачи
    derickrethans.nl/finding-out-colours.html
    • 0
      Хорошая статья! Взял на заметку
  • +3
    А не пробовали приводить цвета в HSV и анализировать по единственному параметру H?
    Получится одномерный кластерный анализ.
    • 0
      Скрипт приложите, пожалуйста.
      • 0
        Не туда написал. Это не ответ на комментарий, а просьба к автору.
    • 0
      HSV — намного удобнее. Разве что из-за низкой разрядности можно получить ошибку (особенно при небольших V), так что для более точного подхода к задаче компоненты H с низким V надо будет не учитывать.
  • 0
    qmax Об этом я тоже думал, скорее всего этим и займусь, как опять появится настроение.
    masterx Мой код крайне не читаемый. Алгоритм не трудный, я его довольно подробно описал, поэтому Вы вполне сможете его восстановить. В следующий раз я постараюсь нормально написать код и приложить к статье.
  • –1
    Вполне годный скрипт. Не думали создать сервис на его основе?
    Ссылка blog.assorium.ru/jpeg сколько времени ещё будет существовать?
    • +1
      Такие сервисы уже есть и много. Я в своё время пользовался этим. Не могу сказать, хуже он или лучше, но меня результат вполне устраивал.
    • 0
      А какого рода информацию Вы хотели бы получить от сервиса?
      В планах удалять эту страничку пока не было.
  • 0
    А класс скрипт вы случайно не рассшарите?

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.