Dessiner avec la main avec la kinect

Licence : libre !

Fichiers : http://www.tonerkebab.fr/wiki/lib/exe/fetch.php/wiki:tutoriels:installation_kinect.zip

Modifié par Damien MUTI DESGROUAS le 17/12/2018

Fichiers :

cours_kinect.pdf

cours_kinect.pptx

making_things_see.pdf

kinect

Exemple de la librairie OpenKinect for Processing

Daniel Shifmann propose un tutoriel très pratique pour l'utilisation de la Kinect :

Getting Started with Kinect and Processing

Librairie OpenKinect

L'exemple AveragePointTraking2 de la librairie OpenKinect permet de détecter le point moyen le plus proche de la Kinect et de dessiner un cercle rouge sur ce point. Vous pouvez le retrouver dans Examples> Open Kinect For Processing > Kinect_v2 > AveragePointTraking2.pde .

Le programme commenté en français est le suivant : A COMPLETER PAR FLORA VANDER POORTE

Exemple 1 : Dessiner une ligne brisée

A partir de l'exemple précédent AveragePointTraking2, on peut dessiner des lignes successives entre le point détecté à l'instant tn et le point détecté l'instant suivant tn+1.

Code principal

Le code est le suivant : averagepointtracking_modif_dessin_ligne_brisee.zip

// Daniel Shiffman
// Tracking the average location beyond a given depth threshold
// Thanks to Dan O'Sullivan
// https://github.com/shiffman/OpenKinect-for-Processing
// http://shiffman.net/p5/kinect/
import org.openkinect.freenect.*;
import org.openkinect.processing.*;
// The kinect stuff is happening in another class
KinectTracker tracker;
Kinect kinect;
// dessin
PVector anciennePosition;
int compteurFrames = 0;
void setup() {
size(640, 520);
// initialisation var. Glob.
kinect = new Kinect(this);
tracker = new KinectTracker();
anciennePosition = new PVector(0, 0);
}
void draw() {
//background(255);
// Run the tracking analysis
tracker.track();
// Show the image
//tracker.display();
// Rond Rouge
// Let's draw the raw location RED
PVector v1 = tracker.getPos();
fill(#FC0808);
noStroke();
ellipse(v1.x, v1.y, 20, 20);
// dessin d'une ligne brisée
if (compteurFrames > 3 ) { //compteurFrames > 3 : on me prend pas en compte les 1ers points
strokeWeight(2);
stroke(255, 255, 0);
line(anciennePosition.x, anciennePosition.y, v1.x, v1.y);
// mémorisation de la nouvelle position
anciennePosition = v1;
}
// Info Profondeur
// Display some info
int t = tracker.getThreshold();
fill(0);
text("threshold: " + t + " " + "framerate: " + int(frameRate) + " " +
"UP increase threshold, DOWN decrease threshold", 10, 500);
// incrémentation du compteur de frames
compteurFrames++;
println("compteurFrames = "+compteurFrames);
}
// Adjust the threshold with key presses
// réglage profondeur de champ
void keyPressed() {
int t = tracker.getThreshold();
if (key == CODED) {
if (keyCode == UP) {
t+=5;
tracker.setThreshold(t);
} else if (keyCode == DOWN) {
t-=5;
tracker.setThreshold(t);
}
}
}

Classe KinectTracker

La classe KinectTracker est la suivante :

// Daniel Shiffman
// Tracking the average location beyond a given depth threshold
// Thanks to Dan O'Sullivan
// https://github.com/shiffman/OpenKinect-for-Processing
// http://shiffman.net/p5/kinect/
class KinectTracker {
// Depth threshold
int threshold = 745;
// Raw location
PVector loc;
// Interpolated location
PVector lerpedLoc;
// Depth data
int[] depth;
// What we'll show the user
PImage display;
KinectTracker() {
// This is an awkard use of a global variable here
// But doing it this way for simplicity
kinect.initDepth();
kinect.enableMirror(true);
// Make a blank image
display = createImage(kinect.width, kinect.height, RGB);
// Set up the vectors
loc = new PVector(0, 0);
lerpedLoc = new PVector(0, 0);
}
void track() {
// Get the raw depth as array of integers
depth = kinect.getRawDepth();
// Being overly cautious here
if (depth == null) return;
float sumX = 0;
float sumY = 0;
float count = 0;
for (int x = 0; x < kinect.width; x++) { // parcours de tous les points "distances" dans la matrice mesurée par la kinect
for (int y = 0; y < kinect.height; y++) {
int offset = x + y*kinect.width;
// Grabbing the raw depth
int rawDepth = depth[offset];
// Testing against threshold
if (rawDepth < threshold) { // détection des points inférieurs au seuil
sumX += x;
sumY += y;
count++;
}
}
}
// As long as we found something
if (count != 0) {
loc = new PVector(sumX/count, sumY/count); // moyenne des points trouvés dont la distance est inférieure au seuil
}
// Interpolating the location, doing it arbitrarily for now
lerpedLoc.x = PApplet.lerp(lerpedLoc.x, loc.x, 0.3f);
lerpedLoc.y = PApplet.lerp(lerpedLoc.y, loc.y, 0.3f);
}
PVector getLerpedPos() {
return lerpedLoc;
}
PVector getPos() {
return loc;
}
void display() {
PImage img = kinect.getDepthImage();
// Being overly cautious here
if (depth == null || img == null) return;
// Going to rewrite the depth image to show which pixels are in threshold
// A lot of this is redundant, but this is just for demonstration purposes
display.loadPixels();
for (int x = 0; x < kinect.width; x++) {
for (int y = 0; y < kinect.height; y++) {
int offset = x + y * kinect.width;
// Raw depth
int rawDepth = depth[offset];
int pix = x + y * display.width;
if (rawDepth < threshold) {
// A red color instead
// couleur contraste profondeur
// display.pixels[pix] = color(150, 50, 50);
display.pixels[pix] = color(#05FF5A);
} else {
display.pixels[pix] = img.pixels[offset];
}
}
}
display.updatePixels();
// Draw the image
// Affichage vidéo
image(display, 0, 0);
}
int getThreshold() {
return threshold;
}
void setThreshold(int t) {
threshold = t;
}
}

Exemple 2 : Dessiner une courbe

On modifie l'exemple précédent en créant un tableau dynamique (ArrayList) qui mémorise au fur et à mesure de leur détection les points les plus proches de la kinect. Ensuite, à chaque itération de la boucle draw(), on affiche l'ensemble des points sous la forme d'une courbe ou d'une ligne brisée.

Code principal

Le code est le suivant : averagepointtracking_modif_dessin_courbe.zip

// Daniel Shiffman
// Tracking the average location beyond a given depth threshold
// Thanks to Dan O'Sullivan
// https://github.com/shiffman/OpenKinect-for-Processing
// http://shiffman.net/p5/kinect/
import org.openkinect.freenect.*;
import org.openkinect.processing.*;
// The kinect stuff is happening in another class
KinectTracker tracker;
Kinect kinect;
// dessin
PVector anciennePosition;
int compteurFrames = 0;
ArrayList<PVector> listePoints;
void setup() {
size(640, 520);
// initialisation var. Glob.
kinect = new Kinect(this);
tracker = new KinectTracker();
anciennePosition = new PVector(0, 0);
listePoints = new ArrayList<PVector>();
}
void draw() {
background(255);
// Run the tracking analysis
tracker.track();
// Show the image
//tracker.display();
// Rond Rouge
// Let's draw the raw location RED
PVector v1 = tracker.getPos();
fill(#FC0808);
noStroke();
ellipse(v1.x, v1.y, 20, 20);
//Mémorisation de toutes les positions
listePoints.add(v1);
// dessin d'une ligne brisée
//for( int i=1; i<listePoints.size(); i++){
// line(listePoints.get(i-1).x, listePoints.get(i-1).y,listePoints.get(i).x, listePoints.get(i).y);
//}
// dessin d'une courbe
noFill();
beginShape();
for( int i=0; i<listePoints.size(); i++){
curveVertex(listePoints.get(i).x, listePoints.get(i).y);
}
endShape();
// Info Profondeur
// Display some info
int t = tracker.getThreshold();
fill(0);
text("threshold: " + t + " " + "framerate: " + int(frameRate) + " " +
"UP increase threshold, DOWN decrease threshold", 10, 500);
// incrémentation du compteur de frames
compteurFrames++;
println("compteurFrames = "+compteurFrames);
}
// Adjust the threshold with key presses
// réglage profondeur de champ
void keyPressed() {
int t = tracker.getThreshold();
if (key == CODED) {
if (keyCode == UP) {
t+=5;
tracker.setThreshold(t);
} else if (keyCode == DOWN) {
t-=5;
tracker.setThreshold(t);
}
}
}// Daniel Shiffman
// Tracking the average location beyond a given depth threshold
// Thanks to Dan O'Sullivan
// https://github.com/shiffman/OpenKinect-for-Processing
// http://shiffman.net/p5/kinect/
import org.openkinect.freenect.*;
import org.openkinect.processing.*;
// The kinect stuff is happening in another class
KinectTracker tracker;
Kinect kinect;
// dessin
PVector anciennePosition;
int compteurFrames = 0;
ArrayList<PVector> listePoints;
void setup() {
size(640, 520);
// initialisation var. Glob.
kinect = new Kinect(this);
tracker = new KinectTracker();
anciennePosition = new PVector(0, 0);
listePoints = new ArrayList<PVector>();
}
void draw() {
background(255);
// Run the tracking analysis
tracker.track();
// Show the image
//tracker.display();
// Rond Rouge
// Let's draw the raw location RED
PVector v1 = tracker.getPos();
fill(#FC0808);
noStroke();
ellipse(v1.x, v1.y, 20, 20);
//Mémorisation de toutes les positions
listePoints.add(v1);
// dessin d'une ligne brisée
//for( int i=1; i<listePoints.size(); i++){
// line(listePoints.get(i-1).x, listePoints.get(i-1).y,listePoints.get(i).x, listePoints.get(i).y);
//}
// dessin d'une courbe
noFill();
beginShape();
for( int i=0; i<listePoints.size(); i++){
curveVertex(listePoints.get(i).x, listePoints.get(i).y);
}
endShape();
// Info Profondeur
// Display some info
int t = tracker.getThreshold();
fill(0);
text("threshold: " + t + " " + "framerate: " + int(frameRate) + " " +
"UP increase threshold, DOWN decrease threshold", 10, 500);
// incrémentation du compteur de frames
compteurFrames++;
println("compteurFrames = "+compteurFrames);
}
// Adjust the threshold with key presses
// réglage profondeur de champ
void keyPressed() {
int t = tracker.getThreshold();
if (key == CODED) {
if (keyCode == UP) {
t+=5;
tracker.setThreshold(t);
} else if (keyCode == DOWN) {
t-=5;
tracker.setThreshold(t);
}
}
}

Classe KinectTracker

La classe KinectTracker est la suivante : voir l'exemple précédent...