【问题标题】:Issue with BackProjection and OpencvBackProjection 和 Opencv 的问题
【发布时间】:2014-12-25 20:54:17
【问题描述】:

我正在尝试使用 opencv 实现反投影算法来检测手。该算法由多个来源组成。我尝试了多种方法,例如形态学和在投影中添加背景减法以尝试获得更好的结果。我也在网上查看。但是,我继续得到下面的图片。有人对我可能做错的事情有建议吗?

-谢谢

这是我的代码,只有 backProjection:

import cv2
import numpy as np

#module for esc keyMap on my computer
import keyMappings as kM

#set up webcam
cap = cv2.VideoCapture(0)
cap.set(cv2.cv.CV_CAP_PROP_FRAME_WIDTH, 1000) 
cap.set(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT, 600)

#read a picture of a hand from my desktop
Hand = cv2.imread('/home/lie/Desktop/handPic.jpg')

#convert HSV and calc Histogram of this Pic
hsvHand = cv2.cvtColor(Hand, cv2.COLOR_BGR2HSV)
h,s,v = cv2.split(hsvHand)
roihist = cv2.calcHist([hsvHand], [0,1], None, [180,256],[0,180,0,256])
cv2.normalize(roihist,roihist,0,255,cv2.NORM_MINMAX)

#while not pressing esc
while cv2.waitKey(30) != kM.esc:

  #take pic convert HSV
  _,frame = cap.read() 
  hsvt = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)

  #backproject
  dst = cv2.calcBackProject([hsvt],[0,1],roihist,[0,180,0,256],1)


  #filtering
  disc = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(5,5))
  cv2.filter2D(dst,-1,disc,dst)



  #threshold
  ret,thresh = cv2.threshold(dst,50,255,0)


   #find contours in thresholded pic
   contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)


   ci =0
   max_area =0

   if len(contours)!=0:
      #find max contour
      for i in range(len(contours)):
        cnt = contours[i]
        area = cv2.contourArea(cnt)
        if(area>max_area):
            max_area = area
            ci =i
      #create hull around contour
      cnt = contours[ci]
      hull = cv2.convexHull(cnt)

 #Code to draw contours and show pic is ommited

这是用于帮助识别手的图像:

这是经过阈值处理的图片:

图片显然没有太多的手和很多噪音。

【问题讨论】:

    标签: python opencv back-projection


    【解决方案1】:

    自从这篇文章发布以来已经很长时间了,坦率地说,我有点惊讶没有人回复你。尽管我很确定您已经找到了答案/替代解决方案,但为了其他人的利益,我会回答这个问题。

    您所观察到的直接由您在 H-S 直方图中使用的 bin 数量引起。更大数量的 bin 意味着您将更精细地表示皮肤,这意味着您的最终直方图将无法建立皮肤的“趋势”。你绝对应该减少垃圾箱的数量。根据我的经验,对于色相和饱和度通道,大约 8 到 12 之间的任何值都可以正常工作。

    但是,这样做并不能保证得到非常漂亮的反投影图像。您仍然有一个主要问题,那就是您正在使用整个手形模板来生成直方图。事实上,模板包含很多皮肤,但手周围有很多不是皮肤的区域。您生成的最终直方图也将代表背景。根据我的经验(我有很多),即使是相对少量的噪声过滤到最终的直方图中也会在你的反投影图像中导致大量的噪声。将直方图中的背景保持在最低限度是关键。因此,请考虑在您的手模板内取一小块区域并仅在其上生成直方图。我修改了您的代码如下,它在我的配置中就像一个梦想。

    请注意,我做了一些更改,例如这只是使用按钮'q'退出,模板的路径已被修改等。大致相同。

    import cv2
    import numpy as np
    
    
    #set up webcam
    
    cap = cv2.VideoCapture(0)
    #cap.set(cv2.cv.CV_CAP_PROP_FRAME_WIDTH, 640)
    #cap.set(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT, 480)
    
    #read a picture of a hand from my desktop
    Hand = cv2.imread('handPic.jpg')
    hh,hw, __ = Hand.shape
    #convert HSV and calc Histogram of this Pic
    hsvHand = cv2.cvtColor(Hand[220:292, 110:220], cv2.COLOR_BGR2HSV)
    h,s,v = cv2.split(hsvHand)
    roihist = cv2.calcHist([hsvHand], [0,1], None, [12,12],[0,181,0,256])
    #cv2.normalize(roihist,roihist,0,255,cv2.NORM_MINMAX)
    
    #while not pressing esc
    while cv2.waitKey(30) & 0xFF != ord('q'):
    
      #take pic convert HSV
      _,frame = cap.read()
      hsvt = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
    
      #backproject
      dst = cv2.calcBackProject([hsvt],[0,1],roihist,[0,180,0,256],1)
    
    
      #filtering
    
      # ret, dst = cv2.threshold(dst,0,255,cv2.THRESH_OTSU)
    
      disc = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(5,5))
      cv2.filter2D(dst,-1,disc,dst)
    
    
      cv2.imshow("Skin Areas", dst)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-07-08
      • 1970-01-01
      • 1970-01-01
      • 2016-05-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多