在轮廓对象周围生成颜色直方图 [英] Generate Color Histogram around a contoured object
问题描述
嘿,OpenCV/Emgu大师,
Hey OpenCV/Emgu gurus,
我有一个正在为其生成轮廓的图像,请参见下文.我正在尝试生成基于颜色直方图的图像搜索空间修剪功能.我如何只在突出的物体轮廓周围放置遮罩,并遮挡其余的遮罩.所以我有一个两部分的问题:
I have an image that I am generating contour for, see below. I am trying to generate a color histogram based pruning of search space of images to look for. How can I get the mask around just the prominent object contour and block out the remaining. So I have a 2 part question:
-
如何将轮廓外的图像反转"?充水倒置,不是吗?我对OpenCV中的所有选项感到困惑.
How do I "invert" the image outside the contour? Floodfill invert, not? I am confused with all the options in OpenCV.
第二,在这种情况下,如何从轮廓对象生成一维颜色直方图,红色汽车排除黑色背景,而仅生成包括汽车的颜色直方图.
Second, how do I generate a 1-d color histogram from the contoured object in this case the red car to exclude the black background and only generate the color histogram that includes the car.
我该如何在OpenCV(最好是Emgu/C#代码)中做到这一点?
How would I do that in OpenCV (preferably in Emgu/C# code)?
推荐答案
也许是这样的吗?使用Python绑定完成,但易于将方法转换为其他绑定...
Perhaps something like this? Done using the Python bindings, but easy to translate the methods to other bindings...
#!/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压缩伪影...如果您具有原始轮廓,那么很容易将其呈现"到遮罩上.
This is a little bit clunky finding the mask - I wonder perhaps due to JPEG compression artefacts in the image... If you had the original contour it is easy enough to "render" this to a mask instead.
示例直方图呈现功能也是一个基本的功能-但我认为它显示了这个主意(以及汽车主要是红色的!).请注意,OpenCV对色相的解释仅在 [0-180]度范围内.
The example histogram rendering function is also a wee bit basic - but I think it shows the idea (and how the car is predominately red!). Note how OpenCV's interpretation of Hue ranges only from [0-180] degrees.
:如果要使用遮罩对原始图片中的颜色进行计数,请从第15行向下进行
if you want to use the mask to count colours in the original image - edit as so from line 15 downwards:
# 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)
(我想这是更想要的,因为然后分别导出蒙版并将其应用于完全不同的图像.两种情况下的直方图大致相同...)
(I think this is more what was intended, as the mask is then derived separately and applied to a completely different image. The histogram is roughly the same in both cases...)
这篇关于在轮廓对象周围生成颜色直方图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!