2012-10-12 22 views
7

OpenCVとPythonのコーディングでRaspberry Piをテストしています。ビデオストリーミングは素晴らしい(中速)が機能しますが、ストリーム上で顔検出を実行すると、CPUが固定され、画像をリフレッシュするのが遅くなります。OpenCVの顔検出が遅いです。

これは私が持っているものです。コードを最適化するにはどうすればよいですか?

#!/usr/bin/env python 
import sys 
import cv2.cv as cv 
from optparse import OptionParser 
min_size = (20, 20) 
image_scale = 2 
haar_scale = 1.2 
min_neighbors = 2 
haar_flags = 0 

def detect_and_draw(img, cascade): 
    # allocate temporary images 
    gray = cv.CreateImage((img.width,img.height), 8, 1) 
    small_img = cv.CreateImage((cv.Round(img.width/image_scale), 
           cv.Round (img.height/image_scale)), 8, 1) 
           cv.Round (img.height/image_scale)), 8, 1) 

    # convert color input image to grayscale 
    cv.CvtColor(img, gray, cv.CV_BGR2GRAY) 

    # scale input image for faster processing 
    cv.Resize(gray, small_img, cv.CV_INTER_LINEAR) 

    cv.EqualizeHist(small_img, small_img) 

    if(cascade): 
     t = cv.GetTickCount() 
     faces = cv.HaarDetectObjects(small_img, cascade, cv.CreateMemStorage(0), 
            haar_scale, min_neighbors, haar_flags, min_size) 
     t = cv.GetTickCount() - t 
     print "detection time = %gms" % (t/(cv.GetTickFrequency()*1000.)) 
     if faces: 
      for ((x, y, w, h), n) in faces: 
       # the input to cv.HaarDetectObjects was resized, so scale the 
       # bounding box of each face and convert it to two CvPoints 
       pt1 = (int(x * image_scale), int(y * image_scale)) 
       # bounding box of each face and convert it to two CvPoints 
       pt1 = (int(x * image_scale), int(y * image_scale)) 
       pt2 = (int((x + w) * image_scale), int((y + h) * image_scale)) 
       cv.Rectangle(img, pt1, pt2, cv.RGB(255, 0, 0), 3, 8, 0) 

    cv.ShowImage("result", img) 

if __name__ == '__main__': 

    parser = OptionParser(usage = "usage: %prog [options] [camera_index]") 
    parser.add_option("-c", "--cascade", action="store", dest="cascade", type="str", help="Haar cascade file, default %default", default = "/usr/local/share/OpenCV/haarcascades") 
    (options, args) = parser.parse_args() 

    cascade = cv.Load(options.cascade) 
    capture = cv.CreateCameraCapture(0) 
    cv.NamedWindow("result", 1) 

    if capture: 
     frame_copy = None 
     while True: 
      frame = cv.QueryFrame(capture) 
      if not frame: 
       cv.WaitKey(0) 
       break 
      if not frame_copy: 
       frame_copy = cv.CreateImage((frame.width,frame.height), 
              cv.IPL_DEPTH_8U, frame.nChannels) 
      if frame.origin == cv.IPL_ORIGIN_TL: 
       cv.Copy(frame, frame_copy) 
      else: 
       cv.Copy(frame, frame_copy) 
      else: 
       cv.Flip(frame, frame_copy, 0) 

      detect_and_draw(frame_copy, cascade) 

      if cv.WaitKey(10) != -1: 
       break 
    else: 
     image = cv.LoadImage(input_name, 1) 
     detect_and_draw(image, cascade) 
     cv.WaitKey(0) 

    cv.DestroyWindow("result") 
+0

あなたの 'parser.add_option'行は切り詰められていると思います。 –

+0

はい、そうです。しかし、それは私の質問のポイントではありません。 – honeyshell

+2

私はそれを言ったことはありません。 :-)それを修正する機会を与えるだけです。私は文字列とかっこを閉じました。 –

答えて

5

Haarの代わりにLBPカスケードをお勧めします。検出率が非常に近く、最大6倍速くなることが知られています。

しかし、レガシーのPythonインターフェイスでアクセスできるかどうかはわかりません。新しいラッパーからのcv2.CascadeClassifierクラスは、LBPカスケードの検出を行うことができます。

+0

ありがとうアンドリュー、私はhttp://stackoverflow.com/questions/8791178/haar-cascades-vs-lbp-cascades-in-face-detectionとhttp://docs.opencv.orgのいくつかのテストコードで同じ答えを見つける/doc/tutorials/objdetect/cascade_classifier/cascade_classifier.html。それは私のラズベリーのhexapodeプロジェクトのためのより多くの希望を与える! – honeyshell

関連する問題