Die Microsoft Kinect ist eine Kamera, welche für die Spielkonsole Xbox entwickelt wurde. Das Besondere an dieser Kamera ist ihre Möglichkeit, neben einem normalen RGB Bild, ein Tiefenbild ihrer Umgebung zurückzugeben. Damit wird es möglich komplexere Computer Vision Aufgaben zu implementieren. Darüber hinaus bietet das sog. Microsoft Kinect SDK die Möglichkeit das Skelett einer Person zu erkennen. Durch das "Skeleton-Tracking" ist es möglich festzustellen, wo die Gelenke einer Person sind und welche Gesten und Bewegungen sie ausführt. Leider ist dieses SDK nur für Windows erhältlich und wir arbeiten daher vor allem mit dem Tiefenbild der Kinect Kamera.
Mittlerweile gibt es zwei Versionen der Kinect Kamera: Kinect v1 und Kinect v2. Der wesentliche Unterschied besteht in der Auflösung und der Geschwindigkeit mit welcher die Kameras arbeiten. Hier ein kurzer Vergleich der Spezifikationen:
Version | Kinect v1 | Kinect v2 |
---|---|---|
Auflösung RGB | 640x480 | 1920x1080 |
Framerate | 30fps | 30fps |
Auflösung Tiefenbild | 320x240 | 512x424 |
Entfernung Auflösung | 2048 | 4500 |
Maximale Distanz | ca. 450cm | ca. 450cm |
Minimale Distanz | ca. 40cm | ca.50 cm |
USB Interface | USB 2.0 | USB 3.0 |
Generell ist also vor allem die Auflösung des RGB Bildes und des Tiefenbilds mit der Version 2 verbessert worden. Ein weiterer kleiner Vorteil der v2 besteht darin, dass sie mit einer Stativschraube befestigt werden kann.
Wir verwenden die Library OpenKinect von Daniel Shiffman. Es existiert auch eine Library von Max Rheiner (ehem. Dozent am IAD), leider funktioniert seine SimpleOpenNI Librar nicht mehr mit der neuen Version der Kinect Kamera. Wer jedoch die Möglichkeiten des Selektion-Trackings aufprobieren möchte, dem sei ein Blick in die Beispiele empfohlen.
Zunächst muss die Library, wie alle anderen Bibliotheken in Processing installiert werden. Dies geht am einfachsten über "Sketch > Library importieren ... > Library hinzufügen". In das Suchfeld kann nun "Open Kinect for Processing" eingetragen werden. Ein Klick auf "Install" installiert die Library und die zugehörigen Beispiele.
Um die Library nutzen zu können, muss diese importiert werden:
import org.openkinect.processing.*;
Danach muss eine Referenz auf das Kinect Objekt gesetzt werden:
Kinect2 kinect;
Im setup()
wird das Objekt dann initialisiert:
void setup() { kinect2 = new Kinect(this); kinect2.initDevice(); }
Wird eine Kinect Kamera v1 verwendet, muss die Referenz und Initialisierung entsprechend angepasst werden:
Kinect kinect; // ohne "2" void setup() { kinect = new Kinect(this); kinect.initDevice(); }
Sind die obigen Schritte erfolgt kann im Weiteren direkt auf die Informationen der Kinect zugegriffen werden.
Zuerst muss der Video-Stream der Kamera in der setup()
Funktion aktiviert werden:
kinect.initVideo(); kinect.initDevice();
Dann kann das aktuelle Bild gelesen werden:
PImage videoImage = kinect.getVideoImage();
Gezeichnet werden kann das Bild mit:
image(videoImage, 0, 0);
Neben dem zeichnen des Bildes in der draw()
Funktion, gibt es auch die Möglichkeit, das Bild asynchron zu zeichnen. Das bedeutet, es wird nur dann ein Bild gezeichnet, wenn ein neues vorhanden ist. Die entsprechende Funktion lautet:
void videoEvent(Kinect k) { // There has been a video event! }
Zuerst muss der Infrarot-Stream der Kamera in der setup()
Funktion aktiviert werden:
kinect.initIR(); kinect.initDevice();
Dann kann das aktuelle Bild gelesen werden:
PImage irImage = kinect.getIrImage();
Zuerst muss der Tiefenbild-Stream der Kamera in der setup()
Funktion aktiviert werden:
kinect.initDepth(); kinect.initDevice();
Um das Tiefenbild als Graustufen zurückzubekommen wird folgendes gemacht:
PImage depthImage = kinect.getDepthImage();
Der Nachteil des Graustufen-Tiefenbildes ist es, dass alle Entfernungsinformationen auf Werte zwischen 0 bis 255 (Helligkeit) verteilt werden. Tatsächlich kann die Kinect Kamera aber eine viel genauere Auflösung der Tiefeninformationen liefern. Dazu ist es jedoch nötig, das Tiefenarray aufzurufen und auszulesen. Dies geschieht über:
int[] depth = kinect.getRawDepth();
Weil bei der Kinect Kamera der Sensor für das RGB Bild und das Titelbild nicht übereinanderliegen stimmen die Positionen in XY Richtung der einen Kamera, nicht mit denen der anderen überein. Um dies zu korrigieren kann ein RGB Bild angefordert werden, welches durch die Library angepasst wird. Dieses Bild bekommt man über:
PImage img = kinect2.getRegisteredImage();
Hier eine Übersicht der Funktionen, welche die Library zur Verfügung stellt:
initVideo()
— Video Bild initialisieren initIR()
—Infrarot Bild initialisiereninitDepth()
— Tiefenbild initialisieren
initDevice()
— Gerät initialisierenPImage getVideoImage()
— RGB BildPImage getIrImage()
— IR BildPImage getDepthImage()
— TiefenbildPImage getRegisteredImage()
— Angeglichenes RGB Bildint[] getRawDepth()
— TiefenarrayFür weitere Informationen: the javadoc reference.