6

私は現在、あなたの顔とトラックオブジェクトを検出できるOpenCvの2つの例を組み合わせています。目的は、最初に顔を検出して追跡することです。CamShift + OpenCvでの顔検出

現在

マイコード:

import numpy as np 
import cv2 
import cv2.cv as cv 
import video 
import math 

cascade = 0 
counter = 0 

class App(object): 
    def __init__(self, video_src): 
     self.cam = video.create_capture(video_src) 
     ret, self.frame = self.cam.read() 
     cv2.namedWindow('camshift') 

     self.selection = None 
     self.drag_start = None 
     self.tracking_state = 0 
     self.show_backproj = False 


    def show_hist(self): 
     bin_count = self.hist.shape[0] 
     bin_w = 24 
     img = np.zeros((256, bin_count*bin_w, 3), np.uint8) 
     for i in xrange(bin_count): 
      h = int(self.hist[i]) 
      cv2.rectangle(img, (i*bin_w+2, 255), ((i+1)*bin_w-2, 255-h), (int(180.0*i/bin_count), 255, 255), -1) 
     img = cv2.cvtColor(img, cv2.COLOR_HSV2BGR) 
     cv2.imshow('hist', img) 

    ''' 
    @param: img the image for the face detection 
    @param: cascade the cascade of the ViolaJones face detection 
    @return: rects, an array of the cornors of the detected face. [x1 y1 x2 y2] 
    ''' 
    def detect(self,img, cascade): 

     # Detect the faces 
     rects = cascade.detectMultiScale(img, scaleFactor=1.1, minNeighbors=3, minSize=(150, 150), flags = cv.CV_HAAR_SCALE_IMAGE) 

     # Check if any faces are detected 
     if len(rects) == 0: 

      # return empty array 
      return [] 
     else: 
      # Get the correct x and y values 
      rects[:,2:] += rects[:,:2] 

      # loop over the recs and shrink the width with 40% 
      for rec in rects: 
       rec[0] = rec[0] + int(math.floor(((rec[2] - rec[0])*0.4)/2)) 
       rec[2] = rec[2] - int(math.floor(((rec[2] - rec[0])*0.4)/2)) 

      return rects 

    def draw_rects(self,img, rects, color): 
     for x1, y1, x2, y2 in rects: 
      cv2.rectangle(img, (x1, y1), (x2, y2), color, 2) 


    def getFace(self,img): 
     gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) 
     gray = cv2.equalizeHist(gray) 

     rects = self.detect(gray, cascade) 
     self.rects = rects 
     img = self.draw_rects(img, rects, (0, 255, 0)) 

     if len(rects) != 0: 
      self.selection = rects[0][1], rects[0][0], rects[0][3], rects[0][2] 

     return rects 


    def run(self): 
     counter= 0 
     rects = None 
     while True: 
      counter +=1; 
      ret, self.frame = self.cam.read() 
      vis = self.frame.copy() 

      if counter % 150 == 0: 
       rects = self.getFace(vis); 

      hsv = cv2.cvtColor(self.frame, cv2.COLOR_BGR2HSV) 

      mask = cv2.inRange(hsv, np.array((0., 60., 32.)), np.array((180., 255., 255.))) 
      if rects is not None: 
       self.draw_rects(vis, rects, (0, 255, 0)) 

      if self.selection: 
       print 'test0' 
       x0, y0, x1, y1 = self.selection 
       self.track_window = (x0, y0, x1-x0, y1-y0) 
       hsv_roi = hsv[x0:x1,y0:y1] 
       mask_roi = mask[x0:x1,y0:y1] 
       hist = cv2.calcHist([hsv_roi], [0], mask_roi, [16], [0, 180]) 
       cv2.normalize(hist, hist, 0, 255, cv2.NORM_MINMAX); 
       self.hist = hist.reshape(-1) 
       self.show_hist() 

       vis_roi = vis[x0:x1,y0:y1] 
       cv2.bitwise_not(vis_roi, vis_roi) 
       vis[mask == 0] = 0 
       self.tracking_state = 1 
       self.selection = None 



      if self.tracking_state == 1: 
       self.selection = None 
       prob = cv2.calcBackProject([hsv], [0], self.hist, [0, 180], 1) 
       prob &= mask 
       term_crit = (cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 1) 
       track_box, self.track_window = cv2.CamShift(prob, self.track_window, term_crit) 

       if self.show_backproj: 
        vis[:] = prob[...,np.newaxis] 
       try: cv2.ellipse(vis, track_box, (0, 0, 255), 2) 
       except: print track_box 
      cv2.imshow('camshift', vis) 


      ch = 0xFF & cv2.waitKey(5) 
      if ch == 27: 
       break 
      if ch == ord('b'): 
       self.show_backproj = not self.show_backproj 
     cv2.destroyAllWindows() 


if __name__ == '__main__': 
    import sys, getopt 

    args, video_src = getopt.getopt(sys.argv[1:], '', ['cascade=', 'nested-cascade=']) 
    try: video_src = video_src[0] 
    except: video_src = 0 
    args = dict(args) 
    cascade_fn = args.get('--cascade', "haarcascade_frontalface_alt.xml") 
    cascade = cv2.CascadeClassifier(cascade_fn) 

    App(video_src).run() 

現在、私は顔が最初に(緑の四角形で)だったと何(赤楕円形で)現時点で追跡される場所を示します。私は顔を検出することができますが、顔のトラッカーは、常に(私は1つまたは2つの肩に)私の顔以外のすべてのものを追跡し続けます。私はそれが座標と関係があると思ったが、私はそれらをチェックして、彼らはうまく見える(mask_roi、hsv_roi、vis_roi)。例: enter image description here

誰かが間違いを指摘できますか?

+0

こんにちは@Ojtwist、私はここでこれを見て、もしあなたが私の問題をぶち壊すことができるかどうか疑問に思っていました:http://stackoverflow.com/questions/16493008/using-opencv-detectmultiscale-to-find-my-face – user592419

答えて

2

コードを実行できませんでした(ビデオという名前のモジュールはありません)。私はOpenCVの2.4.4を使用していますし、次のようにあなたの問題に私の解決策は次のとおりです。

  1. すると、あなたの顔が正常に点灯していることを確認します
  2. プレイ(影は、明るく自然な肌の色は、暗い背景には、多くのことができますありません) hsvの値はmask = cv2.inRange(hsv, np.array((0., 60., 32.)),np.array((180., 255., 255.)))である。私はそれらの使用しています:np.array((0., 51., 89.))を、np.array((17., 140., 255.))

ヒント:cv2.namedWindow('camshift')cv2.namedWindow('mask')

を置く:あなたはそれが

後にどのように動作するかも見ることができるようにあなたは自分のマスクのためのウィンドウを作ることができる

以降:mask = cv2.inRange... put cv2.imshow('mask', mask)またはmask_roi

+0

ビデオモジュールは、opencvで与えられた標準のPythonモジュールです。 opencvフォルダ(video.py)で検索すると見つかります。私はあなたの提案を後で調べます。 – Ojtwist

+0

私はこれらの値で遊んでいましたが、それはより良く機能しますが、今でも私の首を追跡しています。境界ボックスを制限する方法がわかります。 – Ojtwist