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