在轮廓对象周围生成颜色直方图

时间:2012-03-09 04:29:43

标签: opencv computer-vision emgucv

嘿,OpenCV / Emgu大师,

我有一个我正在生成轮廓的图像,见下文。我正在尝试生成基于颜色直方图的修剪图像的搜索空间来寻找。如何围绕突出的物体轮廓获取遮罩并遮挡剩余的遮罩。所以我有两个问题:

  1. 如何在轮廓外“反转”图像?洪水填充反转,不是吗?我对OpenCV中的所有选项感到困惑。

  2. 其次,如何从轮廓对象生成一维颜色直方图,在这种情况下,红色汽车排除黑色背景,只生成包含汽车的颜色直方图。

  3. 我如何在OpenCV中执行此操作(最好是在Emgu / C#代码中)?

    Source Image Contoured Image

1 个答案:

答案 0 :(得分:2)

也许是这样的?使用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

示例直方图渲染功能也很简单 - 但我认为它显示了这个想法(以及汽车主要是红色的!)。请注意OpenCV对Hue的解释范围仅来自 [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)

(我认为这更符合预期,因为然后将面具单独导出并应用于完全不同的图像。直方图在两种情况下大致相同......)