OpenCV übernimmt die Gesichtserkennung
Dass die Gesichtserkennung in einem eigenen Thread läuft, hat einen einfachen Grund: Sie ist rechenzeitintensiv, die angelieferten Bilder der Kamera werden gepuffert. Liefe das Holen des Bildes und dessen Auswertung im gleichen Thread, würden wir beim nächsten Schleifendurchgang ein Bild unbekannten Alters aus dem Puffer erhalten. Mit capture.grab() leeren wir stets den Puffer und sorgen dafür, dass im Thread mit capture.retrieve() immer nur das aktuelle Bild ausgewertet wird:
void *faceThread(void *arg) { Mat img; while(1) { if(capture.retrieve(img)) { checkFace(img); } } }
Die eigentliche Erkennung läuft in der Funktion checkFace(). Diese Funktion sah ursprünglich so aus:
void checkFace(Mat img) { ... cvtColor(img, gray, CV_BGR2GRAY); equalizeHist( gray, gray); face_cascade.detectMultiScale(small, faces, 1.1, 2, CV_HAAR_SCALE_IMAGE); if(faces.size() > 0) { int p = faces[0].x + (faces[0].width/2); int pd = map_pixel_to_deg(p); servo(180 - pd); } }
Das Kamerabild wird in ein Graustufenbild umgewandelt, die Farbverteilung im Bild normalisiert und schließlich auf Gesichter geprüft. Die detectMultiScale()-Methode liefert für jedes gefundene Gesicht ein Rect-Objekt zurück. Es enthält die xy-Koordination eines Rechtecks sowie dessen Höhe und Breite. Jedes Rechteck beschreibt also, wo im Bild ein Gesicht gefunden wurde. Wir ermitteln auf Basis dieser Daten dann die x-Koordinate der Mitte des Rechtecks. Sie wird in eine Grad-Angabe (0 - 180 Grad) umgerechnet und der Funktion servo() zur Ansteuerung des Servos übergeben.
Oder nutzen Sie das Golem-pur-Angebot
und lesen Golem.de
- ohne Werbung
- mit ausgeschaltetem Javascript
- mit RSS-Volltext-Feed
Programmieren in C++ und mit MRAA | Der Edison beeindruckt |
Na ja - das Edison/Arduino Gespann ist nun so viel kleiner nicht. Das reine Edison Modul...
und vom USB-Stick? Von SD wäre natürlich genial und vielleicht besser Intel hier ja noch...
Irgendwie ist die Betonung des Sprechers im Video ... hmm, naja, seltsam. *Sehr* seltsam...