Monday, November 10, 2014

Point Cloud | processing - tutorial



Processing 2.0


Der Kinect Sensor bietet die einzigartige Möglichkeit die Distanz der einzelnen Bildpunkte zur Kamera zu messen. Wir nutzen diese Möglichkeit jetzt und zeichnen alle einzelnen Bildpunkte, die der Sensor liefert einfach im 3-dimensionalen Raum darzustellen. Das ganze bezeichnet man als Point Cloud.


141104_113108_52



/** Copyright 2014 Thomas Koberger
*/

// http://ift.tt/1w8DL7V
// 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://ift.tt/jtTJvY
// 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.

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

SimpleOpenNI kinect;

void setup() {
size(1200, 768, P3D);
kinect = new SimpleOpenNI(this);
kinect.enableDepth();
stroke(255);
}

void draw() {
background(0);
kinect.update();

// Verschiebe die Szene in den Mittelpunkt des Fensters
translate(width/2, height/2, -500);
// vertikal drehen, damit die Szene nicht auf dem Kopf steht
rotateX(radians(180));
// Rotationspunkt in die Mitte der Szene verschieben

translate(0, 0, 1500);
randomSeed(20);
// Damit die Szene automatisch rotiert.
rotateY((float)frameCount/50);
translate(0, 0, -1500);

// Einkommentieren, wenn man die Szene per Maus rotieren will!
// rotateY(map(mouseX, 0, width, -PI, PI));
// rotateX(map(mouseY, 0, width, -PI, PI));

// Hier liefert die Kinect ein Array mit Vektoren
PVector[] depthPoints = kinect.depthMapRealWorld();

// Wir zeichnen nicht jeden Punkt, um die Sache zu beschleunigen
for (int i = 0; i < depthPoints.length; i+= (int)random(2, 10)) {
PVector currentPoint = depthPoints[i];
stroke(map(currentPoint.z, 0, 7000, 255, 80));
point(currentPoint.x, currentPoint.y, currentPoint.z);
}
}

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

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


Farbe


Nun können wir auch beide Kameras der Kinect nutzen und den Punkten ihre entsprechende Farbe zuweisen. Dabei kommen die Tiefeninformationen von der IR und die Farbinformationen von der RGB Kamera. Die dafür notwendigen mathematischen Operationen, nämlich das Auffinden der korrespondierenden Punkte der beiden Kameras, erledigt die Kinect.


141107_164425_59



</pre>
<pre>/** Copyright 2014 Thomas Koberger
*/

// http://ift.tt/1w8DL7V
// 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://ift.tt/jtTJvY
// 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.

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

SimpleOpenNI kinect;

void setup() {
size(1200, 768, P3D);
kinect = new SimpleOpenNI(this);
kinect.enableDepth();
// Aktiviert die RGB Kamera der Kinect
kinect.enableRGB();
//Berechnet die korresponierenden Punkte der beiden Kameras
//Dadurch bekommen die korrespondierenden Punkte der Tiefen- und der RGB Kamera
//die gleichen Indizes
kinect.alternativeViewPointDepthToImage();
}

void draw() {
background(0);
kinect.update();

// Verschiebe die Szene in den Mittelpunkt des Fensters
translate(width/2, height/2, -500);
// vertikal drehen, damit die Szene nicht auf dem Kopf steht
rotateX(radians(180));
// Rotationspunkt in die Mitte der Szene verschieben

translate(0, 0, 1500);

// Damit die Szene automatisch rotiert.
rotateY((float)frameCount/50);
translate(0, 0, -1500);

// Einkommentieren, wenn man die Szene per Maus rotieren will!
// rotateY(map(mouseX, 0, width, -PI, PI));
// rotateX(map(mouseY, 0, width, -PI, PI));

// Hier liefert die Kinect ein Array mit Vektoren
PVector[] depthPoints = kinect.depthMapRealWorld();
PImage rgbImage = kinect.rgbImage();

// Wir zeichnen nicht jeden Punkt, um die Sache zu beschleunigen
for (int i = 0; i < depthPoints.length; i+= 10) {
PVector currentPoint = depthPoints[i];

// Hiermit färben wir die Punkte der Tiefeninformation mit der entsprechend
// Farbe aus der RGB Kamera ein.
stroke(rgbImage.pixels[i],map(currentPoint.z,0,7000,255,80));
point(currentPoint.x, currentPoint.y, currentPoint.z);
}
println(frameRate);
}

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

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



Linien


Nun kann man die einzelnen Punkte auch mit Linien verbinden.



/** Copyright 2014 Thomas Koberger
*/

// http://ift.tt/1w8DL7V
// 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://ift.tt/jtTJvY
// 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.

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

SimpleOpenNI kinect;

void setup() {
size(1200, 768, P3D);
kinect = new SimpleOpenNI(this);
kinect.enableDepth();
// Aktiviert die RGB Kamera der Kinect
kinect.enableRGB();
//Berechnet die korresponierenden Punkte der beiden Kameras
//Dadurch bekommen die korrespondierenden Punkte der Tiefen- und der RGB Kamera
//die gleichen Indizes
kinect.alternativeViewPointDepthToImage();
noSmooth();
}

void draw() {
background(0);
kinect.update();

// Verschiebe die Szene in den Mittelpunkt des Fensters
translate(width/2, height/2, -500);
// vertikal drehen, damit die Szene nicht auf dem Kopf steht
rotateX(radians(180));
// Rotationspunkt in die Mitte der Szene verschieben

translate(0, 0, 1500);

// Damit die Szene automatisch rotiert.
rotateY((float)frameCount/50);
translate(0, 0, -1500);

// Einkommentieren, wenn man die Szene per Maus rotieren will!
// rotateY(map(mouseX, 0, width, -PI, PI));
// rotateX(map(mouseY, 0, width, -PI, PI));

// Hier liefert die Kinect ein Array mit Vektoren
PVector[] depthPoints = kinect.depthMapRealWorld();
PImage rgbImage = kinect.rgbImage();
strokeWeight(1);
PVector prevPoint, currentPoint;
prevPoint = new PVector(0, 0, 0);
// Wir zeichnen nicht jeden Punkt, um die Sache zu beschleunigen
for (int i = 20; i < depthPoints.length; i+= 3) {

currentPoint = depthPoints[i];

stroke(rgbImage.pixels[i]);

if (prevPoint.x!=0 && currentPoint.x!=0) {
line(currentPoint.x, currentPoint.y, currentPoint.z, prevPoint.x, prevPoint.y, prevPoint.z);
}

// Wie speichern die Koordinaten des aktuellen Punkts als letzten Punkt
prevPoint = currentPoint;
}
println(frameRate);
}

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

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







Source:


http://ift.tt/1u0cLuP






The Late News from http://ift.tt/1j1u6hM