Алгоритм обнаружения цвета - Как мне это сделать? - PullRequest
2 голосов
/ 18 марта 2011

Я немного застрял в разработке системы распознавания цвета - я не могу придумать, как легко это сделать.

-

По сути, у меня есть библиотека изображений, которую я хочу отсортировать по цвету. Поэтому, если пользователь указывает «сортировать по синему», в верхней части результатов отображаются самые синие изображения, а в нижней части - наименее синий.

Проблема в том, что изображения не все одного цвета, поэтому он делает две вещи одновременно:

1 - поиск самой синей части изображения
2 - ранжирование этого синего цвета (на основе оттенка цвета и количества этого цвета).

Я пробовал около 3 или 4 разных подходов с разными результатами - хотя ни один из них не работал хорошо, и 2 из них были довольно математическими алгоритмами (которые все работают намного лучше на бумаге, чем на практике, ха-ха).

-

Какими разными путями я мог бы пройти весь процесс? Я, вероятно, упускаю некоторые действительно очевидные способы, которыми это могло бы работать - любая помощь или идеи очень ценились бы:)

-

РЕДАКТИРОВАТЬ: Спасибо за все ответы - вот что я попробовал до сих пор:

  • получение среднего значения rgb для всего изображения и сравнение его с синим. Сравнение проводилось с использованием нормализованных пространственных векторов rgb 3 и нахождения расстояний между ними. Это работает наименее хорошо, изображение без синего может легко появиться над изображением с частичным очень сильным синим.

  • нахождение доминирующего цвета и сравнение его с синим (снова с использованием 3 пространственных векторных расстояний). Это не сработало, так как, возможно, была большая синяя часть изображения, которая не была самой (или в верхней паре) доминирующих цветовых срезов.

  • поиск пикселей, близких к синему, усреднение всех этих значений и сравнение ответа с фактическим синим.

  • найти все пиксели, близкие к синему, увеличить счетчик и найти процент на основе количества / общего количества пикселей.

Ответы [ 6 ]

7 голосов
/ 18 марта 2011

На ум приходят две мысли:

Дешевая версия: преобразовать изображения в цветовое пространство HSV, и для каждого пикселя вычислить cos(H - target_hue) или разумное приближение (для синего, target_hue будет 240 градусов), умножить на насыщенность и усреднить это количество по всем пикселей на изображении. Высокие значения - лучшие. Обратите внимание, что цвета, которые ближе к желтому, чем к синему, имеют «отрицательную голубизну», а черный, белый и чистый серый имеют одинаково «нулевую голубизну». Обратите внимание, что вы действительно хотите HSV, а не HSL, в этой ситуации, потому что «S» в HSL не очень хорошо отображает насыщение восприятия. Например, цвет # f8f8ff (RGB 248, 248, 255) имеет насыщенность 100% в HSL (то есть чисто синий), но выглядит почти белым. Тот же цвет в HSV имеет S-координату всего 3%, что вполне разумно.

Менее дешевая версия: преобразовать изображения в цветовое пространство CIELAB, отбросить L и вычислить расстояние в * b * пространстве между каждым пикселем и целевым цветом, а затем усреднить или среднеквадратическое значение по каждому пикселю. Низкие значения лучше.

2 голосов
/ 18 марта 2011

Я думаю, что для измерения "синевы" вам нужно принять во внимание все три компонента, а не только синий.Например, [255,255,255] - чистый белый, а не синий - но [0, 0, 30] - чистый синий, хотя его синий компонент имеет гораздо меньшую ценность.

В качестве альтернативы, вы можете преобразовать вчто-то вроде HSL или HSV, в этом случае «синеву» следует измерить немного проще (только оттенок и насыщенность).

1 голос
/ 18 марта 2011

Я бы искал алгоритм для создания 256 цветовых палитр из 24-битных изображений (см. http://en.wikipedia.org/wiki/Color_quantization для получения дополнительной информации), а затем посмотрел бы, какие цвета в этой палитре преобладают, если изображение было сопоставлено с ним. т. е. выполнение подсчета для каждой записи 256 палитр того, сколько пикселей отображается в нем.

примечания, вам, конечно, не нужны целые 256, просто говорится 256, чтобы объяснить мое мышление. Кроме того, непосредственное изучение алгоритма для этого поколения палитры может дать вам прямой ответ.

0 голосов
/ 18 марта 2011

Я бы сказал, что нужно взять среднее значение самого RGB по всей картинке. Я бы сказал, что псевдо ниже должен дать вам «средний синий цвет» картинки.

SUMr
SUMg
SUMb    
for pixel <- image
  SUMr += pixel.r
  SUMg += pixel.g
  SUMb += pixel.b    
SUMr / pixelcount
SUMg / pixelcount
SUMb / pixelcount

Если это не сработает; тогда я бы подумал, что вам нужно будет ранжировать «синий» пиксель как взвешенный выше / ниже на основе значений G / B. Затем сложите ваши взвешенные значения и сравните их.

weight
for pixel <- image
  tweight = b
  b -= r
  b -= g
  b = 0 if b < 0
  weight += tweight
compare weights of all images.
0 голосов
/ 18 марта 2011

Если у вас есть один пиксель, я бы сказал, что его синева в терминах RGB - это значение B / (R + G + B), поэтому 1 полностью синий, а 0 вовсе не синий, а белый 1 / 3 синих. (Следите за черным, что является особым случаем.) А голубизна изображения - это средняя голубизна его пикселей. А если это слишком дорого, просто возьмите среднее значение фиксированного числа случайно выбранных пикселей.

0 голосов
/ 18 марта 2011

Вам действительно нужно найти самую голубую часть изображения? Почему бы просто не присвоить «голубоватость» изображения как среднее значение синего компонента для всех пикселей?

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

...