2012-10-12 23 views
7

Testuję Raspberry Pi z kodowaniem OpenCV i Python. Strumieniowanie wideo działa świetnie (średnia prędkość), ale po uruchomieniu wykrywania twarzy w strumieniu procesor jest sztywno ustawiony i odświeżanie obrazu jest powolne.Wykrywanie twarzy OpenCV jest powolne na Raspberry Pi

Oto, co mam. Jak mogę zoptymalizować mój kod?

#!/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

Twoja linia 'parser.add_option' jest obcięta, tak mi się wydaje. –

+0

Tak, jest. Ale nie o to pytam. – honeyshell

+2

Nigdy nie powiedziałem, że to było. :-) Po prostu dając ci możliwość poprawienia tego; Zamknąłem ciąg i nawias. –

Odpowiedz

5

Mogę zaproponować Ci kaskadę LBP zamiast Haar. Wiadomo, że jest do 6 razy szybszy przy bardzo ścisłej wykrywalności.

Ale nie jestem pewien, czy jest dostępny w starym interfejsie Pythona. Klasa cv2.CascadeClassifier z nowych opakowań może wykryć kaskadę LBP.

+0

Dziękuję Andrew, znajduję tę samą odpowiedź na http://stackoverflow.com/questions/8791178/haar-cascades-vs-lbp-cascades-in-face-detection i niektóre kody testowe na http://docs.opencv.org /doc/tutorials/objdetect/cascade_classifier/cascade_classifier.html. Daje więcej nadziei na mój malinowy projekt hexapode! – honeyshell