2

手を検出するために、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

これは、手の認識に役立つ画像です。 手の絵として読み込まれた画像

これはしきい値処理された画像です: ここに画像の説明を入力

写真には明らかに手の部分がほとんどなく、ノイズが多くなっています。

4

1 に答える 1

2

この投稿から非常に長い時間が経ちましたが、率直に言って、誰もあなたに返信していないことに少し驚いています. 答え/代替ソリューションを見つけたと確信していますが、他の人のためにこれに答えます。

観察しているのは、HS ヒストグラムで使用しているビンの数が直接の原因です。ビンの数が多いということは、肌をより細かく表現できることを意味します。つまり、最終的なヒストグラムで肌の「傾向」を構築することができなくなります。ビンの数を絶対に減らす必要があります。私の経験では、色相チャンネルと彩度チャンネルの両方で 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)
于 2016-01-24T13:19:46.943 に答える