Computer vision: OpenCV realtime face detection in Python

Per festeggiare degnamente l’arrivo del mio nuovo portatile in famiglia ho pensato di renderlo in grado di riconoscere volti umani da una sorgente video in tempo reale.

Video dell’applicazione realizzata

Segue il video dimostrativo dell’applicazione realizzata:

OpenCV (Open Source Computer Vision Library)

Era da tempo che desideravo utilizzare la libreria Open CV per tornare a fare qualche esperimento di Computer Vision e per esplorare le sue tanto decantate potenzialità.

OpenCV è una libreria rilasciata sotto licenza BSD dalla Intel per l’elaborazione realtime delle immagini e la Computer Vision.

Scritta in C e C++ è utilizzabile, tramite wrapper (sia ufficiali che non) in diversi linguaggi: Python, Ruby, Java, C# ed è stata portata sui principali sistemi operativi: GNU/Linux, FreeBSD, Mac OS X, Windows ma anche Android e iOS per lo sviluppo di applicazioni su dispositivi mobili.

Alcuni wrapper esportano solo un limitato sottoinsieme di funzionalità.

face-detection demo 009Mi sono reso conto che le potenzialità di tale libreria sono superiori alle mie più rosee aspettative: c’è tutto quello che può servire (e si può sognare) per realizzare applicazioni avanzate di Computer Vision ed elaborazione delle immagini.

Video di alcune interessanti applicazioni che è possibile realizzare

Sviluppare un’applicazione di ottima qualità per la face detection in realtime, problema normalmente complesso, diventa banale a tal punto che mi sono limitato a fare qualche ricerca su internet ed assemblare poche righe di codice Python trovate in alcuni blog.

Face Detection ed Haar-like features

L’algoritmo molto efficiente che viene utilizzato per la rilevazione dei volti, basato sulle Haar wavelet, è stato elaborato da Viola-Jones nell’ambito dell’object detection ed è stato pensato proprio per il problema della face detection in tempo reale.

Con OpenCV è possibile addestrare nuovi identificatori di oggetti tuttavia sono già presenti i seguenti classificatori (in formato xml):

haarcascade_eye_tree_eyeglasses.xml
haarcascade_eye.xml
haarcascade_frontalface_alt2.xml
haarcascade_frontalface_alt_tree.xml
haarcascade_frontalface_alt.xml
haarcascade_frontalface_default.xml
haarcascade_fullbody.xml
haarcascade_lefteye_2splits.xml
haarcascade_lowerbody.xml
haarcascade_mcs_eyepair_big.xml
haarcascade_mcs_eyepair_small.xml
haarcascade_mcs_lefteye.xml
haarcascade_mcs_mouth.xml
haarcascade_mcs_nose.xml
haarcascade_mcs_righteye.xml
haarcascade_mcs_upperbody.xml
haarcascade_profileface.xml
haarcascade_righteye_2splits.xml
haarcascade_upperbody.xml

Nelle mie prove, dopo aver individuato il volto, ho provato a rilevare anche gli occhi e la bocca ma in questo caso i risultati non mi hanno soddisfatto.

Sorgente Python

I miei esperimenti sono stati effettuati su una macchina GNU/Linux Ubuntu 11.04 con OpenCV 2.1.

E’ richiesto il pacchetto python-opencv, presente nei repository ufficiali e si assume che nel path dello script sia presente una directory haarcascades contenente i vari xml necessari per la detection.

Su Ubuntu 11.04 è possibile trovarli nella directory:

/usr/share/doc/opencv-doc/examples/haarcascades/haarcascades/

segue il codice sorgente utilizzato per la realizzazione del video:

#!/usr/bin/python

#----------------------------------------------------------------------------
# Face Detection Test (OpenCV)
#
# thanks to:
# http://japskua.wordpress.com/2010/08/04/detecting-eyes-with-python-opencv
#----------------------------------------------------------------------------

import cv
import time
import Image

def DetectFace(image, faceCascade):

    min_size = (20,20)
    image_scale = 2
    haar_scale = 1.1
    min_neighbors = 3
    haar_flags = 0

    # Allocate the temporary images
    grayscale = cv.CreateImage((image.width, image.height), 8, 1)
    smallImage = cv.CreateImage(
            (
                cv.Round(image.width / image_scale),
                cv.Round(image.height / image_scale)
            ), 8 ,1)

    # Convert color input image to grayscale
    cv.CvtColor(image, grayscale, cv.CV_BGR2GRAY)

    # Scale input image for faster processing
    cv.Resize(grayscale, smallImage, cv.CV_INTER_LINEAR)

    # Equalize the histogram
    cv.EqualizeHist(smallImage, smallImage)

    # Detect the faces
    faces = cv.HaarDetectObjects(
            smallImage, faceCascade, cv.CreateMemStorage(0),
            haar_scale, min_neighbors, haar_flags, min_size
        )

    # If faces are found
    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))
            pt2 = (int((x + w) * image_scale), int((y + h) * image_scale))
            cv.Rectangle(image, pt1, pt2, cv.RGB(255, 0, 0), 5, 8, 0)

    return image

#----------
# M A I N
#----------

capture = cv.CaptureFromCAM(0)
#capture = cv.CaptureFromFile("test.avi")

#faceCascade = cv.Load("haarcascades/haarcascade_frontalface_default.xml")
#faceCascade = cv.Load("haarcascades/haarcascade_frontalface_alt2.xml")
faceCascade = cv.Load("haarcascades/haarcascade_frontalface_alt.xml")
#faceCascade = cv.Load("haarcascades/haarcascade_frontalface_alt_tree.xml")

while (cv.WaitKey(15)==-1):
    img = cv.QueryFrame(capture)
    image = DetectFace(img, faceCascade)
    cv.ShowImage("face detection test", image)

cv.ReleaseCapture(capture)

Share

47 thoughts on “Computer vision: OpenCV realtime face detection in Python

  1. Socio, risultati google:
    computer vision -> posizione 7
    computer vision wrapper -> posizione 5
    computer vision perl wrapper -> posizione 1
    Mi fai paura !
    Senti ma per lavorarci in perl ? Sai che sto programmando in java con android sdk ?
    e’ fighissimo socio

    • ciao Frank,
      in Perl puoi provare ad utilizzare il package:
      Image::ObjectDetect
      che si basa su OpenCV.
      a presto!!!

  2. Pingback: Frattanto nella blogosfera #9 « Ok, panico

  3. Non è che potresti spiegarmi con installare OpenCV su ubuntu per utilizzarlo con Python?Ciao e grazie

    • ciao nico, su ubuntu dovresti:
      1) aprire un terminale
      2) lanciare il comando:
      sudo apt-get install python-opencv
      il gestore dei pacchetti installera’ tutto il necessario.
      non dovresti avere problemi ma fammi sapere se ti serve ulteriore supporto.

  4. ciacio Luca,
    there are a minimal mistake in code, is lacking identation between lines 47 to 49.
    Excelent work.
    grazie

  5. Ciao Luca, complimenti per l’articolo. Stavo cercando una soluzione per far funzionare l’effetto Face detect in Kdenlive 0.8.2, sembra che manchino le librerie OpenCV. Ho provato quindi ad installare python-opencv (in Ubunutu 11.10) ma senza ottenere nessun risultato. Tu ne sai qualcosa in merito? Ti ringrazio anticipatamente. Ciao.

  6. Pingback: Python + OpenCV: FaceReplace | Quel Blog Lì

  7. Ciao Luca, io sono americano quindi ti prego di perdonare il mio povero, tradotta macchina italiana.

    Si dispone di un “import Image” comando che b0rks mio interprete Python, quindi ho appena rimosso come quel modulo non sembra essere utilizzati nel codice a tutti. Chiunque ha bisogno di aiuto con questo, questo dovrebbe risolvere il problema

    Also, you may want to leave a note that for American viewers seeing the page through Google Translate, the “def” for “def DetectFace( … )” will show up as a “final”! Definitely not right.

    Ottimo lavoro! Questo script è veramente sorprendente! Penso che ho intenzione di reimplementare in C + +.

    • Hi Nathan,

      I was wondering if you have implemented simlar project in c++?

      Thank you so much!

  8. Pingback: Raspberry PI powered Face Follower Webcam | Daniele Nicassio's blog

  9. Ciao Luca,
    splendido post, una domanda se mi è concesso, ma per quei video dove si vede l’analisi in tempo reale del viso rilevandone lo stato (arrabbiato,felice,sorpreso… etc. etc.) esiste uno script già pronto che tu sappia?
    Grazie in anticipo

  10. hi am not getting any thing
    plz help am gettin error in fallowin
    import image
    faceCascade = cv.Load(“haarcascades/haarcascade_frontalface_alt.xml”)

  11. Il tuo lavoro è incredibile e il vostro tempo il riconoscimento facciale reale e monitoraggio è solo il software di cui ho bisogno. Mi piacciono molti altri stanno lavorando su progetti. Posso si prega di utilizzare il codice sorgente? Sono convincere il tuo lavoro è proprio quello che ho bisogno di fare il mio progetto prende vita. Se si tratta di un successo, mi metterò in contatto con per i progetti futuri. Vi ringrazio per il lavoro, che mi fa ben sperare per il mio progetto e il futuro, è genere.

    rispettosamente,
    Mustafa Stanley

  12. Ciao Luca,
    ho provato il tuo codice sun raspberry pi ma mi da questo errore:

    /home/pi# python lucaa.py
    Traceback (most recent call last):
    File “lucaa.py”, line 70, in
    image = DetectFace(img, faceCascade)
    File “lucaa.py”, line 23, in DetectFace
    grayscale = cv.CreateImage((image.width, image.height), 8, 1)
    AttributeError: ‘NoneType’ object has no attribute ‘width’

    E’ possibile utilizzare python + opencv per contare il numero di faccie frontali visibili senza utilizzare un’interfaccia grafica di output o gestione? (nella fattispecie non ho X installato)

    • Sono riuscito in questo modo:

      import cv
      import Image
      from subprocess import call
      import datetime as dt
      import pytz

      # Script Batch per Raspberry Pi con Pi Cam

      rome = pytz.timezone(“Europe/Rome”)
      # Ora corrente in fuso orario locale
      d = rome.localize(dt.datetime.now())
      strImage = d.strftime(“%Y%m%d%H%M%S”);

      print (“input-“+strImage+”-“+strImageEnd+”.jpg”):

      # Scatta una foto con il raspberry
      call ([“raspistill -t 50 -ex auto -n -w 640 -h 480 -o input-” + strImage + “.jpg”], shell=True)

      # Carica l’immagine di input fatta dalla cam del raspberry
      imcolor = cv.LoadImage(“input-“+strImage+”.jpg”)

      # Carica le informazioni per rilevare gli oggetti (Viso, Occhi)
      haarFace = cv.Load(‘haarcascades/haarcascade_frontalface_default.xml’)
      haarEyes = cv.Load(‘haarcascades/haarcascade_eye.xml’)

      # Esegue l’algoritmo di ricerca e salva le informazioni degli oggetti trovati
      storage = cv.CreateMemStorage()
      detectedFace = cv.HaarDetectObjects(imcolor, haarFace, storage)
      detectedEyes = cv.HaarDetectObjects(imcolor, haarEyes, storage)

      # Disegna un rettangolo attorno alla faccia
      if detectedFace:
      print (“trovate nr. facce: “+repr(len(detectedFace)))
      for face in detectedFace:
      cv.Rectangle(imcolor,(face[0][0],face[0][1]),
      (face[0][0]+face[0][2],face[0][1]+face[0][3]),
      cv.RGB(155, 255, 25),2)

      #draw a purple rectangle where the eye is detected
      if detectedEyes:
      print (“trovati nr. occhi”+repr(len(detectedEyes)))
      for face in detectedEyes:
      cv.Rectangle(imcolor,(face[0][0],face[0][1]),
      (face[0][0]+face[0][2],face[0][1]+face[0][3]),
      cv.RGB(155, 55, 200),2)

      dd = rome.localize(dt.datetime.now())
      strImageEnd = dd.strftime(“%Y%m%d%H%M%S”)
      cv.SaveImage(“output-“+strImage+”-“+strImageEnd+”.jpg”, imcolor)
      print (“output-“+strImage+”-“+strImageEnd+”.jpg”)

      tempo = dd-d
      print (“Tempo impiegato:”+tempo.strftime(“%M%S”))

  13. Hi luca
    i’ve tried the code above but i’m getting an error :
    import Image
    ImportError: No module named Image
    how can i solve it
    waiting for your solution as soon as possible
    thank you

  14. m installing open cv 2.4 on raspberry pi in siduction …its give error after 74%completed and shows internal compiler error (program colapse) if u can help me den plz tryto help me…..

  15. Ciao!
    Voglio fare una variabile che memorizza quante facce sono state trovate nel video. Hai un suggerimento?
    Grazie.

    //

    Hi!
    I want to make a variable that stores how many faces were found in the video. Have a suggestion?
    Thank you.

  16. pi@supra ~/face_recognition_project/face_recog_1 $ sudo python face_recog_1.py
    VIDIOC_QUERYMENU: Invalid argument
    VIDIOC_QUERYMENU: Invalid argument
    VIDIOC_QUERYMENU: Invalid argument
    Traceback (most recent call last):
    File “face_recog_1.py”, line 59, in
    faceCascade = cv.Load(“haarcascades/haarcascade_frontalface_alt.xml”)
    TypeError: OpenCV returned NULL

    How do i get xml file?

  17. Ciao Luca, devo inserire in questo codice un id e un timer per ogni persona, puoi suggerirmi qualcosa? grazie

    import cv2
    import sys

    faceCascade = cv2.CascadeClassifier(“haarcascade_frontalface_default.xml”)
    eyeCascade = cv2.CascadeClassifier(“haarcascade_eye.xml”)

    video_capture = cv2.VideoCapture(0)

    while True:
    # Capture frame-by-frame
    ret, frame = video_capture.read()

    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    faces = faceCascade.detectMultiScale(
    gray,
    scaleFactor=1.1,
    minNeighbors=5,
    minSize=(30, 30),
    flags=cv2.cv.CV_HAAR_SCALE_IMAGE
    )

    # Draw a rectangle around the faces
    for (x, y, w, h) in faces:
    cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2)
    roi_gray = gray[y:y+h, x:x+w]
    roi_color = frame[y:y+h, x:x+w]
    eyes = eyeCascade.detectMultiScale(roi_gray)
    for(ex,ey,ew,eh) in eyes:
    cv2.rectangle(roi_color,(ex,ey),(ex+ew,ey+eh),(0,255,0),2)

    # Display the resulting frame
    cv2.imshow(‘Video’, frame)

    if cv2.waitKey(1) & 0xFF == ord(‘q’):
    break

    # When everything is done, release the capture
    video_capture.release()
    cv2.destroyAllWindows()

  18. Ciao Luca, innanzitutto complimentoni per l’articolo e il programma, sei indicizzato alla grandissima!
    Puoi postare il codice per implementarlo in C++ con DEVC++?
    Magari con un contatore che indica quanti volti sono stati rilevati?
    Ti ringrazio sperando in una tua risposta positiva !

    Saluti, Antonio

    • Ciao, per far funzionare questo script su Mac, è necessaria qualche modifica? Inoltre, in quale sottocartella di open-cv deve essere salvato? grazie

  19. mi da errore nell’import di cv mi dice nessun modulo chiamato cv.
    Volevo capire come hai fatto e provarlo per fare il riconoscimento delle forme.
    Grazie! 🙂

    • hai installato il pacchetto python-opencv? che sistema operativo ed eventuale distribuzione gnu/linux stai utilizzando?

  20. can you plz tell how you made it work on diff size of faces and if you scales classifiers how you scaled it??? i will be very helpful if you can provide the code……please 🙂 thanks in advance

  21. Hi Luca, i’am using ubuntu 14.04 and opencv 2.4.9, so your codec does not run in my computer, do you can help me? the error is:
    Traceback (most recent call last):
    File “/home/eliaz/opencv-2.4.9/samples/python2/face.py”, line 65, in
    faceCascade = cv.Load(“haarcascades/haarcascade_frontalface_alt.xml”)
    TypeError: OpenCV returned NULL

  22. hi
    when i run the cod this error occur:
    line 55, in
    faceCascade = cv.Load(“haarcascades/haarcascade_frontalface_alt.xml”)
    TypeError: OpenCV returned NULL

  23. Ciao, vorrei sapere se è possibile confrontare le immagini rilevate in realstream con delle immagini salvate in una cartella, per un piccolo riconoscimento facciale.
    Comunque mi piace molto l’articolo, i miei complimenti

  24. Hello luke,

    How can I detect through pi camera?
    Can u help me with that?
    Hoping for faster response.

    Thanks in advance.

  25. Pingback: make videos by linux + PowerDirector | My work notes

Leave a Reply

Your email address will not be published. Required fields are marked *