基于huesaturation直方图的皮肤检测OpenCV-Python

2024-06-28 15:43:04 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在用python编写一个小程序,用单目摄像机的2D图像来估计指向手势的方向,我正在使用opencv2.3。 我知道这有点棘手,但我有动力!:) 我的方法是首先使用面部检测来检测我确信有很多皮肤的区域:

img = cv2.imread("/home/max/recordings/cameras/imageTEST.jpg",1)
img_hsv = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
hc1 = cv2.CascadeClassifier("/home/max/haarcascade_frontalface_alt.xml")
faces1 = hc1.detectMultiScale(img)
for (x,y,w,h) in faces1:
  cv2.rectangle(img, (x,y), (x+w,y+h), 255)
crop_img = img[y+2:y+w, x+2:x+h]

我真的很想用这种方法,因为我希望我的检测对光的变化是鲁棒的。然后计算检测到的人脸图像的色调饱和度直方图进行反投影:

^{pr2}$

最后,我可以用一个阈值对图片进行二值化,跟踪头部和手部的斑点来估计指向的方向。 我对我的代码没有问题,但皮肤没有被检测到。。。 我做错什么了? 谢谢你的帮助!在

最大


Tags: 方法图像程序homeimg方向cv2max
2条回答

我最近一直在研究网络上可用的opencv示例(只是一些基本的好玩的东西)。我已经从人脸识别(有趣,但我喜欢的黑盒子)转移到手动选择HSV空间中的roi,然后使用“camshift”进行跟踪。我仍然得到了我不理解的可变结果,所以我还绘制了所有中间处理窗口,如hsv图像和backproject图像,还绘制了窗口中的直方图。突然间一切都很清楚了-你可以确切地看到电脑在用什么。在

这是我的python3.4,opencv3的工作代码。可以手动选择蒙皮。主要归功于我在网上找到的其他例子。在

“cv2.calcBAckProject”函数可以很好地显示皮肤特征。在

hsv and backproject

import numpy as np import cv2 roiPts = [] track_mode = False termination = (cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 1) roiBox = None kernel = np.ones((5, 5), np.uint8) frame_width_in_px = 640 number_of_histogram_elements=16 def selectROI(event, x,y,flags,param): global track_mode, roiPts if (event == cv2.EVENT_LBUTTONDOWN) and (len(roiPts)==4): #reselecting ROI points so take out of tracking mode and empty current roipoints roiPts=[] track_mode = False if (event==cv2.EVENT_LBUTTONDOWN) and (len(roiPts) < 4): #ROI point selection roiPts.append([x, y]) cap = cv2.VideoCapture(0) cv2.namedWindow("frame") cv2.setMouseCallback("frame", selectROI) while True: ret, frame = cap.read() if len(roiPts)<=4 and len(roiPts)>0: for x,y in roiPts: cv2.circle(frame, (x,y), 4, (0, 255, 0), 1) # draw small circle for each roi click if len(roiPts)==4 and track_mode==False: #initialize the camshift # convert the selected points to a box shape roiBox = np.array(roiPts, dtype=np.int32) s = roiBox.sum(axis=1) tl = roiBox[np.argmin(s)] br = roiBox[np.argmax(s)] #extract the roi from the image and calculate the histograme roi = frame[tl[1]:br[1], tl[0]:br[0]] roi = cv2.cvtColor(roi, cv2.COLOR_BGR2HSV) # roiHist = cv2.calcHist([roi], [0], None, [number_of_histogram_elements], [0, 180]) roiHist = cv2.normalize(roiHist, roiHist, 0, 255, cv2.NORM_MINMAX) roiBox = (tl[0], tl[1], br[0], br[1]) track_mode = True #ready for camshift if track_mode == True: #tracking mode hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) backProj = cv2.calcBackProject([hsv], [0], roiHist, [0, 180], 1) #perfrom some noise reduction and smoothing erosion = cv2.erode(backProj, kernel, iterations=2) dilate = cv2.dilate(erosion, kernel, iterations=2) (r, roiBox) = cv2.CamShift(dilate, roiBox, termination) #this takes prev roiBox and calculates the new roiBox pts = np.int0(cv2.boxPoints(r)) cv2.polylines(frame, [pts], True, (0, 255, 0), 2) #tracking box cv2.polylines(backProj, [pts], True, (0, 255, 0), 2) #tracking box cv2.polylines(dilate, [pts], True, (0, 255, 0), 2) #tracking box cv2.polylines(hsv, [pts], True, (0, 255, 0), 2) #tracking box # plot histogram polyline across the windows x = np.linspace(0,640,number_of_histogram_elements,dtype=np.int32) y = roiHist.flatten().astype(np.int32, copy=False)-255 #note frame height needs to be greater than 255 which is the max histo value y=np.absolute(y) pts2 = np.stack((x, y), axis=1) cv2.polylines(frame, [pts2], False, (0, 255, 0), 2) cv2.polylines(hsv, [pts2], False, (0, 255, 0), 2) cv2.imshow("backproject", backProj) cv2.imshow("dilate", dilate) cv2.imshow("hsv", hsv) cv2.imshow("frame", frame) if cv2.waitKey(1) & 0xFF == ord('q'): break # When everything done, release the capture cap.release() cv2.destroyAllWindows()

和13;
和13;

你试过使用YCbCr格式的Cr频道吗?当我以前用肤色进行手部检测时,我有点运气。另外,还有一个this paper,它使用了一个很好的方法来检测手。但请记住,只要您使用肤色,检测将不适用于所有手,但可以针对特定用户或一群用户进行调整。在

相关问题 更多 >