определение наиболее используемого цвета в изображении с помощью python

Я хочу найти наиболее используемый цвет в изображении с помощью python. например, определите цвет объекта на следующем изображении

http://www.shopcrazy.com.ph/wp-content/images/2007/02/shiny-bags-01.jpg.

Как определить базовый цвет из кодов RGB (пример - красный на приведенном выше изображении).

6 ответов


поскольку вам, скорее всего, не понадобится гистограмма всех миллионов цветов, которые возможны с использованием 24-битного цветового пространства, я предлагаю вместо этого преобразовать изображение в пространство HSV. Затем вы можете разделить часть оттенка этого пространства на несколько ячеек, которые описывают оттенки, которые вы хотите найти ("темно-красный", "оранжевый красный" или что-то еще). Затем сделайте гистограмму этих бункеров и найдите, какой из них является доминирующим оттенком, который является "цветом".

статьи в Википедии http://en.wikipedia.org/wiki/HSL_and_HSV должен заставить вас начать. Если вы используете библиотеку обработки изображений, скорее всего, существует функция rgb-to-hsv/hsl.

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


подход грубой силы-это цикл по всем пикселям изображения и подсчет значений R, G, B. Более изысканный подход-использовать Библиотека Изображений Python функция гистограммы и вычислить среднее значение всех цветов.


Я бы использовал библиотеку изображений Python. Это фрагмент кода, который вычисляет количество белых/небелых пикселей в изображении.

import sys

from PIL import Image

im = Image.open(sys.argv[1])
white = 0
black = 0
for i in im.getdata():
  if i == (255,255,255):
    white += 1
  else:
    # we assume black everything that is not white:
    black += 1
print im.size[0],im.size[1],white,black

в вашем случае я бы сделал словарь, чтобы каждый rgb тройной против счетчика, поэтому я бы переработал программу так (не тестировал)

import sys

from PIL import Image

im = Image.open(sys.argv[1])
count= {}
for i in im.getdata():
  if not count.has_key(i):
      count[i] = 0

  count[i] += 1

теперь вы можете проверить один с самым высоким количеством и получить наиболее используемый RGB тройной. Конечно, если вы хотите проверить также vicinal цвета, вам придется конвертировать в HSV и проверить расстояния между различными точками HSV, а затем решить, какое расстояние слишком много. Точки, достаточно близкие в пространстве ВПГ (и, в частности, компонент оттенка), скорее всего, одного цвета и, следовательно, могут быть суммированы вместе.


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

в противном случае, вы можете (и должны ) использовать означает сдвиг. Это довольно просто, делает именно то, что вы хотите, и есть библиотеки, которые вы можете использовать, хотя я ничего не мог найти в Python. Вы можете либо реализовать его, либо вызвать код c++.

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


сортировка пикселей на месте, затем цикл через изображение и найти самый длинный пробег.


как было предложено, будет удобнее преобразовать изображение из RGB в HSV. Стандартный библиотечный модуль colorsys содержит функцию rgb_to_hsv на этот счет. Затем вы можете отобразить цвета на изображении, скажем, с H как x и S как y. Выберите точки в этом пространстве и дайте им имена; чем больше точек, тем лучше. Затем для каждого пикселя изображения найдите ближайшую из выбранных точек и используйте ее имя в качестве значения пикселя. Подсчитайте, какое имя встречается чаще всего раз.

вы хотите, чтобы я предоставил код?