11

ライブ ビデオ ストリームから自分の手を検出し、手のマスクを作成したいと思います。ただし、写真からわかるように、かなり悪い結果に達しています。

私の目標は手の動きを追跡することです。そのため、ビデオ ストリームを 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

そして、これが上からのサンプル写真です:

胴体と腕 ... と手のサンプル画像

4

2 に答える 2

15

ピクセル単位のしきい値を実行して「肌のピクセル」を「肌以外のピクセル」から分離するには多くの方法があり、事実上すべての色空間 (RGB を含む) に基づく論文があります。したがって、私の答えは、Chai と Ngan によるテレビ電話アプリケーションでの肌色マップを使用した紙の顔セグメンテーションに基づいています。彼らは YCbCr 色空間で作業し、非常に良い結果を得ました。この論文では、彼らに適したしきい値についても言及しています。

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

チャネルのしきい値Yは指定されていませんが、言及している論文がありますY > 80。単一の画像の場合、Y範囲全体で問題ありません。つまり、実際に肌を区別することは問題ではありません。

これは、入力、前述のしきい値によるバイナリ イメージ、および小さなコンポーネントを破棄した後の結果のイメージです。

ここに画像の説明を入力 ここに画像の説明を入力 ここに画像の説明を入力

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 をトレーニングし、この分類子に基づいて他の入力を識別します。

于 2013-02-07T16:44:14.823 に答える
3

シンプルで強力なオプションは、ヒストグラム逆投影です。たとえば、H と S (HSV 色空間から) または a* と b* (La*b* 色空間から) を使用して、手のさまざまなトレーニング画像のピクセルを使用して 2D ヒストグラムを作成します。次に、[cv2.calcBackProject][1] を使用して、ストリーム内のピクセルを分類します。非常に高速で、25 ~ 30 fps は簡単に得られるはずです。これは、関心のあるオブジェクトの色分布を学習する方法であることに注意してください。他の状況でも同じ方法を使用できます。

于 2013-02-08T10:49:24.840 に答える