13 Minuten
Distanzmessung von Objekten mit Hilfe der Microsoft Kinect

Einleitung
Diese Ausarbeitung ist im Rahmen der Vorlesung „Bildverarbeitung" im Sommersemester 2016 als Teil der Klausurleistung entstanden. Sie befasst sich mit dem Thema „Distanzmessung von Objekten mit Hilfe der Microsoft Kinect" und kann als Vorleistung der kommenden Masterarbeit im Bereich Robotik angesehen werden. Das Ziel dieser Arbeit, ist es mögliche Einsatzgebiete der Kinect-Kamera aufzudecken und gegebenenfalls auf Probleme und weniger sinnvolle Einsatzgebiete hinzuweisen. Der Grund warum die Kinect zum Einsatz kommt ist, erstens sie war verfügbar und zweitens ist sie, obwohl sie von Microsoft entwickelt wurde, technisch gesehen eine vielseitig einsetzbare TOF-Kamera. Mit Zunahme der Relevanz von Robotern werden auch Kamera-Systeme immer wichtiger, welche diesem ihre Augen verleihen.
Kinect
Einer der Gründe, warum die Kinect von Microsoft zum Einsatz kam, ist das sie im Vergleich wesentlich kostengünstiger ist als vergleichbare Lösungen anderer Hersteller und zumeist auch vielseitiger einsetzbar ist. Dieses kommt nicht von ungefähr. Sie wurde ursprünglich für die Spielekonsole „Xbox 360" entwickelt und sollte als Bewegungs- und Sprachsensor dienen. Findige Ingenieure erkannten jedoch schnell, dass die Kinect ihr Talent, nur als Spielsensor zu fungieren, verschwendet. Ein gutes halbes Jahr nach dem Release der ersten Kinect-Modelle, erschien die erste C++-Bibliothek für PC´s und Mac. Basierend auf dieser Bibliothek kamen die ersten Wrapper für die verschiedensten Programmiersprachen sehr schnell nach.
Verfügbare SDK´s
Momentan existieren 3 nennenswerte SDK´s für die Kinect. Zum einen hat Microsoft doch noch irgendwann erkannt, dass die Kinect sehr viel Potenzial im Zusammenhang mit dem PC aufweist und ein SDK veröffentlicht und zum anderen hat eine Community rund um die Kinect ein Open-Source-Projekt mit dem Namen „OpenKinect" hervorgerufen, welches das SDK „libfreenect" veröffentlicht hat. Ein weiteres SDK stammt von der Firma „Structure Sensor", welches als Open-Source-Projekt „OpenNI" bekannt ist und als abgeänderte Version (forked version) in die Produkte von Structure Sensor einfliesst.
Technische Details zur Kinect
Der folgende Abschnitt behandelt die technischen Details der Kinect-Kamera und gibt einen ersten Einblick möglichen Einsatzgebiete.
Technische Spezifikation
System | Beschreibung |
---|---|
Sensoren | - Linsensensoren mit Farb- und Tiefeninformationen - Mikrofonverbund für Stimmerkennung - Neigungsmotor für Nachjustierung der Sensoren - Voll kompatibel mit bestehenden Xbox-360-Konsolen |
Sichtfeld | - Horizontales Sichtfeld: 57 Grad - Vertikales Sichtfeld: 43 Grad - Vertikales Sichtfeld: 43 Grad - Neigungsspielraum: ± 27 Grad - Reichweite des Tiefensensors: 1.2m - 3.5m |
Datenströme-Video | - 320x240 16-bit Farbtiefe @ 30 Bilder/sek. - 640x480 32-bit Farbtiefe @ 30 Bilder/sek. |
Datenströme-Audio | - 16-bit Audio @ 16 kHz |
Skelett-Tracking-System | - Verfolgt 20 Gelenke pro aktivem Spieler - Kann aktive Spieler auf LIVE-Avatare projizieren - Verfolgt bis zu 6 Personen, davon 2 aktive Spieler |
Audio-System | - Echounterdrückungssystem zur Verbesserung der Sprachqualität - Mehrfache simultane Spracherkennung - Voice-Chat |
Sichtfeld
Das Sichtfeld der Kamera beträgt im horizontalen Bereich 57° und im vertikalen Bereich 43°. Zudem besitzt die Kinect einen Motor, mit dem sie eine Neigung von 27° erreichen kann. Bei der Personenerkennung kann es also von Vorteil sein, wenn die Person nicht zu nah an der Kamera steht, damit sie den ganzen Körper erkennen kann. Zusätzlich fällt unteranderem auf, dass der Tiefensensor nur eine Reichweite von 4,0 m besitzt. Dies sieht auf den ersten Blick erstmal wenig aus, ist aber für die lokale Costmap1, für welche die Kinect hauptsächlich verwendet wird, völlig ausreichend.
Auflösung
Die optimale Auflösung beträgt 640x480 32-bit Farbtiefe bei 30 Bilder/sek.. Bei dieser geringen Auflösung ist schon zu vermuten, dass die Kamera nicht entwickelt wurde, um Details von Objekten wahrzunehmen, sondern eher auf gröbere Objekte ausgelegt ist. Einen einzelnen Finger einer Hand zuerkennen ist auf eine Distanz von 3,5 m nicht mehr möglich.
Audio
Das System verfügt über ein Mikrofon-Array aus 4 Mikrofonen mit einer Abtastrate von 16kHz. Somit ist es möglich Töne bzw. Sprache einer Richtung oder einer bestimmten Person zuzuordnen.
Skeletal Tracking System
Das System kann bis zu zwei aktive Personen erkennen. Passiv können jedoch so viele Nutzer erkannt werden, wie in das Sichtfeld der Kinect passen. Pro aktiver Person kann die Kamera 20 Gelenke im „Skelett Modell" erstellen. Das Verfahren, welches hier angewendet wird, nennt sich „Skelettierung2". Die Kamera verfolgt die aktiven Nutzer und stellt sie als Sammlung von Gelenken dar. So kann zu jeder Zeit die Position und das Verhalten der Person bestimmt werden.
Grundlagen der Distanzmessung mit Hilfe der Kinect
Bevor es zu der Funktionsweise der Kinect kommt, sollen im Vorfeld einige Grundlagen zu der Entfernungsmessung mit Hilfe solcher Systeme erläutert werden, um bei auftretenden Problemen besser zu verstehen, warum sie auftreten bzw. wie man sie gegebenenfalls lösen könnte.
Time of Flight
Das Time-of-Flight Lichtlaufzeitverfahren ist ein Verfahren zur Entfernungsbestimmung. Die Messobjekte werden von einer Lichtquelle angeleuchtet, bei der Kinect sind es 2 IR3-Lichtquellen, und die Signallaufzeit gemessen. Aufgrund dieser Laufzeit kann die Entfernung zwischen der Kamera und den Objekten errechnet werden. Bei der Kinect ist es allerdings so, dass die optimale Entfernung zwischen 80 cm und 4,0 m liegt. Berücksichtigt man, dass das Licht für einen Zentimeter zirka 33 Pikosekunden4 benötigt, ist es relativ schwer , aufgrund der eingesetzten Hardware, die Zeit genau zu bestimmen welches das Licht für die jeweilige Strecke benötigt. Um dieses Verfahren aber dennoch auf kostengünstiger Hardware und mit relativ wenig Aufwand bei der Kinect einsetzen zu können, wurde auf ein spezielles Modulationsverfahren gesetzt. Folgend eine kleine Beispielrechnung, um zu veranschaulichen, wie präzise die Zeitmessung sein müsste.
Beispielrechnung
Die Messdauer für ein in fünf Meter entferntes Objektes beträgt in etwa:
Wobei die Konstante cluft für die Lichtgeschwindigkeit steht.
Modulation
Das Modulationsverfahren, welches die Kinect verwendet nennt sich Continuous Wave5 Modulation (CWM).

Die Entfernungsinformationen berechnen sich wie folgt:
- Offset a0 (Hintergrundbeleuchtung)
- Amplitude a1 (Reflektiertes moduliertes Licht)
- Phasenverschiebung ΔØ
Jedoch werden zusätzliche Messungen durchgeführt, um ein robustes Ergebnis zu erhalten.
Funktionsweise der Kinect
Die Funktionsweise der Kinect basiert auf drei verschiedenen Bildarten. Zum einen hat das System eine normale RGB-Kamera, wie man sie von jeder anderen Kamera her kennt. Sie nimmt ein 2-dimensionales Bild der Umgebung auf. Zum anderen besitzt die Kinect einen IR-Laser und eine IR-Kamera. Mit diesem Duo wird ein moduliertes Muster auf die gegebene Oberfläche projiziert und mittels ihrer Kamera wieder in sichtbare Bildinformationen umgewandelt. Aus diesen gewonnen Daten, wird ein Tiefenbild berechnet.



Alle drei Bilder wurden zur selben Zeit aufgenommen, nur wurde auf unterschiedliche Schnittstellen der Kinect zugegriffen. Auf dem mittleren Bild ist das Punktmuster des IR-Lasers bzw. der IR-Kamera zu erkennen, welches die eigentlich Magie der Kinect ist.
Das Punktmuster
Das Punktmuster der Kinect ist ein definiertes Muster aus Punkten, welche von dem IR-Laser auf die gegebene Oberfläche aus geworfen werden. Dabei handelt es sich um ein wiederholungsfreies Muster, um kleine Ausschnitte aus dem Gesamtmuster wiederfinden zu können. Folgend ein kurzes Beispiel, wo der kleine Ausschnitt im Gesamtmuster eindeutig lokalisiert werden konnte.
Das Muster besteht insgesamt aus 633×495 potentiellen Punktpositionen. Dies entspricht weniger als der Hälfte der Auflösung, die die IR-Kamera besitzt (1280×1024 Pixel), so dass das Muster entsprechend erfasst werden kann. Da die verwendete Optik des Laser-Projektors nicht ideal ist, weist das projizierte Muster eine kissenförmige Verzerrung auf. Aufgrund des verwendeten infraroten Lichts ist das Punktmuster weder für das menschliche Auge noch für die RGB-Kamera sichtbar, da diese über einen IR-Filter verfügt, der infrarotes Licht blockt.
Distanz- bzw. Tiefenberechnung
Bei der Tiefenberechnung hängt die Lage des Musters auf der Projektionsfläche direkt von der Tiefe ab. Dabei wird das Punktmuster vom IR-Laser auf die Projektionsfläche geworfen und von der IR-Kamera erfasst. Mittels ermittelten Daten kann die Distanz unmittelbar berechnet werden. Die folgende Grafik zeigt die theoretische Ermittlung der Tiefe.
Allgemeine Verarbeitungspipeline der Kinect
Die Verarbeitungspipeline der Kinect ist in sieben wesentliche Schritte unterteilt:
Projektion des strukturierten Punktmusters mit dem IR-Laserprojektor
Erfassung des von der Szene reflektierten Musters mit der IR-Kamera
Berechnung der Disparitäten für jedes Pixel im IR-Kamerabild (Disparitätsbild)
Umrechnung der Disparitätswerte in Tiefenwerte (Tiefenbild)
Schätzung der Skelettkonfiguration des Spielers anhand des Tiefenbildes
Klassifikation der Spielerpose anhand der Skelettkonfiguration
Steuerung der Anwendung entsprechend der klassifizierten Spielerpose
Objekt-Lokalisierung
Bei der Objekt-Erkennung ist es in erster Linie wichtig den Hintergrund, den Anteil des Bildes der nicht auf Objektebene liegt, herauszufiltern. Dafür können verschiedene Techniken angewandt werden. Da die Kinect über ein generiertes Tiefenbild verfügt, kann der Hintergrund von dem Tiefenbild getrennt werden. Dabei wird zunächst erst einmal davon ausgegangen, dass alles zum Hintergrund gehört. Die folgenden Bilder zeigen, wie das in der Praxis funktioniert.
Tiefenbildauswertung



Der Arbeitsablauf läuft, bis auf die Justierung der Hintergrundtiefe, immer auf die gleiche Weise ab.
Dabei ist die Schwellenwertfunktion verantwortlich für die Trennung von Hintergrund und Objekt. Diese Funktion definiert sich wie folgt:
Die empirischen Werte wurden wie folgt ermittelt:
- a = 150000 mm-1
- b = 0
- c = 5 mm
x [mm] | 500 | 1000 | 2000 | 3000 |
---|---|---|---|---|
t(x) [mm] | 7 | 12 | 31 | 65 |
x [mm] | 4000 | 5000 | 6500 | 8000 |
---|---|---|---|---|
t(x) [mm] | 112 | 172 | 287 | 432 |
Pixel an Unstetigkeitsstellen weisen eine hohe Varianz auf und werden auch im stationären Zustand als Vordergrund, sprich zum zu erkennenden Objekt, erkannt. Die verwendeten Filteroperationen „abtragen" und „erweitern" sind wie folgt definiert:
abtragen - Pixel mit schwarzen Nachbarn werden schwarz
erweitern - Pixel mit weißen Nachbarn werden weiß
Somit lässt sich der Maskenfilter wie folgt beschreiben:
1x abtragen ⤳ Kante löschen
2x erweitern ⤳ Lücken füllen
2 x abtragen ⤳ Rand entfernen
Filter zur Objekttrennung
Der Filter für die Objekttrennung arbeitet mit dem oben schon erwähnten Maskenfilter und setzt ausserdem noch auf die Operationen fill, contour, dilate.
fill - Interpoliert die Datenlücken
contour - Führt eine Kantenerkennung durch
dilate - Erweitert die Maske
Praxistest Objekttrennung
In dem folgenden Praxistest wurde der Filter für die Objekterkennung angewendet. Dabei gehen wir davon aus, dass das Bild perfekt ist und keine Fülloperationen benötigt. Dies ist zwar selten der Fall, aber bei einer Aufnahme von zwei Kisten nicht zwingend notwendig.


Wie man auf den obigen Bildern sehen kann, ist der erste Schritte die Objekte von dem Hintergrund zu lösen. Übrig bleiben die Objekte, welche in den nächsten Schritten voneinander getrennt werden.


Der zweite Schritt besteht daran, die Konturen jedes Objektes zu erkennen. Dies ist bei Objekten, welche sich überlappen oder auf der gleichen Tiefenebene liegen, nicht immer einfach. Gegebenenfalls müssen hierfür die Parameter der verwendeten Filter verändert werden.


Mittels der gewonnen Konturdaten können die gefundenen Objekte voneinander getrennt betrachtet werden.
Programmierung
Bei der Programmierung wurde auf des Open-Source Projekt OpenKinect gesetzt. Dieses Projekt hat, wie schon erwähnt wurde, eine sehr starke Community, welche bei auftretenden Problemen sehr schnell und gut arbeitet. Zusätzlich ist der Quellcode voll einsehbar und kann bei möglichen Problemen schnell angepasst werden.
Daten zu OpenKinect
Entstand im Rahmen der OpenKinect-Community
Ermöglicht den Low-Level-Zugriff auf alle Funktionen der Kamera
Die Grundlage bildet eine in C geschriebene Bibliothek
Wrapper für sehr viele Programmiersprachen verfügbar
Python
C++
Actionscript
C#
Java JNA, Java JNI
Javascript
Common Lisp
…
Dokumentation ⇒ libfreenect.h
Prinzip
Initialisierung der Kamera
Aufbauen der USB-Verbindung
Registrieren von Callback-Handlern
Auswahl der Video-Modi
Starten der Streams (RGB-Bild und/oder Tiefenbild)
Aufruf der Eventhandler-Funktion
Event-Handler ruft Callback für jeden empfangenen Frame auf
Deinitialisierung
⇒ Ansteuerung der LEDs bzw. Motoren erfolgt synchron
Zugriff auf die libfreenect-API
In diesem Abschnitt sollen einige grundlegende Zugriffe auf die libfreenect-API beschrieben werden. Dabei ist der Quellcode in C geschrieben.
Initialisierung der Kamera
#include <libfreenect/libfreenect.h>
freenect_context *ctx;
freenect_device *dev;
freenect_frame_mode mode;
void cbfunc (freenect_device *dev, void *depth, uint32_t t) {
}
int init() {
freenect_init (&ctx, NULL);
if (freenect_num_devices (ctx) < 1)
return -1;
freenect_select_subdevices (ctx, FREENECT_DEVICE_CAMERA);
freenect_open_device (ctx, &dev, 0);
freenect_set_depth_callback (dev, cbfunc);
mode = freenect_find_depth_mode (FREENECT_RESOLUTION_MEDIUM, FREENECT_DEPTH_REGISTERED);
freenect_set_depth_mode (dev, mode);
freenect_start_depth (dev);
return 0;
}
Anhand dieses Quellcode, ist es möglich die Kamera zu initialisieren. Es stellt die Vorbereitung für die Verwendung dar und kann zeitgleich als Check für den ordnungsgemäßen Zugriff auf die Kamera betrachtet werden.
Erweiterte Initialisierungsfunktionen und globale Variablen
Folgend werden einige wichtige erweiterte Initialisierungsfunktionen und globale Variablen vorgestellt:
- Fähigkeiten der Hardware auslesen
int freenect_supported_subdevices (void)
- Gerät anhand der Seriennummer öffnen
int freenect_open_device_by_camera_serial (freenect_context *ctx, freenect_device *dev, const char *camera_serial)
- Eigenen Frame-Puffer festlegen
int freenect_set_depth_buffer (freenect_device *dev, void *buf)
- Funktionen des RGB-Datenstroms
void freenect_set_video_callback (freenect_device *dev, freenect_video_cb cb)
int freenect_set_video_buffer (freenect_device *dev, void *buf)
int freenect_start_video (freenect_device *dev)
int freenect_stop_video (freenect_device *dev)
FREENECT_DEPTH_11BIT, FREENECT_DEPTH_10BIT
- Rohdaten. 16 Bit pro Pixel
- Wertebereich: {0, . . . , 2048}
- 2047 ⇒ Datenlücke
FREENECT_DEPTH_11BIT_PACKED, FREENECT_DEPTH_10BIT_PACKED
- Rohdaten. Nur Signifikante Bits im Puffer
FREENECT_DEPTH_MM
- Tiefenangabe in Millimeter
- Wertebereich: {50,…, 10000}
- 0 ⇒ Datenlücke
FREENECT_DEPTH_REGISTERED
- Wie
FREENECT_DEPTH_MM
- Tiefenbild wird auf RGB-Bild umprojiziert
- Wie
Hauptschleife
Der folgende Quellcode stellt die Hauptschleife dar. Sie wartet auf Events, welche von der Kinect-Kamera geworfen werden.
#include <libfreenect/libfreenect.h> freenect_context *ctx;
int die=0;
void mainloop() {
while(!die) freenect_process_events (ctx);
}
- Der Handler wird durch
freenect_process_events()
abgearbeitet freenect_process_events()
kann auch zurückkehren ohne irgendeinen Handler aufzurufen- Timeout-Variante
int freenect_process_events_timeout(freenect_context *ctx, struct timeval* timeout)
Verarbeitung der Frames
Der nächste Quellcode stellt einen kleinen Test dar und soll prüfen, ob ein Pixel vor der Kameraebene liegt oder ob die Distanz des Pixels nicht eindeutig bestimmt werden konnte.
#include <libfreenect/libfreenect.h>
freenect_frame_mode mode;
/* Modus: FREENECT_DEPTH_REGISTERED */
static void cbfunc(freenect_device *dev, void *depth, uint32_t t) {
unsigned int x, y, offset; uint16_t dist;
printf("Zeitstempel: %12u:\n", t); x = /* ... */;
y = /* ... */;
offset = (y * mode.width + x) * (mode.data_bits_per_pixel + mode.padding_bits_per_pixel) / 8;
dist = *(uint16_t*)(depth + offset);
if(dist)
printf("Pixel (%u, %u) liegt %u mm vor der Kameraebene.\n", x, y, dist);
else
printf("Distanz von Pixel (%u, %u) ist nicht bestimmbar.\n", x, y); }
Deinitialisierung
#include <libfreenect/libfreenect.h>
freenect_context *ctx;
freenect_device *dev;
freenect_frame_mode mode;
void deinit() {
freenect_stop_depth(dev);
freenect_close_device(dev);
freenect_shutdown(ctx);
}
Mittels der Deinitialisierung wird die Verbindung zur Kamera geschlossen und es werden alle gesetzten Variablen in der Kamera mit den Default-Werten überschrieben.
Weitere Funktionen
Die Kinect besitzt noch mehr Features als die oben beschriebenen für die Frameabgreifung der unterschiedlichen Kameras der Kinect. Mit Hilfe der libfreenect-Bibliothek hat man auch auf diese Zugriff.
Zugriff auf Schwerkraftsensor
- Bestimmung des Neigungswinkels
Ansteuerung der Motoren in der Montierung der Kinect
Ansteuerung der LED´s an der Frontblende
Für eine Übersicht der möglichen Funktionen der API gibt es Dokumentation in der Header-Datei libfreenect.h.
Fazit
Dank der, von der Community entwickelten, libfreenect-Bibliothek, ist es sehr einfach schnelle Erfolge in der 3D-Objekterkennung zu erzielen. Besonders hilfreich ist dabei, dass die Bibliothek leicht in die Software Matlab eingebunden werden kann und daher die Möglichkeit besteht die erhaltenen Daten der Kinect direkt weiterverarbeiten zu können. Ohne die Kinect an dieser Stelle zu sehr zu loben, ist sie eine sehr gute Kamera, welche sich in den unterschiedlichsten Projekten einsetzen lässt. Spontan würde mir ein Videokonferenzsystem einfallen, welches sich mit Hilfe der Kinect mit Personentracking und Interaktionsbereichen erweitern lassen würde. Aber auch eine Gestensteuerung wie in dem Film Minority Report könnte ich mir gut vorstellen. Dabei würde das integrierte Trackingsystem sehr hilfreich sein.
Nichtsdestotrotz bringt das System natürlich auch seine gewissen Probleme mit sich. Da die Kinect auf Infrarotlicht setzt, ist es nicht möglich bei direkter Sonneneinstrahlung eine Objekterkennung durchzuführen. Auch in sehr hellen Räumen gibt es oft Schwierigkeiten mit der Distanzberechnung. Bei der Gestensteuerung wäre zum Beispiel die geringe Auflösung ein Hindernis, da ein einzelner Finger auf eine Entfernung von 4 m nicht mehr erkannt wird.
Abschließen ist zu sagen, dass die Kinect ein sehr guter Einstieg in die Welt der TOF-Kameras ist und dabei einen Bruchteil der Profigeräte kostet.
Quellenverzeichnis
Marc Sperling - Diplomarbeit am Institut für Informatik der Freien Universität Berlin Arbeitsgruppe: Intelligente Systeme und Robotik Berührungslose QWERT-Z Eingabemethoden für interaktive Flächen
Bernd Jähne ["]{dir=“rtl”}Entwicklungsstand und Zukunftsperspektiven für 3D-Laufzeitkameras"
Kinect Range Sensing: Structured-Light versus Time-of-Flight Kinect - https://arxiv.org/pdf/1505.05459.pdf
Microsofts Kinect als Bastlertraum - http://www.hardware-infos.com/news/3766/microsofts-kinect-als-bastlertraum.html
Time-of-Flight and Kinect Imaging
Costmap - Dient der Navigation und hilft bei der Bestimmung des optimalen Pfades. ↩︎
Skelettierung - Als Skelettierung wird eine Klasse von Verfahren der Bildverarbeitung bezeichnet. Bei der Skelettierung wird ein flächenhaftes Bildobjekt in eine 1 Bildpunkt breite, innere Skelettlinie umgewandelt. ↩︎
IR (Infrarot) - Infrarot bezeichnet in derPhysik elektromagnetische Wellen im Spektralbereich zwischen sichtbarem Licht und der längerweiligen Teraherzstrahlung. ↩︎
Pikosekunde - 1 ps = 1.0E-12 s ↩︎
Continuous wave oder continuous waveform, abgekürzt CW, bezeichnet eine ungedämpfte, also zeitlich konstante abgestrahlte Welle. Im Fall der Kinect ist es ein IR-Laser mit moduliertem Muster. ↩︎
kinect xbox distance measuring
2744 Wörter
05-04-2022 00:00 (Letzte Aktualisierung: 19-02-2025 23:04)
974ad4a @ 19-02-2025