Kinect Einstieg


Die Kinect ist eine 3D Kamera. Sie nimmt in erster Linie nicht das Aussehen von Objekten auf, sondern deren Position im Raum.

Wie schafft die Kinect das?

Die Hardware besteht aus 2 Kameras. Einer normale RGB Kamera und einer Infrarot Kamera. Die RGB Kamera liefert ein Bild vergleichbar einer günstigen Webcam in einer Auflösung von 640 mal 480 Pixel. Die IR Kamera liefert ein IR Bild in der selben Auflösung. Außerdem ist die Kinect mit einem IR Projektor ausgestattet. Dieser projeziert Infrarot Pixel, die dann mit den entsprechenden Pixel der IR Kamera verrechnet werden. Daraus kann dann die Entfernung der Pixel vom Sensor errechnet werden.

121212_222007_369

IR Bild aus der Kinect

Die Kinect kann nun verschiedene Outputs produzieren. Dafür verwenden wir folgendes Beispielprogramm:

/** Copyright 2012 Thomas Koberger
*/

// https://lernprocessing.wordpress.com/
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/**
*
* MOUSE
*
* KEYS
* s                   : save png
*/

import SimpleOpenNI.*;
import java.util.Calendar;

SimpleOpenNI  kinect;

void setup()
{
size(640, 480);

kinect = new SimpleOpenNI(this);

// depthMap aktivieren
kinect.enableDepth();

// RGB Kamera aktivieren
//kinect.enableRGB();

// IR Kamera aktivieren
//kinect.enableIR();

// Scenemap aktivieren
//kinect.enableScene();
}

void draw()
{
// Update Kinect
kinect.update();

// Eine der vier Images können aktiviert werden, wenn auch in
// setup() die entsprechende Funktion aktiviert wurde
// Achtung: RGB und IR können nicht parallel genutzt werden!!!
image(kinect.depthImage(), 0, 0);
//image(kinect.rgbImage(),0,0);
//image(kinect.irImage(), 0, 0);
//image(kinect.sceneImage(),0,0);
}

void keyReleased() {
if (key == 's' || key == 'S') saveFrame(timestamp()+"_##.png");
}

// timestamp
String timestamp() {
Calendar now = Calendar.getInstance();
return String.format("%1$ty%1$tm%1$td_%1$tH%1$tM%1$tS", now);
}

Das Programm erzeugt zuerst einmal ein Objekt des SimpleOpenNI Sensors namens kinect. Mit dessen Hilfe kann man nun die Funktionen der Kinect kontrollieren. Damit wir dann Output generieren können, müssen wir die verschiedenen Funktionen der Kinect aktivieren. Das passiert in der Funktion setup(). In draw() müssen dann die Daten aus dem Sensor abergerufen werden. Nun können die vom Sensor bereitgestellten Bilder ausgegeben werden.

Wie sind diese Bilder zu interpretieren?

1. depthImage()

121212_221759_2334

Dieses Bild wird von der Kinect aus den Tiefeninformationen generiert. Nahe Objekte werden heller dargestellt, als weiter entfernte. Sind Objekte weniger weit als etwa 50 cm funktioniert die Entfernungsmessung nicht. Diese Objekte werden schwarz dargestellt. Der Messbereich reicht bis 8m. Die Entfernung werden von der Kinect sehr genau gemessen. Wir werden später sehen, wie wir diese ermitteln können. Was an  dem Bild noch auffällt ist, dass es kleine scharze Bereiche enthält. Diese werden von Schatten verursacht, die näher gelegene Objekte auf weiter entfernte werfen. In diesen Bereichen kann natürlich keine Tiefeninfo abgerufen werden.

Wenn wir das Programm um folgende Zeile erweitern, können wir die Tiefeninformation an der Mausposition abrufen. Dafür verwenden wir die OpenNI Funktion depthMap(). Sie gibt ein int- Array mit der Entfernung des Punktes zum Sensor zurück.

  println(kinect.depthMap()[640*mouseY+mouseX]);

2. rgbImage()

121212_221837_865

Dieses Bild stammt von der RGB Kamera und ist qualitativ nicht besonders ansprechend. Allerdings ist sie doch recht interessant. Wir werden uns später ansehen, wie man die Farbinfos auf die Tiefenprojektion übertragen und somit ein farbiges 3 dimensionales Bild erstellen können.

3. irImage()

121212_222007_369

Output der IR Kamera. Hier kann man sehr gut die projezierten IR Punkte sehen.

4. sceneImage()

121212_224833_15438

Hier sind wir schon bei den höheren Funktionen der SimpleOpenNI. In diesem Modus versucht die Library Gegenstände im Bild zu erkennen. Wird ein Gegenstand erkannt, färbt ihn das System automatisch ein.

Advertisements

3 Kommentare

  1. Pingback: Processing – Über dieses Weblog « processing – tutorial

  2. Pieter De Cuyper

    Hey
    Ich arbeite gerade an einer Interaktiven Installation an der Uni, und bräuchte ein wenig Hilfe beim schreiben des Java-Codes. Ich habe leider nicht so viel Ahnung von processing, und wäre sehr dankbar wenn mir jemand hier helfen könnte.
    Ich würde gerne die Visualisierung die Ich habe mit dem Average Point Tracking von Daniel Schiffermann (http://shiffman.net/2011/01/13/new-kinect-example-average-point-tracking/) verknüpfen. Ziel ist es mit der Hand, die Bewegung auf dem Raster der Visualisierung beeinflussen zu können.

    Code der Visualisierung :
    int i=0;
    int j=0;
    float distance=0;
    int spacing= 30;

    void setup(){
    size(800,800);
    background(255);
    }
    void draw(){
    background(255);
    int numX=width/spacing;
    int numY=height/spacing;
    float[] ranX =new float[numX*numY];
    float[] ranY =new float[numX*numY];
    float[] x =new float[numX*numY];
    float[] y =new float[numX*numY];
    for(i=1;i<numX;i++){ noFill();
    beginShape();
    x[i]=spacing*i;
    //vertical lines
    for(j=1;j<numY;j++){
    y[j]=spacing*j;
    distance=dist(mouseX,mouseY,x[i],y[j])*0.004; //caluate distance from mouseX,Y to regular grid points ranX[numY*i+j] =random(-1/distance,1/distance); // if distance close, ranX value ++
    ranY[numY*i+j] =random(-1/distance,1/distance); // if distance close, ranX value ++ vertex(x[i]+ranX[numY*i+j],y[j]+ranY[numY*i+j]); // regular grid point + random value
    }
    endShape();
    }

    //vertical lines
    for(i=1;i<numX;i++){
    beginShape();
    for(j=1;j<numY;j++){
    vertex(x[j]+ranX[numY*j+i],y[i]+ranY[numY*j+i]); //connect lines
    }
    endShape();
    }
    }

    Wenn mir jemand behilflich sein kann wäre ich wie gesagt sehr dankbar !

  3. Pingback: Der Kinect-Bewegungssensor | seinteractive

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s

%d Bloggern gefällt das: