Bildbasierte Detektion eines Garagentores (Teil 2 – Cognitive Services)

Einleitung

Dies ist der zweite Blog-Post zur bildbasierten Detektion eines Garagentores. Im Ersten Teil befassten wir uns mit der Datenakquise. Dazu nutzten wir einen Raspberry Pi mit angeschlossener PiCamera um in regelmäßigen Abständen Bilder unseres Garagentores aufzunehmen. Die Bilder übertrugen wir an einen Web-Service der sie im Azure Blob Storage speicherte und einen passenden Eintrag im Azure DocumentDB ablegte.

Dieser Artikel befasst sich nun mit der Suche nach einem geeigneten Verfahren, um anhand eines Eingabebildes zu erkennen, ob das Garagentor offen oder geschlossen ist. Dazu müssen wir für die aufgenommenen Bilder aber zunächst festhalten, ob das abgebildete Garagentor offen oder geschlossen ist. Später wollen wir die so gelabelten Bilder nutzen, um unseren Klassifikator zu trainieren und zu evaluieren.

Um uns die Arbeit zu erleichtern haben wir eine kleine WPF-Anwendung geschrieben, die wir im folgenden Kapitel kurz vorstellen wollen.

Labeling-Anwendung

Figure 1: Die Labeling-Anwendung.

Die Anwendung, die wir zum Labeln der Trainingsdaten erstellt haben, ist in Figure 1 dargestellt. Die Liste auf der linken Seite zeigt alle vorhandenen Einträge aus Azure DocumentDB. Rechts wird dann das zum
selektierten Eintrag passende Bild angezeigt. Über Tastenkürzel lässt sich der Status ändern oder ein Eintrag löschen wenn wir der Ansicht sind, dass das aufgenommene Bild nicht verwendet werden kann.

Implementierung

Die Implementierung erfolgte in C#. Zunächst rufen wir sämtliche Dateien aus Azure DocumentDB ab und erstellen damit eine Liste, die auf der linken Seite von Figure 1 zu sehen ist.

Wird ein Eintrag selektiert, zeigen wir das dazugehörige Bild auf der rechten Seite an. Dazu bedienen wir uns eines kleinen Tricks, um uns die Arbeit zu erleichtern. Die URL zum Bild unterscheidet sich für einen bestimmten Tag nur im selektierten Namen. Daher ersetzen wir diesen einfach:

Ändert sich der Tag an dem die Labeling Anwendung genutzt wird, unterscheidet sich auch die URL grundlegend, sodass dieser Trick nicht mehr funktioniert. Da wir das Labeling allerdings an einem Abend durchführen konnten, waren wir von dieser Einschränkung nicht betroffen 1.

Cognitive Services

Als ersten Versuch nutzten wir die Maschinelles Sehen-API von Azure Cognitive Services AzureCognitiveAzureCV. Dabei handelt es sich um eine von Microsoft zur Verfügung gestellte API, die zur Bildanalyse verwendet werden kann. Die API bietet verschiedenen Endpunkte. Aktuell sind das Requests für eines der folgenden Ergebnisse aus einem Eingabebild:

  • Beschreibung
  • Tags
  • Analyse
  • Texterkennung
  • Thumbnail-Erstellung

Eine Beschreibung der einzelnen Requests kann unter AzureCognitiveAPI gefunden werden.

Für einen ersten Test kann aber auch die Demo-Seite oder die Beispiel-Anwendung genutzt werden. Letztere setzt allerdings eine Azure-Subscription voraus, da ein Subscription Key benötigt wird. Zusätzlich
muss die Anwendung zunächst kompiliert werden.

Die Cognitive Services sind ein fertiges Paket. Es ist nicht möglich, sie speziell für unseren Anwendungsfall zu trainieren. Wir müssen daher mit dem von Microsoft eingelernten Modell zurecht kommen. Allerdings liefert die Analyse viele Informationen zu einem Eingabebild, insbesondere die in der Antwort enthaltenen Tags erwiesen sich als sehr hilfreich.

Um zu testen, ob wir die Cognitive Services verwenden können, nutzten wir die oben erwähnte Beispiel-Anwendung. Damit ließen wir zwei Bilder analysieren, einmal mit offenem, einmal mit geschlossenem Tor. Die folgenden beiden Listings (offenes_Tor, geschlossenes_Tor) enthalten die Ergebnisse:

Auch wenn die Beschreibung in beiden Fällen falsch ist, sehen die Tags in diesem Versuch vielversprechend aus. So scheint die API bei geschlossenem Tor zu erkennen, dass wir uns in einem geschlossenem Raum befinden (Das Tag „indoor“ legt diese Vermutung nahe). Basierend auf dieser Vermutung haben wir eine Evaluation geschrieben um unsere Annahme zu bestätigen. Das folgende Kapitel stellt die zur Evaluation erstellte Anwendung und die Ergebnisse vor.

Evaluation der Cognitive Services API

Für die Evaluation haben wir zunächst eine Konsolenanwendung geschrieben die nichts weiter tut, als all unsere gelabelten Bilder nacheinander an die Cognitive Services API zu übermitteln und das Analyse-Ergebnis zunächst in einer Liste zu speichern. Nach dem Durchlauf wird die Liste gespeichert. Die Auswertung der so gespeicherten Ergebnisse haben wir anschließend mit LinqPad (LINQPad) durchgeführt.

Zunächst erstellten wir die nötigen Clients um Zugriff zu DocumentDB, BlobStorage und Cognitive Services API zu erhalten:

Wie die Clients für DocumentDB und BlobStorage zu erstellen sind haben wir der jeweiligen Dokumentation (AzureDocumentDBGettingStartedAzureBlobStorageGettingStarted) entnommen.
Für die Cognitve Services haben wir uns an der bereits erwähnten Beispiel-Anwendung orientiert.

Nachdem die Clients erstellt waren konnten wir mit der Evaluation beginnen:

Zunächst holten wir die Dateien und Bilder vom DocumentDB, bzw. BlobStorage. Anschließend suchten wir zu jeder Datei das zugehörige Bild und ließen es vom VisionServiceClient analysieren. Das Ergebnis speicherten wir, zusammen mit der Datei und der vom VisionServiceClient benötigten Zeit zur Analyse, in einer Liste. Zu beachten ist, dass die gemessene Zeit ausschließlich die vom VisionServiceClient benötigte Zeit zur Analyse umfasst. Das Abrufen des Bildes aus dem BlobStorage sowie die Erstellung des EvaluationResult sind nicht in der Zeitmessung enthalten.

Mit LINQPad haben wir anschließend eine Konfusionsmatrix aus der gespeicherten Analyse generiert:

Vorhersage: OffenVorhersage:GeschlossenRecall
Offen122100.92424242
Geschlossen372120.85140562
Precision0.767295600.95495495

Dabei sind wir davon ausgegangen, dass das Tor geschlossen ist, wenn das Tag „indoor“ vorhanden ist und die Confidence über 85% liegt. Die Genauigkeit lag mit dieser Annahme bei 87,7%. Des weiteren erhielten wir eine mittlere Precision von ca 85% und einen mittleren Recall von ca. 89%.

Insgesamt benötigte ein Durchlauf knapp 31,5 Minuten. Im Mittel wurden für die Analyse eines Bildes 4,96 Sekunden benötigt.

Azure Machine Learning

Nach dem recht erfolgreichen Test der Cognitive Services wollten wir uns den verschiedenen Machine Learning Algorithmen von AzureML widmen. Leider stellte sich heraus, dass Azure Machine Learning noch keine Bilder verarbeiten kann. Davon waren wir sehr überrascht, da bereits auf OpenCV basierende Möglichkeiten der Bildverarbeitung in Azure enthalten sind (siehe AzureMLOpenCV). In den folgenden Absätzen möchten wir dennoch unsere Herangehensweise erläutern.

Zunächst wollten wir mit Hilfe des „Import Images Module“ (AzureMLImportImages) unsere Bilder aus dem BlobStorage laden. Dieser Versuch scheiterte jedoch, trotz korrekter Credentials, bereits an der
Authentifizierung am BlobStorage. Auch der Support wusste keinen Rat. Somit blieb uns nichts anderes übrig als die Bilder über ein Python-Script zu importieren.

Azure Machine Learning kann selbst geschriebene Python– oder R-Skripte ausführen (AzureMLExecutePythonScript,AzureMLExecuteRScript). Bei beiden Modulen ist es zusätzlich möglich, „Script Bundles“ anzuhängen um weitere, nicht in Azure Machine Learning enthaltene, APIs benutzen zu können (Figure 2).

Figure 2: Genutzte Module für Azure Machine Learning

Wir nutzten diese Möglichkeit, um in unserem „Execute Python Script“ Modul den BlockBlobService nutzen zu können. Damit konnten wir die Bilder durch folgenden Aufruf laden:

Die so erhaltenen Bilder wollten wir mit Hilfe von OpenCV (OpenCV) in verschiedene Farbräume zerlegen und mit den so erhaltenen Daten die verschiedenen Machine Learnung Algorithmen testen. Zu diesem Zweck ergänzten wir unser Script Bundle um OpenCV. Leider erhielten wir dennoch die Fehlermeldung, dass das Modul cv2 nicht importiert werden konnte.

Unsere Recherche ergab, dass OpenCV in Python Script Modulen nicht nutzbar ist, da cv2 von der C-Implementierung von OpenCV abhängt und diese nicht in das Modul integriert werden kann.

Das ist sehr schade, zumal OpenCV ja enthalten ist und in den vorgefertigten Modulen durchaus auch verwendet wird. Die Nutzung in eigenen Scripten ist jedoch nicht möglich, was für uns verwirrend und nicht nachvollziehbar ist. Diesem Umstand widmet sich auch eine User-Voice in der der Autor darum bittet, OpenCV auch in Python Skripten verwenden zu können.

Es gäbe mit Sicherheit noch weitere Möglichkeiten, um die Bilddaten auszulesen und zu verarbeiten. Dazu wäre allerdings erheblich mehr Aufwand nötig. Aus diesem Grund stellten wir unsere Versuche an dieser Stelle ein.

Zusammenfassung

Dieser Artikel befasste sich mit der Suche nach einem geeigneten Klassifikator. Nach dem Labeln der Bilddaten, die wir im ersten Blog-Post generiert haben, nutzten wir die Cognitive Services zur Detektion. Ein anschließender Test von Azure Machine Learning blieb leider erfolglos oder wäre nur mit erheblich größerem Aufwand durchführbar gewesen.

Bibliography

Fußnoten:

1

Der korrekte Ablauf zum Abrufen der Blobs ist in Kapitel Evaluation beschrieben.