计算机视觉:掩盖人手

时间:2013-02-07 13:14:11

标签: python opencv computer-vision

我想从实时视频流中检测到我的手并创建一个我的手的面具。然而,正如你从图片中看到的那样,我的结果非常糟糕。

我的目标是跟踪手部动作,所以我所做的是将视频流从BGR转换为HSV色彩空间,然后我对图像进行阈值处理以隔离手的颜色,然后我试图找到轮廓我的手虽然最后的结果并不是我想要达到的目的。

我怎样才能改善最终结果?

import cv2
import numpy as np

cam = cv2.VideoCapture(1)
cam.set(3,640)
cam.set(4,480)
ret, image = cam.read()

skin_min = np.array([0, 40, 150],np.uint8)
skin_max = np.array([20, 150, 255],np.uint8)    
while True:
    ret, image = cam.read()

    gaussian_blur = cv2.GaussianBlur(image,(5,5),0)
    blur_hsv = cv2.cvtColor(gaussian_blur, cv2.COLOR_BGR2HSV)

#threshould using min and max values
    tre_green = cv2.inRange(blur_hsv, skin_min, skin_max)
#getting object green contour
    contours, hierarchy = cv2.findContours(tre_green,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)

#draw contours
    cv2.drawContours(image,contours,-1,(0,255,0),3)

    cv2.imshow('real', image)
    cv2.imshow('tre_green', tre_green)   

    key = cv2.waitKey(10)
    if key == 27:
        break

这里是图片链接:https://picasaweb.google.com/103610822612915300423/February7201303。 带图像的新链接以及轮廓,蒙版和原始图像。 https://picasaweb.google.com/103610822612915300423/February7201304

以上是上面的示例图片:

Sample picture of a torso with arms ... and a hand

2 个答案:

答案 0 :(得分:14)

有许多方法可以执行像素方式阈值以将“皮肤像素”与“非皮肤像素”分开,并且有几乎基于任何色彩空间(甚至使用RGB)的纸张。因此,我的答案仅仅基于Chai和Ngan在可视电话应用中使用肤色映射的纸张分割。他们使用YCbCr色彩空间并得到了相当不错的结果,该论文还提到了一个适合他们的阈值:

(Cb in [77, 127]) and (Cr in [133, 173])

未指定Y频道的阈值,但有些论文提到Y > 80。对于您的单张图片,整个范围内的Y都很好,即实际区分皮肤无关紧要。

这是输入,根据提到的阈值的二进制图像,以及丢弃小组件后得到的图像。

enter image description here enter image description here enter image description here

import sys
import numpy
import cv2

im = cv2.imread(sys.argv[1])
im_ycrcb = cv2.cvtColor(im, cv2.COLOR_BGR2YCR_CB)

skin_ycrcb_mint = numpy.array((0, 133, 77))
skin_ycrcb_maxt = numpy.array((255, 173, 127))
skin_ycrcb = cv2.inRange(im_ycrcb, skin_ycrcb_mint, skin_ycrcb_maxt)
cv2.imwrite(sys.argv[2], skin_ycrcb) # Second image

contours, _ = cv2.findContours(skin_ycrcb, cv2.RETR_EXTERNAL, 
        cv2.CHAIN_APPROX_SIMPLE)
for i, c in enumerate(contours):
    area = cv2.contourArea(c)
    if area > 1000:
        cv2.drawContours(im, contours, i, (255, 0, 0), 3)
cv2.imwrite(sys.argv[3], im)         # Final image

最后,有相当数量的论文不依赖于单个像素分类来完成此任务。相反,它们从已知包含皮肤像素或非皮肤像素的标记图像的基础开始。从那里他们训练,例如,SVM,然后基于这个分类器区分其他输入。

答案 1 :(得分:3)

一个简单而强大的选项是直方图反投影。例如,使用来自手的不同 training 图像的像素,使用H和S(来自HSV颜色空间)或*和b *(来自La * b *颜色空间)创建2D直方图。然后使用[cv2.calcBackProject] [1]对流中的像素进行分类。它的速度非常快,你应该可以轻松获得25到30 fps。请注意,这是一种了解感兴趣对象的颜色分布的方法。在其他情况下也可以使用相同的方法。