Создание цветовой гистограммы вокруг контурного объекта - PullRequest
3 голосов
/ 09 марта 2012

Привет OpenCV / Emgu gurus,

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

  1. Как мне «инвертировать» изображение вне контура?Затопление инвертировать, не так ли?Меня смущают все варианты в OpenCV.

  2. Во-вторых, как мне сгенерировать 1-мерную цветную гистограмму из контурного объекта, в данном случае красный автомобиль, чтобы исключить черный фон и создать только цветовую гистограмму, которая включает автомобиль.

Как мне это сделать в OpenCV (желательно в коде Emgu / C #)?

Source Image Contoured Image

1 Ответ

2 голосов
/ 14 января 2013

Возможно, что-то подобное?Закончено использование привязок Python, но легко перевести методы в другие привязки ...

#!/usr/local/bin/python

import cv 
import colorsys

# get orginal image
orig = cv.LoadImage('car.jpg')

# show orginal 
cv.ShowImage("orig", orig)

# get mask image
maskimg = cv.LoadImage('carcontour.jpg')

# split original image into hue and value
hsv = cv.CreateImage(cv.GetSize(orig),8,3)
hue = cv.CreateImage(cv.GetSize(orig),8,1)
val = cv.CreateImage(cv.GetSize(orig),8,1)
cv.CvtColor(maskimg,hsv,cv.CV_BGR2HSV)
cv.Split(hsv, hue, None, val, None)

# build mask from val image, select values NOT black
mask = cv.CreateImage(cv.GetSize(orig),8,1)
cv.Threshold(val,mask,0,255,cv.CV_THRESH_BINARY)

# show the mask
cv.ShowImage("mask", mask)

# calculate colour (hue) histgram of only masked area
hue_bins = 180 
hue_range = [0,180]
hist = cv.CreateHist([hue_bins], cv.CV_HIST_ARRAY, [hue_range], 1) 
cv.CalcHist([hue],hist,0,mask)

# create the colour histogram 
(_, max_value, _, _) = cv.GetMinMaxHistValue(hist)
histimg = cv.CreateImage((hue_bins*2, 200), 8, 3) 
for h in range(hue_bins):
  bin_val = cv.QueryHistValue_1D(hist,h)
  norm_val = cv.Round((bin_val/max_value)*200)
  rgb_val = colorsys.hsv_to_rgb(float(h)/180.0,1.0,1.0) 
  cv.Rectangle(histimg,(h*2,0),
                ((h+1)*2-1, norm_val),
                cv.RGB(rgb_val[0]*255,rgb_val[1]*255,rgb_val[2]*255),
                cv.CV_FILLED)
cv.ShowImage("hist",histimg)

# wait for key press
cv.WaitKey(-1)

Это немного неуклюже найти маску - интересно, возможно, из-за артефактов сжатия JPEG в изображении ..Если у вас был исходный контур, вместо этого достаточно просто «визуализировать» его в маску.

mask

Пример функции рендеринга гистограммы также довольно прост - но ядумаю, это показывает идею (и как машина преимущественно красная!).Обратите внимание, что интерпретация Hue для OpenCV варьируется только от [0-180] градусов .

histogram

РЕДАКТИРОВАТЬ: , если вы хотите использоватьмаска для подсчета цветов в оригинальном изображении - отредактируйте, начиная со строки 15 и ниже:

# split original image into hue
hsv = cv.CreateImage(cv.GetSize(orig),8,3)
hue = cv.CreateImage(cv.GetSize(orig),8,1)
cv.CvtColor(orig,hsv,cv.CV_BGR2HSV)
cv.Split(hsv, hue, None, None, None)

# split mask image into val
val = cv.CreateImage(cv.GetSize(orig),8,1)
cv.CvtColor(maskimg,hsv,cv.CV_BGR2HSV)
cv.Split(hsv, None, None, val, None)

(я думаю, что это больше, чем предполагалось, поскольку маска затем получается отдельнои применяется к совершенно другому изображению. Гистограмма примерно одинакова в обоих случаях ...)

...