Ceci est une ancienne révision du document !
Daniel Shifmann propose un tutoriel très pratique pour l'utilisation de la Kinect :
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 WAN DER POORT
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.
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); } } }
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; } }
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.
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; 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); } } }
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; } }