Kinect sychron mit OpenCV als Qt Thread – endlich

 Nach vielen Versuchen in der noch frischen Kinect-Welt ist nun endlich ein lauffähiger erster Wurf heraus gekommen. Aber erst noch ein paar Worte zur Vorgeschichte und als Erfahrungsbericht, falls noch jemand in diese Probleme Herausforderungen läuft.

Begonnen wurde mit der Nutzung von openFrameworks, da es hierzu ein komplexes Beispiel gab, welches auf Anhieb das Bild der Kinect (RGB und Tiefenbild) anzeigt und zusätzlich sogar eine 3D-Punktwolke und auch schon per OpenCV Hindernisse als Blobs darstellt. Vorteil dieser Lösung ist, dass sie unter Mac OS X und unter Linux einwandfrei lief. Nachteil lag (für mich) darin, dass es ein recht komplexes oder besser gesagt sehr vielfältiges Framework ist, welches zusätzlich auf diverse eigene Bibliotheken und zig eigene Datentypen zurückgreift – Nicht gerade der einfachste Einstieg, wenn man ansonsten nicht auf diesem Framework aaufbaut.

Eine weitere Herausforderung war, dass das Ganze in die "Qt-Welt" von direcs eingebettet werden muss, also z.B. mit den genialen Qt-eigenen Mitteln für Events und Eventhandler (sogenannte Signals und Slots). Hierzu gab es dann weitere Experimente, die dann auch mit dem Qt Framework ganz gut zusammen liefen. Hier gab es dann die Schwierigkeit (für mich), dass das Bild mittels OpenGL angezeigt wurde. Da aber ja der Bildinhalt später mit OpenCV weiter verarbeitet werden sollte, gestaltete sich dieses als schwierig.

Um OpenCV erst einmal weitere Erfahrungen zu sammeln, wurde das Buch Learning OpenCV (ISBN 978-0-596-51613-0) von Gary Bradski & Adrain Kaehler aus dem berühmten O’REILLY-Verlag beschafft. Für 50 EUR nicht gerade ein Schnäppchen; ein Fachbuch eben. Das Buch gefällt; leider basiert es auf der alten OpenCV Version 2.0. Seit Dezember 2010 ist Version 2.2 aktuell, bei der es so einige Änderungen gab – insbesondere haben sich die Bibliotheksnamen geändert und es wird offenbar nun viel der Datentyp Mat statt IplImage verwendet, was beim Verständnis bzw. beim Umsetzen von Code-Beispielen, die man im Netz aktuell hat (mir) oft noch schwer fällt. Erste Erfolge wurden daraufhin wie hier beschrieben dann auch zusammen mit Qt und OpenCV erzielt – hier aber noch mit der im iMac verbauten Kamera, nicht mit der Kinect. 

Nun galt es per libfreenect / OpenKinect an das Kamerabild der Kinect zu kommen, das ganze als Qt Thread laufen zu lassen und per OpenCV weiter zu verarbeiten. Und – tadaa – hier es das Ergebnis:

 

 

Und nach vielen Stunden Anpassen, Programmieren und Verstehen kam dann auch das Tiefenbild hinzu: 

 

Hier noch einmal mit Roboter und Laserscanner im vollen Betrieb:

  

Im Gegensatz zu den meisten Beispielen im Netz wird hier übrigens das synchronous Interface / Wrapper genutzt! Verwendet wurde Qt 4.7.1 und OpenCV 2.2.0 – beides installiert unter Mac OS X via MacPorts. Der Sourcecode ist wie immer bei im online Repository bei github als Open Source verfügbar (camThread.h und camThread.cpp). Viel Spaß. Fragen? Kommentare? Gerne.

Kinect Live-Bild in vorhandene Roboter GUI integriert

 Die Integration des Kinect-Bildes geht voran. Sowohl das Live-Bild, als auch das "Tiefenbild" wird nun in der GUI angezeigt. Und hier die ersten Tests:

  

Wie man sieht, ist auf dem ersten Bild eine leicht geöffnete Tür (zum Flur) erkennbar – sowohl auf dem "original" Livebild der Kamera, als auch an den grünen Laserlinien und im Tiefenbild der Kinect; erkennbar am blauen Bereich. Im zweiten Bild sieht man die geöffnete Tür. Auf dem dritten ist sowohl auf dem Kamerabild also auch bei den Laserlinien eine Person gut erkennbar.

Weitere Fortschritte mit der Microsoft Kinect – Erste erfolgreiche Nutzung mit Qt!

 Ein erster eigener Erfolg wurde beim Ansteuern der Kinect erzielt: Vollständige Integration in ein eigenes eigenständiges Qt-Programm. Zugrunde liegend der Open Source Treiber / die Library OpenKinect. Des weiteren sollte der Wrapper für das Qt Framework, welches von mir genutzt wird, verwendet werden, dieser aber brach aber mit Compiler-Fehlermeldungen ab. Statt dessen wurde auf OpenKinect and Qt reference von Jon Macey zurück gegriffen, welches genau so einen Wrapper zur Verfügung stellt. Und so sieht das ganze dann in der per Qt-Designer erstellten GUI aus:

Der Sourcecode ist wie immer hier verfügbar. Der direkte Link zum eigenständigen Kinect-Testprogramm ist dann dieser. Das Original von Jon Macey wurde des weiteren dahingehend erweitert, dass es z.B. bei nicht angeschlossener Kinect das Programm nicht per EXIT beendet, sondern eine von außen abfragbare Variable abgefragt werden kann, ob die Kamera erkannt wurde oder eben nicht.

Zwischenschritt: Analyse von Motorverhalten

 Beim Umstellen der seriellen Funktionen auf ASCII-Klartext-Anweisungen anstatt binärer Daten, stellte sich heraus, dass die Motoren nicht immer gleich auf die selben Anweisungen reagierten. Um sicher zu gehen, dass es kein Hardwarefehler ist – und weil ein Programmfehler nicht feststellbar war – wurde kurzerhand ein kleiner Analysestecker gebaut und alle Verbindungen insgesamt aufgetrennt um jedes elektrische Modul für sich sauber zu testen. Und so sah der Test dann aus:

  

Wie mah sieht zeigt die grüne LED den Zustand des betreffenden Portbits des Atmel an. Zum einfacheren Testen wurden einfach ein paar LEDs mit je einem 1,5 k Ohm Vorwiderstand gegen Masse auf den betreffenden Pfostenverbinder gelötet:

  

Das funktionierte offenbar wie gewünscht. Anschließend wurden umgekehrt die Eingänge der Motorcontrol-Boards jeweils per Drahtbrücken auf high gesetzt um zu sehen, ob die Motorcontrol-Boards beide ordentlich funktionieren. Das Wichtigste dabei: Eine ordentliche und aufgeräumte Testumgebung! 

  

Spaß beiseite. Hintergrund dieser wilden Verkabelung ist natürlich, dass das Board "vor Ort" also in der Originalumgebung "im Roboter" getestet werden soll, also mit der gleichen Spannungsversorgung etc. Also wurde die Platinen nur soweit gelöst, dass man an die betreffenden Stecker ordentlich ran kommt und etwas unter die Platinen gelegt, damit es keine Kurzschlüsse gibt.

Nun wurden endlich auch die letzten Stecker und Kabel bei der Gelegenheit beschriftet – wo sowieso schon mal alles auseinander gebaut war:

    

Ergebnis: Interessanterweise wurde kein Fehler gefunden und nach dem Zusammenbau funktionierte alles wie gewünscht – ohne was geändert zu haben. Irgendwie seltsam… 

Erste Tests mit der Microsoft Kinect und OpenKinect / libfreenect

 Wie aus dem letzten Post vielleicht für den einen oder anderen zu erkennen, handelt es sich bei dem selbst gemachten Weihnachtsgeschenk um die Microsoft Kinect, die gerade vielfältig von sich reden macht. Denn eine Art 3D-Sensor in dieser Preisklasse schien vorher nicht recht möglich. Seit ein paar Tagen werden die gehackten und mittlerweile als Open Source verfügbaren Treiber, Libraries und Sourcecodes untersucht und ein wenig damit experimentiert. Hier die ersten Eindrücke:

      

Und hier das erste Erfolgserlebnis im etwas angepassten Sourcecode:

Wie man an der markierten Stelle sieht, wird hier schon ganz gut ein mögliches "Hindernis" für den Roboter angezeigt. Auf dem Live-Bild der Kamera rechts oben im Bild ist ein "Klavier-Hocker" zu erkennen. Der Sourcecode wurde so angepasst bzw. beim Programmstart so eingestellt, dass im Fenster links unten nur Objekte (Hindernisse) ab einer bestimmten Entfernung markiert (umrahmt) werden. Das Programm zeigt das größte Hindernis an, erkennt nun deren Mittelpunkt innerhalb des Bilders (X/Y-Koordinaten) und zeigt auch den Abstand des Objektes an. Und das beste: Das läuft soweit bereits unter Mac OS und unter Linux.

Genutzt wurde dazu der als Open Source verfügbare Treiber / die Library OpenKinect. Ergänzt um openFrameworks und ofxKinect. Vorteil dieser Lösung ist, dass sie unter Windows, Linux und Mac OS läuft. Ein Nachteil dieser Lösung könnte sein: Es gibt zwar einen Wrapper für das Qt Framework, welches von mir genutzt wird, aber da fehlen sämtliche OpenCV Elemente, die bei der openFrameworks Lösung alle schön beinhaltet sind. Da ist also noch etwas Analyse erforderlich, wie das ganze zusammenzubringen ist. :-) Es wird nicht langweilig…