26.02.2014 Aufrufe

smart developer Ein Code für alle (Vorschau)

Sie wollen auch ein ePaper? Erhöhen Sie die Reichweite Ihrer Titel.

YUMPU macht aus Druck-PDFs automatisch weboptimierte ePaper, die Google liebt.

Entwicklung<br />

Bada: Face Recognition App<br />

über die Liste von Dateipfaden. Zur Decodierung<br />

einer Bilddatei benötigen Sie zunächst<br />

eine Image-Instanz. Legen Sie die Image-Instanz<br />

an und rufen Sie Construct() und<br />

DecodeN() auf dieser Instanz auf. DecodeN()<br />

übergeben Sie den Dateipfad und das Format,<br />

in das die Datei codiert werden soll. Das<br />

gewählte Format muss eines der vom Face-<br />

Recognizer unterstützten Formate sein.<br />

Nun rufen Sie auf der zu Beginn von Run()<br />

angelegten FaceRecognizer-Instanz Extract‐<br />

FaceInfoFromStillImageN() auf und übergeben<br />

die von DecodeN() erzeugte Bitmap.<br />

ExtractFaceInfoFromStillImageN() führt die<br />

Gesichtserkennung durch und liefert im Erfolgsfall<br />

eine Liste mit FaceRecognitionInfo-<br />

Instanzen zurück (Listing 4). Erweitern Sie<br />

den Listener um die Methode OnFinishedAnalyzingFile(),<br />

die als Parameter den Index des<br />

Bildes in der Liste, die Länge der Liste und die<br />

Anzahl der gefundenen Gesichter übernimmt.<br />

Um der UI das Ergebnis mitzuteilen, rufen Sie<br />

die Methode auf dem Listener auf.<br />

Um die gefundenen Gesichter später wieder<br />

der Bilddatei zuordnen zu können, implementieren<br />

Sie die Hilfsklasse MyFaceInfo<br />

mit einem Zeiger auf eine FaceRecognition‐<br />

Info-Instanz und auf einen String als Attribut.<br />

Für jede FaceRecognitionInfo-Instanz<br />

erzeugen Sie eine MyFaceInfo-Instanz, speichern<br />

die FaceRecognitionInfo und den dazugehörigen<br />

Dateinamen darin ab und hängen<br />

die MyFaceInfo-Instanz an die ArrayList.<br />

Der Listener erhält die Methode OnFinished‐<br />

AnalyzingFiles(), um der UI die Summe der<br />

gefundenen Gesichter mitzuteilen.<br />

Resultate vergleichen<br />

In der vierten Phase des Threads vergleicht<br />

die App die gefundenen Gesichter miteinander.<br />

<strong>Ein</strong>e Schleife durchläuft dazu die Liste<br />

mit MyFaceInfo-Instanzen. Für jede Instanz<br />

aus der Liste durchläuft die App eine weitere,<br />

innere Schleife, in der die MyFaceInfo-Instanz<br />

mit <strong>alle</strong>n folgenden MyFaceInfo-Instanzen der<br />

Liste verglichen werden.<br />

Die Methode MeasureSimilarity() gibt<br />

einen Wert zwischen 0 und 100 und IsMatching()<br />

einen boolschen Wert zurück. Die<br />

Rückgabewerte schreiben Sie mit AppLogDebug()<br />

in die Output-View. Listing 5 zeigt, wie<br />

der Vergleich stattfindet. Für die Ausgabe auf<br />

der UI erweitern Sie den Listener um die Methode<br />

OnFoundMostSimilarFaces(), die einen<br />

Zeiger auf die beiden MyFaceInfo-Instanzen<br />

übernimmt.<br />

Ergibt ein Vergleich zweier Gesichter eine<br />

höhere Ähnlichkeit als <strong>alle</strong> vorhergehenden<br />

Vergleiche, dann speichert die App den Wert<br />

und die Indizes auf die MyFaceInfo-Instanzen<br />

innerhalb der Schleife in Variablen und<br />

informiert den Listener mit dem Aufruf von<br />

OnFoundMostSimilarFaces() über das Ereignis.<br />

Um die UI über das Ende des Vergleiches<br />

zu informieren, erweitern Sie den Listener<br />

um eine letzte Methode. OnFinishedComparingFaces()<br />

und rufen die Methode auf den<br />

Listener auf. Damit endet die Methode Run()<br />

und der Thread terminiert.<br />

Damit ist die Implementierung des Threads<br />

und seiner Kommunikationsschnittstelle,<br />

dem Listener, abgeschlossen und Sie können<br />

mit der Implementierung der UI beginnen.<br />

Die grafische Oberfläche<br />

Die GUI besteht aus der Klasse Form1, die<br />

von Osp::Ui::Controls::Form und RecognizerThreadListener<br />

erbt. Zunächst definieren<br />

Listing 3: Der Listener im Detail<br />

class RecognizerThreadListener {<br />

public:<br />

virtual void OnFinishedGrabbingFiles(int numberOfFiles) = 0;<br />

virtual void OnFinishedAnalyzingFile(int index, int total, int numberOfFaces)<br />

= 0;<br />

virtual void OnFinishedAnalyzingFiles(int numberOfFaces) = 0;<br />

virtual void OnFinishedComparingFace(int index, int total, int maxSimilarity)<br />

= 0;<br />

virtual void OnFoundMostSimilarFaces(MyFaceInfo *pCurrentMyFaceInfo,<br />

MyFaceInfo *pOtherMyFaceInfo) = 0;<br />

virtual void OnFinishedComparingFaces(int similarity) = 0;<br />

};<br />

Listing 4: Die Gesichtserkennung<br />

// Bild dekodieren<br />

Image *image = new Image();<br />

image‐>Construct();<br />

Bitmap* pBitmap = image‐>DecodeN(*pFilename, BITMAP_PIXEL_FORMAT_ARGB8888);<br />

delete image, image = null;<br />

result r = GetLastResult();<br />

if (IsFailed(r)) {<br />

AppLogDebug("failed decoding image %ls", pFilename‐>GetPointer());<br />

return null;<br />

}<br />

// Gesichter aus dem Bild extrahieren<br />

IList *pFaces = null;<br />

pFaces = faceRecognizer.ExtractFaceInfoFromStillImageN(*pBitmap);<br />

r = GetLastResult();<br />

if (IsFailed(r)) {<br />

delete image, image = null;<br />

AppLogDebug("failed decoding image %ls", pFilename‐>GetPointer());<br />

continue;<br />

}<br />

<strong>smart</strong>-<strong>developer</strong>.de 02/2011 69

Hurra! Ihre Datei wurde hochgeladen und ist bereit für die Veröffentlichung.

Erfolgreich gespeichert!

Leider ist etwas schief gelaufen!