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à.
Mi 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)