我正在尝试用opencv实现反投影算法来检测手。该算法由多个源组成。我尝试了多种方法,如形态学和为投影添加backgroundSubtraction,以试图获得更好的结果。我也在网上看了。但是,我继续得到下面的图片。有没有人对我可能做错了什么有建议?
- 谢谢你
这是我的代码,只有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
这是用于帮助识别手的图像:
这是阈值图片:
图片显然没有显示出很多手和很多噪音。
答案 0 :(得分:2)
这篇帖子以来已经很长时间了,坦率地说,我有点惊讶没有人回应你。虽然我很确定你已找到答案/替代解决方案,为了别人的利益,我会回答这个问题。
您观察的内容直接由您在H-S直方图中使用的垃圾箱数量引起。更多的垃圾箱意味着您将更精细地表示皮肤,这意味着您的最终直方图将无法建立一个"趋势"皮肤你应该绝对减少垃圾箱的数量。根据我的经验,Hue和饱和度通道的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)