In diesem Recipie schauen wir uns an wie eine OpenMV Camera mit einem eigenen Trainingsset ausgestattet werden kann. Wir trainieren die Cam für die Detektion eines Logos und schauen uns an wie dieses Training genutzt werden kann, um eine DSLR mit einem Objekt zu triggern. Die Hardware-Seite ist in diesem Beispiel sehr simpel dafür werden wir uns stärker mit dem Workflow der Datenaquisition, des Labelns, des Trainings in Edge Impulse und einer kleineren Anpassung unseres Codes in der IDE auseinandersetzen.
Prolog
Die OpenMV Cam (Open Machine Vision Camera) kommt bereits mit einigen großartigen Beispiel Algorithmen, die du recht simpel über die OpenMV IDE ansteuern und ausprobieren kannst. Im oben verlinkten Artikel findest du sämtliche Infos zu Hardware und Software wie auch die Videos zu einigen Beispielprogrammen.
Beispielfiles in der IDE
- eine Auflistung einiger Beispiele inklusive Demovideos findest du hier
eigenes Training
Wir wollen uns in diesem Recipie aber auf ein eigenes Training fokussieren. Das heisst einen Datensatz erstellen, ein Training basierend darauf durchführen und diese Eigenentwicklung in Betrieb nehmen, um eine DSLR-Kamera anzusteuern.
Vorbereitung
Um später unser trainiertes Modell zu deployen benötigen wir ein Machine Vision taugliches Board, wir nutzen hier die OpenMV Cam H7 Plus. Die Hardware ist absolut überschaubar das einzige wichtige Bauteil ist der Optokoppler.
Bill of Material
- OpenMV Cam H7 Plus
- 1 Optokoppler 4n25
- Protoshield
- ca 5cm Litze
- eine Microjack Buchse
- und Microjack Fotoapparat adapter
File Download: Code
Die Files für den Aufbau dieses Recipies findest du hier:
Finden eines zu detektierenden Objekts
Als Objekt kann dir fast alles dienen. Ideal ist in jedem Falle etwas, dass seine Form evt. auch die Farbe beibehält. Ich habe für dieses Beispiel das Logo von Camera Arts genommen. Es können aber auch andere Objekt genutzt werden, so zum Beispiel Früchte, Spielzeug, Flaschen, Pflanzen ect.
Software
OpenMV IDE
Du brauchst die IDE Von Open MV Cam:
Training eines eigenen Modells
Um ein Datensatz zu erstellen, nutzen wir die IDE und unsere OpenMV Cam. Die Software bietet bereits die Möglichkeit einen Datensatz zu erstellen. Öffne einen neuen Datensatz, indem du auf Extras > Datensatzeditor > Neuer Datensatz klickst. Du wirst nun aufgefordert einen Ordner zu definieren in welchem dein Datensatz angelegt wird.
In diesem Ordner wird nun ein das dataset_capture_script.py gespeichert und dieses Script öffnet sich auch direkt in der IDE:
Objektklassen
Eine neue Objektklasse muss für jedes Objekt, dass du mit deinem Detektor lokalisieren willst, erstellt werden. Um dies zu tun, klicke auf das Ordner Symbol mit dem Plus Zeichen dann wirst du aufgefordert einen Klasse zu benennen. Für jede Klasse wird nun im Zielordner einen Unterordner erstellt und ein Textfile mit allen Klassennamen erstellt.
Datenaquisation (fotografieren)
Jedes der Objekte wird nun idealerweise in unterschiedlichen Winkeln, Raum- und Lichtverhältnissen fotografiert. in der Regel reichen ca. 50 Bilder pro Objekt gut aus. Die Gewinnung von Daten erfolgt idealerweise direkt mit dem Gerät, auf welchem das Modell nachher genutzt wird in unserem Fall die OpenMV Cam. Falls du ein interessantes Datenpaket findest, dass bereits existiert, kann dies auch genutzt werden, wird aber tendenziell etwas in der Präzision einbüssen.
Wir wählen nun einen Klassenordner aus und machen Fotos von den Objekten, indem wir das Kamera/Fotosymbol drücken:
In meinem Beispiel habe ich natürlich nicht Bananen von Orangen unterschieden, sondern für jede Farbe des Logos einen neuen Ordner gemacht (ein Fehler wie sich nachher beim Training heraus gestellt hat) und alle Taschenfarben in verschiedenen Positionen fotografiert, 158 Bilder insgesamt:
Das Objekt ist mittig im Bild. Das Bild selbst ist 320 x 240 Pixel klein und selbst das wird danach im Training nochmals deutlich reduziert. Die Bilder werden im Prozess des Trainings der Regel quadratisch zugeschnitten (96 x 96 Pixel / 48 x 48 Pixel). Dein Objekt sollte also idealerweise gut erkennbar und nicht weit aussen am Rand des Bildes im folgenden Bild rot markiert sein:
Garbage in, Garbage out
Die Informatik- Faustregel sollte unbedingt berücksichtig werden. Sind in deinem Projekt deine Daten, das Labeln oder die Parameter schlecht, dann wird es sicherlich auch kein stabil laufendes Modell geben. Die Bilder deines Datensatzes sollte einigermassen gut ausgeleuchtet und die Objekte mehr oder weniger im Zentrum der Aufnahmen sein.
Edge Impulse
Edge Impulse ist eine Firma die Trainings kostenlos in der Cloud anbietet, das heisst du brauchst keinen superstarken PC, um deine eigenen Modelle zu trainieren. Registriere dich dort und du kannst loslegen.
Nach dem du dich registriert hast und ein neues Projekt eröffnet hast findest du dich auf folgender Oberfläche wieder:
Clicke erst auf Data acquisition, dann auf Add data:
Wähle deine Dateien über Choose Files aus und lade sie hoch:
Labeln
Nachdem du dein vorhin gesammeltes Datensatz hochgeladen hast, gehts ans labeln. Edge impulse unterteilt dein Datensatz später automatisch in einen Trainingsteil (~80%) und einen Validationsteil (~20%). Um ein Training zu machen, solltest du die Dateien Labeln. Das heisst wir markieren für das nachfolgende Training bei jedem Bild mit einem Rahmen, wo sich das Objekt auf dem Bild befindet und was sein Label ist. Dies kann ein sehr langer und mühsamer Prozess sein.
Clickwork
In unserem Fall ist das ein Miniatur Datensatz und das Labeln sollte in ca. einer Stunde gemacht sein aber für viele Clickworker:innen ein Job dem sie täglich nachgehen. Falls dich diese Seite der Grossen KI Modelle interessiert, ist evt. dieser Dokfilm interessant:
Labeling Queue
Nun zeichnest du mit der Maus um jedes Objekt in deinem Dataset ein Viereck und setzt das Label entsprechend. Achtung! Wenn du mehrere Objekte gleichzeitig trainierst, ist es wichtig konzentriert zu bleiben und nicht einfach durchzuklicken. Ein schlecht gelabelter Datensatz kann massgeblich für den Erfolg oder das Scheitern deines Trainings entschieden (GIGO).
Create Impulse
Nachdem du alles gelabelt hast, kannst du nun der eigentliche Training beginnen. Eine Trainingseinheit wird in Edge Impulse als Impulse benannt. Du klickst auf «Impulse Design» und dann auf «Create Impulse» um die Trainings – Parameter zu setzen. Setze deine Parameter wie folgt ein:
Nach dem Speichern klickst du auf Impulse Design und dann auf Image. Hier klickst du dann auf den Button «Generate Features». Dieser Prozess sucht nun in deinem Bildersatz nach Features und zeigt dir die Features danach grafisch in clustern geordnet. Wenn alles gut verlief sieht es in etwa so aus:
Mit mehreren Objekten in etwa so:
Dies ist ein wichtiger Schritt, um dein Datensatz zu überprüfen. je näher sich die Featurecluster zusammenballen, desto höher die «treffsicherheit» ein Feature zu erkennen. Wir haben in unserem Beispiel nur ein Objekt: alle CA-Logos in unterschiedlichen Farben, daher ist dies vielleicht nicht das beste Beispiel. Hast du mehrere Features, die erkannt werden sollen, sollte sich jedes Feature zu einem Cluster formen, falls das ganze sehr zerstreut, aussieht wird dir das trainierte Modell keine zuverlässige Detektion liefern können. So ist dies auch in meinem ersten Anlauf geschehen…
Retraining: Datensatz erweitern oder umlabeln
In meinem Fall hatte ich die erste Idee in meinem Datensatz unterschiedliche Logos & Farben zu detektieren: Ich habe Labels für Lila, White, Orange, Green und Yellow erarbeitet. Leider hat sich bereits bei der Stufe der Feature Generation gezeigt, dass die Features nicht Clustern, sondern ziemlich Homogen verstreut sind, was nach dem Training zu einer schlechten Validation und einem schlechten Modell führte:
In meinem Fall der unterschiedlichen Logofarben musste nun also ein anderer Lösungsansatz her. Es boten sich mehrere Möglichkeiten, dies zu verbessern:
- Den Datensatz pro Objekt (in diesem Fall Logo-Farbe) vergrössern ca. 50 – 70 Bilder pro Logofarbe
- Den Datensatz als ein Objekt behandeln und alle Logos neu Labeln.
Ich habe mich in diesem Fall für Option 2 entschieden. Nun weisst du auch, weshalb die Datei auf Github diesen doofen Namen hat. (2ndTry)
Start Training und Validation deines Modells
Wenn des Clusters einigermassen Vielversprechend aussehen können wir das eigentliche Training starten.
In unserem Fall nutzen wir
- 70 Lernzyklen
- 0.0001 Lernrate
- Data Augmentation checked
- FOMO (Faster Objects, More Objects) MobileNetV2 0.35
Danach startest du das Training…
Nach dem Trainingsprozess wird dein Modell mit dem Validations Datensatz überprüft. Und diese Überprüfungswerte kannst du danach einsehen. Um die Detektionswerte deines Modells zu überprüfen kannst du unter Impulsedesign > Object Detection die Validationswerte abrufen. In der Regel, ist ein Wert von um die 80% – 90% schon ganz OK. Im Falle, dass du an einem Selbstfahrenden Auto arbeitest, würde ich aber sicherlich nochmals etwas Zeit ins Optimieren investieren.
In meinem Beispiel des mehrfarbig gelabelten Datensatzes waren die Detektionswerte wie zu erwarten die Labels: Grün, Lila und Gelb sie wurden nur schlecht erkannt und hatten schlechte Werte:
Im Falle des 2nd Try Logodetektors mit nur einem Label hingegen ziemlich hoch:
Training und Validation geglückt? Deploy It!
Um das trainierte Modell für unsere Kamera nutzbar zu machen, müssen wir nun dieses Model deployen, das mach wir unter Deploy… Hier suchen wir nach unserem Endgerät. Tippe in der Suchleiste «open» ein und du bekommst zwei Vorschläge:
Beides wäre lauffähig auf unserer OpenMV Cam aber wir brauchen die Library Option, da wir noch ein wenig an unserem Code weiterarbeiten wollen. Klicke auf Build und du kriegst dein eigenes Modell in deinen Downloads Ordner geladen.
Hardware
Wenn Du`s bis hier hin geschafft hast, Gratuliere – du hast dein erstes KI Modell trainiert! Dieses können wir nun auf unserer OpenMV Cam nutzen! Nochmals zur Erinnerung: hier sind alle Infos zur Cam.
Modell auf der Cam zum Installieren
Das Modell kann gestartet werden indem du:
- die beiden Files (trained.tflite + labels.txt) auf den internen Speicher deiner Cam ziehst, Schliesse dazu deine Cam per USB an deinem Computer an und verschiebe diese Files auf die Cam.
- das Pythonscript «ei_object_detection_shutter_LED.py» in der OpenMV IDE öffnest.
- die OpenMV IDE startest die Cam verbindest und das Script mit dem Playknopf startest.
Sieht deine Kamera das Objekt und detektiert es zeichnet sie einen kleinen Kreis auf das entsprechende Objekt im Vorschaubild.
Kamera steuert Kamera
Da die Software nun läuft ist die Frage was wollen wir damit tun? Ich habe die in diesem Beispiel vor eine Kamera automatisch anzusteuern. Um den Auslöser einer DSLR-Kamera zu aktivieren so bald ein Logo sichtbar wird. Hierzu nutzen wir die Möglichkeit, die uns die Fernauslöserbuchse einer Kamera bietet. In den meisten Fällen muss man nur die richtigen Verbindungen kurzschliessen und damit ein Foto. Wir nutzen hier eine Nikon D800 das gleiche Prinzip funktioniert auch mit einer Fujifilm XT2 wie theoretisch mit vielen anderen Kameras, die einen Kabelgebundenen Fernauslöser haben.
Um bei unserer Kamera die Fotos auszulösen, nutzen wir einen der Pins an der Cam. Jedes Mal, wenn ein Objekt detektiert wird wird der Pin aktiviert und lässt 3.3V auf den Optokoppler «fliessen» und schaltet das onboard LED an.
Hierzu haben wir folgende kleine Funktion geschrieben:
# Camera Shutter Function def shutter(): global timer timer = now print("Auslöser") led.on() p.high() time.sleep(1) led.off() p.low()
Wenn du das Programm «ei_object_detection_LED.py» in der IDE startest, dann blinkt ein Blaues LED bei jeder Detektion und der Shutter der DSLR-Kamera wird ausgelöst. Um dies in der realen Welt zu machen, müssen wir aber noch etwas Kleines zusammenlöten und es mit der Kamera verbinden.
Wir werden unser Signal auf einen Optokoppler geben. Dieses Bauteil trennt die eine Kamera Galvanisch von der anderen. Das heisst es sind zwei unabhängige Stromkreise. Dies machen wir, um Schäden an der DSLR-Kamera zu verhindern.
Achtung 3.3V Logik
Nur als kleiner Hinweis: manche Optokoppler funktionieren mit niedrigstrom bereits bestens, andere brauchen 5-6V. Der Test bei uns haben ergeben, dass der 3.3V Ausgang der Pins bei folgenden Optokopplern gut funktionert:
- 4N25
- PC817 (sharp)
Um zu verstehen, wie wir die DSLR-Kamera ansteuern können…
Aufbau
Sobald du alles zusammengelötet hast, sollte es in etwa so aussehen:
Wenns KLICK macht hast du alles richtig gemacht!