Comments 76
Хорошая работа, молодец
Оффтопом — рыжие круты.
Спасибо за скрипт, думаю, пригодится.
ЗЫ Никто не знает, с помощью чего можно быстро отделить цветные фото от ч/б? Есть, к примеру, большая папка с кучей фоток, где есть и те, и те. Нужно быстрое решение, позволяющее выделить (переместить) только цветные или только ч/б.
Всем спасибо, автору плюсы.
Спасибо за скрипт, думаю, пригодится.
ЗЫ Никто не знает, с помощью чего можно быстро отделить цветные фото от ч/б? Есть, к примеру, большая папка с кучей фоток, где есть и те, и те. Нужно быстрое решение, позволяющее выделить (переместить) только цветные или только ч/б.
Всем спасибо, автору плюсы.
Ммм, ну да, там есть поиск по цветам, только как это поможет мне разделить мои собственные фотки?))
Переводить в HSV и строить гистограмму H. Если получим только один тон (узкую полосу), изображение явно монохромное (черно-белое, либо подкрашенное).
Спасибо, будем посмотреть.
Если рассматривать решение на PHP, то построение гистограммы не самое идеальное решение.
Тут вполне можно дополнить выложенный мною класс. Ч/б это по сути цвета у которых r=g=b. Собственно ставится условие, бежит цикл до первого нарушения, иначе изображение цветное.
Тут вполне можно дополнить выложенный мною класс. Ч/б это по сути цвета у которых r=g=b. Собственно ставится условие, бежит цикл до первого нарушения, иначе изображение цветное.
Ну, на сях это делается просто. С пыхпыхом я не знаком, да и не представляю, зачем локальное приложение на пыхпыхе писать.
А вообще, можно попробовать эту задачу решить при помощи простого скриптика: посредством ImageMagic'овского identify получить информацию о статистике по изображению; затем grep'ом выделить статистику по цветам; а затем сравнить средние и экстремальные значения RGB, а также их дисперсии. Если они будут примерно одинаковыми, изображение наверняка черно-белое. Правда, монохромные (окрашенные) изображения так не определить.
А вообще, можно попробовать эту задачу решить при помощи простого скриптика: посредством ImageMagic'овского identify получить информацию о статистике по изображению; затем grep'ом выделить статистику по цветам; а затем сравнить средние и экстремальные значения RGB, а также их дисперсии. Если они будут примерно одинаковыми, изображение наверняка черно-белое. Правда, монохромные (окрашенные) изображения так не определить.
Почему тут не выдаёт бирюзовый цвет губ?
пс: и да. это первая попавшаяся картинка на моём компьютере.
пс: и да. это первая попавшаяся картинка на моём компьютере.
Также работают и ч/б изображения, хотя с ними возможны баги.
Например, такие?
Например, такие?
Какая девушка красивая…
собственно модель: vk.com/id12825453
А скрипт на выходе дает превалирующие цвета именно из самого изображения, или просто выводит похожие?
Я забыл упомянуть, что алгоритм был описан в прошлой статье.
Цвета он берет из самого изображения, но их он сглаживает при наличии подобных цветов. Т.е. если есть градиент на изображении, то он выдаст некое среднее из этого градиента (с учетом яркости само собой).
Если, к примеру, изображение наполнено белым (255,255,255) цветом на 90% и серым (200,200,200) на 10%, то в итоге он должен выдать серый (250,250,250)
Цвета он берет из самого изображения, но их он сглаживает при наличии подобных цветов. Т.е. если есть градиент на изображении, то он выдаст некое среднее из этого градиента (с учетом яркости само собой).
Если, к примеру, изображение наполнено белым (255,255,255) цветом на 90% и серым (200,200,200) на 10%, то в итоге он должен выдать серый (250,250,250)
UFO just landed and posted this here
Может кто-нибудь сделает сайт-сервис? Загрузил фотку, на выходе получил результат. Я бы пользовался!
skifcha популярен я смотрю, даже группа вконтакте есть)
В статье нехватает ссылки на реализацию алгоритма, исходник.
* PHP versions 4 and 5
и
public $error = 1;
Как-то не совместимы :)
и
public $error = 1;
Как-то не совместимы :)
Сделайте поддержку png, плиз.
Я писал про 2 допущения, которые делаются при анализе изображения.
1. Шаг выборки пикселей (10px)
2. Количество возвращаемых цветов
На изображении куда больше бежевых оттенков (особенно учитывая градиент), также возможно голубые оттенки просто не попали в шаг в том количестве, в котором попали бежевые.
На локалке пробежался по каждому 2 пикселю и увеличил количество яркостных интервалов до 4. Вот, что получил:
1. Шаг выборки пикселей (10px)
2. Количество возвращаемых цветов
На изображении куда больше бежевых оттенков (особенно учитывая градиент), также возможно голубые оттенки просто не попали в шаг в том количестве, в котором попали бежевые.
На локалке пробежался по каждому 2 пикселю и увеличил количество яркостных интервалов до 4. Вот, что получил:
Все-таки, по-моему, построение гистограммы изображения дало бы более правильный результат: строим гистограмму H, находим положение нескольких локальных максимумов, выдаем результат…
Я постараюсь поподробнее рассмотреть этот вариант, хотя локальные максимумы еще ни о чем не говорят. Доминирующие тона — это не просто самые часто встречающиеся цвета, а в то же время и контрастные. Этими контрастными цветами может быть цвет губной помады, маленький зеленый листок посреди снега итд. Он не обязательно будет превалировать в количестве, но будет тут же заметен глазам и поэтому в идеале он должен попасть в выдачу. Собственно я именно эту цель и преследовал, хотя работать еще много есть над чем…
Такие явно контрастирующие цвета и дадут локальные максимумы (пусть даже небольшие) на гистограмме. Например, если у вас монохромное голубовато-черное изображение с ярко красной розой, то гистограмма даст всего два максимума: главный — для голубого и маленький локальный — для красного. Если мы прогоним гистограмму через лапласиан гауссианы, получим две области с отрицательными значениями, соответствующие локальному и глобальному максимуму. Сортируя затем эти области по значению на гистограмме, мы сможем выделить нужные цвета.
Да, близкие цвета можно объединять (т.е., например, если у нас уйма локальных минимумов в синей области, мы просто расширяем ее и суммируем в один синий цвет).
Да, близкие цвета можно объединять (т.е., например, если у нас уйма локальных минимумов в синей области, мы просто расширяем ее и суммируем в один синий цвет).
Гистограмма мало что дает:
Брались максимумы в пространстве (r/s, g/s, b/s, s/768), где s=r+g+b
Брались максимумы в пространстве (r/s, g/s, b/s, s/768), где s=r+g+b
А если попробовать найти алгоритмы расчета палитр при оптимизации gif файлов: там же есть несколько разных и ими на сегодня пользуются Очень многие.
Ограничение 6тью цветами — все портит. Ну и зачастую «тон» совсем не тот что ожидается. Как напримере последней фото с девушкой. Цвет лица «ушел» а появился какойто непонятный розовый.
Отлично! Поможет юзерам кастомизировать свои интерфейсы, раскрасив панели и виджеты в цвета, выданные скриптом, которому передана ему обоину. Лично у меня всегда вызывает небольшое затруднение подбор цветовой темы для wm, это значительно упрощает процесс «стилизации».
Notice: Unable to open image file in /var/www/u1063004/data/www/blog.assorium.ru/jpeg/getImageColor.php on line 59
Warning: Invalid argument supplied for foreach() in /var/www/u1063004/data/www/blog.assorium.ru/jpeg/index.php on line 18
Warning: arsort() expects parameter 1 to be array, null given in /var/www/u1063004/data/www/blog.assorium.ru/jpeg/index.php on line 101
на этой картинке сломалось:
интересный материал, кстати у адоба есть очень интересный инструмент на флеше, с ч/б отлично справляется, при чем есть возможность самому подкорректировать «точку сбора» и он показывает откуда берет цвет, самое то для дизайнера
Не всегда верно работает (нет розового и сиреневого):
Но за старание — большой плюс, конечно)
Но за старание — большой плюс, конечно)
Notice: Unable to open image file in /var/www/u1063004/data/www/blog.assorium.ru/jpeg/getImageColor.php on line 59
Warning: Invalid argument supplied for foreach() in /var/www/u1063004/data/www/blog.assorium.ru/jpeg/index.php on line 18
Warning: arsort() expects parameter 1 to be array, null given in /var/www/u1063004/data/www/blog.assorium.ru/jpeg/index.php on line 101
Я построил карту распределения цвета (проекция на плоскость r+g+b=1) для фотографии дерева:
и «незабудки»:
красный цвет — справа внизу, синий — слева внизу, зеленый — вверху.
Я сочувствую программам, которые пытаются найти в этом тумане «доминирующие цвета» :)
и «незабудки»:
красный цвет — справа внизу, синий — слева внизу, зеленый — вверху.
Я сочувствую программам, которые пытаются найти в этом тумане «доминирующие цвета» :)
Яркость точки определятся количеством вхождений цвета?
Определить доминирующий цвет или цвета на самом деле не трудная задача. Куда труднее выбрать контрастные цвета. Возможно изображение будет изобиловать какими-то 4 превалирующими оттенками, которые будут занимать 98% изображения, но если где-то посередине появится цвет, контрастный остальным, окружающим его и он займет оставшиеся 2% изображения, то он не попадет в список «доминирующих», но должен попасть в список основных тонов изображения.
Я решаю это проблему практически в лоб и каждый раз лишь заостряю инструмент, но не создаю нового подхода… Соответственно, если в следующий раз меня опять припрет усовершенствовать приложение, т.е. я его буду переписывать с 0.
Определить доминирующий цвет или цвета на самом деле не трудная задача. Куда труднее выбрать контрастные цвета. Возможно изображение будет изобиловать какими-то 4 превалирующими оттенками, которые будут занимать 98% изображения, но если где-то посередине появится цвет, контрастный остальным, окружающим его и он займет оставшиеся 2% изображения, то он не попадет в список «доминирующих», но должен попасть в список основных тонов изображения.
Я решаю это проблему практически в лоб и каждый раз лишь заостряю инструмент, но не создаю нового подхода… Соответственно, если в следующий раз меня опять припрет усовершенствовать приложение, т.е. я его буду переписывать с 0.
Да, разрешение картинки примерно 1024 точки на расстояние от «синего» до «красного», чем больше цветов пикселей попало в данную точку, тем она темнее.
Контрастные цвета на гистограмме будут выглядеть как изолированные облака точек. На этих картинках их не видно, но на других встречаются. Но вообще, видно, что такая гистограмма, не привязанная к реальным 2D-координатам — это неправильный инструмент. Нужна какая-то двойная статистика: одна найдет цветные пятна (сгущения в 5-мерном пространстве x,y,r,g,b?), а вторая сгруппурует их по цветам и выделит «основные». Я тут вижу сразу два или три подхода, но они наверняка тоже работать не будут :(
Контрастные цвета на гистограмме будут выглядеть как изолированные облака точек. На этих картинках их не видно, но на других встречаются. Но вообще, видно, что такая гистограмма, не привязанная к реальным 2D-координатам — это неправильный инструмент. Нужна какая-то двойная статистика: одна найдет цветные пятна (сгущения в 5-мерном пространстве x,y,r,g,b?), а вторая сгруппурует их по цветам и выделит «основные». Я тут вижу сразу два или три подхода, но они наверняка тоже работать не будут :(
Ну если абстрагироваться до твоего варианта, то я по сути, пытаюсь найти центр облака подобных и выделить центровой цвет, тем самым убиваю большое количество точек вокруг облака. После нескольких итераций, остаются довольно отчетливые отдельно-стоящие островки, которые как раз и необходимы.
Но тут возникает самая большая трудность, это обработка облака. С одной стороны необходимо выделить центр, что уже является трудоемкий задачей, а с другой стороны этот центр должен выбирать. В моем алгоритме есть такая зависимость, что цвет A похож на B и цвет С похож на В, но А не похож на С. Соответственно центру А необходимо выбирать, поглощать цвет В или нет, но по сути такое реализовать крайне сложно.
Т.к. я все преследую умеренную ресурсоемкость, то и решение должно быть крайне простым, поэтому я даже и не пытаюсь лезть в дебри подобных алгоритмов. Проще всего задействовать человеческий фактор по окончании обработки, пусть человек доделывает все, как надо.
Но я думаю, что следующим шагом обработки я возьму HSV координаты, т.к. с помощью них крайне легко определить похожесть цвета и яркость цвета.
Но тут возникает самая большая трудность, это обработка облака. С одной стороны необходимо выделить центр, что уже является трудоемкий задачей, а с другой стороны этот центр должен выбирать. В моем алгоритме есть такая зависимость, что цвет A похож на B и цвет С похож на В, но А не похож на С. Соответственно центру А необходимо выбирать, поглощать цвет В или нет, но по сути такое реализовать крайне сложно.
Т.к. я все преследую умеренную ресурсоемкость, то и решение должно быть крайне простым, поэтому я даже и не пытаюсь лезть в дебри подобных алгоритмов. Проще всего задействовать человеческий фактор по окончании обработки, пусть человек доделывает все, как надо.
Но я думаю, что следующим шагом обработки я возьму HSV координаты, т.к. с помощью них крайне легко определить похожесть цвета и яркость цвета.
Я сначала думал, что основная проблема будет в «побочном пике на склоне горы» в гистограмме. Но картинки показали, что никаких склонов в фотографиях, в общем, нет — есть острые пики разной высоты там и сям разбросанные по плато. Про поглощение одного цвета другим казалась разумной такая идея: если по пути от цвета A к цвету B по гистограмме (хорошо сглаженной, т.е. с крупными ячейками) нам придется пройти через точку, высота которой ниже, чем сколько-то процентов от минимума из высот A, B, то эти цвета различны. Таким образом, чтобы проверить, что локальный максимум высотой H окажется «цветом», мы возьмем множество клеток гистограммы со значением не меньше cf*H, выделим связную область, содержащую нашу точку, и проверим, является ли точка в ней общим максимумом. Если да — то она есть «цвет», и можно искать центр области вокруг нее? либо брать среднее от всех пискселей, попавших в область, либо работать только с одной клеткой гистограммы.
А что, попробую. У меня все готово, надо только поправить пару строчек в поиске связных компонент…
А что, попробую. У меня все готово, надо только поправить пару строчек в поиске связных компонент…
Попробуйте вначале перевести цвет пикселя в цветовое пространоство L*a*b. Оно спроектировано таким образом, чтобы растояние между похожими цветами было линейным для восприятия.
Если же говорить про RGB, то большинство файлов созданы для гаммы 2.2. Поэтому, перед обработкой, их надо перевести обратно в линейное цветовое пространство.
Если же говорить про RGB, то большинство файлов созданы для гаммы 2.2. Поэтому, перед обработкой, их надо перевести обратно в линейное цветовое пространство.
Я так и не понял, почему автор не использовал CIE L*a*b. По-моему, это очень удобно. Когда-то делал проект кластеризации, так вот в матлабе сначала переводил в CIELAB, а потом уже использовал кластеризацию по методу k-средних для сегментации изображений. Т.к. пространство содержит две хроматических составляющих цвета и одну управляющую светлостью, то светлость выкидывал и искал расстояние по двум координатам.
Мне становится страшно при одном взгляде на формулы пересчета. Кроме того, смущает огромное количество точек, не имеющих RGB-представления. Да и если посмотреть в фотошопе на кары цветов при фиксированной одной из координат, то видно, что ничего не понятно — какие-то странные радужные переливы, с огромными областями, которые заполнены, на взгляд, одним цветом. Непонятно. А если непонятно, как можно им пользоваться?
Считать действительно получается немало, однако не все так сложно. Для начала делаем нормальное преобразование RGB -> XYZ
После преобразования получим данные в пространстве XYZ. Потом делаем преобразование XYZ -> L*a*b, как это сделать есть википедия.
Ну а насчет того что Вы далее написали, то L*a*b имеет огромный цветовой охват и перевод в него не связан с потерями. Если перевести RGB -> LAB -> RGB, то потерь не будет.
После преобразования получим данные в пространстве XYZ. Потом делаем преобразование XYZ -> L*a*b, как это сделать есть википедия.
Ну а насчет того что Вы далее написали, то L*a*b имеет огромный цветовой охват и перевод в него не связан с потерями. Если перевести RGB -> LAB -> RGB, то потерь не будет.
Если переводить в линейное пространство, все получается гораздо хуже. Основным цветом практически любой картинки становится черный (если брать метрику в линейном RGB-пространстве) или оттенки черного (если отделять яркость от оттенка/насыщенности). Там слишком большая плотность точек. Пожалуй, лучше, наоборот, в качестве координаты взять логарифм яркости.
В конечном итоге, через гистограмму все получилось:
Другие примеры здесь
А программа здесь (для .NET)
Программа управляется тремя параметрами — число ячеек на одной стороне гистограммы (если ввести N, то построит гистограмму N*N*N), число, показывающее, насколько глубокой должна быть щель между цветами, чтобы они считались различными, и максимальное количество цветов, которые будут выведены на картинку.
Чем меньше первые два параметра (до определенных пределов), тем больше оттенков «затянет» каждый найденный цвет, и тем больше шансов будет пробиться у более редких цветов.
Другие примеры здесь
А программа здесь (для .NET)
Программа управляется тремя параметрами — число ячеек на одной стороне гистограммы (если ввести N, то построит гистограмму N*N*N), число, показывающее, насколько глубокой должна быть щель между цветами, чтобы они считались различными, и максимальное количество цветов, которые будут выведены на картинку.
Чем меньше первые два параметра (до определенных пределов), тем больше оттенков «затянет» каждый найденный цвет, и тем больше шансов будет пробиться у более редких цветов.
Очень даже хорошо справляется Ваш алгоритм. Правда на выходе почти у каждого оттенка есть сильно похожий на него…
Да и просмотрев Ваши работы, заметил ту же пропасть, что и у меня. Некоторые, даже довольно часто встречающиеся цвета он совсем не выводит… Я откомментировал в пикассе 2 самые выделяющиеся работы.
Да и просмотрев Ваши работы, заметил ту же пропасть, что и у меня. Некоторые, даже довольно часто встречающиеся цвета он совсем не выводит… Я откомментировал в пикассе 2 самые выделяющиеся работы.
Поигравшись с параметрами, иногда можно заставить его найти цвета, встречающиеся реже (чуть позже попробую построить и выгрузить примеры). Но без участия человека здесь трудно.
Обидно, что в итоге у меня получился самый примитивный алгоритм — не помогли ни k-d деревья, ни вычисление фрактальной размерности, ни прочие способы автоматической оценки параметров. С одной стороны, чем примитивнее, тем, казалось бы, больше возможностей куда-нибудь его развивать, с другой — если все делается одним волшебным параметром, до дополнительные ручки управления прикручивать может оказаться некуда.
Обидно, что в итоге у меня получился самый примитивный алгоритм — не помогли ни k-d деревья, ни вычисление фрактальной размерности, ни прочие способы автоматической оценки параметров. С одной стороны, чем примитивнее, тем, казалось бы, больше возможностей куда-нибудь его развивать, с другой — если все делается одним волшебным параметром, до дополнительные ручки управления прикручивать может оказаться некуда.
Оказывается, мой алгоритм работал из-за ошибки в программе: я случайно запретил ему объединять цвета с разной яркостью. После того, как я ошибку исправил, он радостно объявил все цвета на картинке оттенками черного :(
Sign up to leave a comment.
Определение доминирующих тонов на изображении [v 1.1]