====== 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 : * {{:wiki:tutoriels:kinect:cours_kinect.pdf|}} * {{:wiki:tutoriels:kinect:cours_kinect.pptx|}} * {{:wiki:tutoriels:kinect:making_things_see.pdf|}} * [[wiki:tutoriels:kinect:kinect]] ===== Exemple de la librairie OpenKinect for Processing ===== Daniel Shifmann propose un tutoriel très pratique pour l'utilisation de la Kinect : * [[https://shiffman.net/p5/kinect/|Getting Started with Kinect and Processing]] * [[https://github.com/shiffman/OpenKinect-for-Processing | Librairie OpenKinect]] L'exemple [[https://github.com/shiffman/OpenKinect-for-Processing/tree/master/OpenKinect-Processing/examples/Kinect_v2/AveragePointTracking2|AveragePointTraking2]] de la librairie [[https://shiffman.net/p5/kinect/|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 {{:wiki:tutoriels:kinect_dessiner_avec_la_main:capture_d_ecran_2020-11-27_a_12.11.16.png|}} {{:wiki:tutoriels:kinect_dessiner_avec_la_main:capture_d_ecran_2020-11-27_a_12.12.48.png?400|}} ===== Exemple 1 : Dessiner une ligne brisée ===== A partir de l'exemple précédent [[https://github.com/shiffman/OpenKinect-for-Processing/tree/master/OpenKinect-Processing/examples/Kinect_v2/AveragePointTracking2|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 : {{ :wiki:tutoriels:kinect_dessiner_avec_la_main: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 : {{ :wiki:tutoriels:kinect_dessiner_avec_la_main: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 listePoints; void setup() { size(640, 520); // initialisation var. Glob. kinect = new Kinect(this); tracker = new KinectTracker(); anciennePosition = new PVector(0, 0); listePoints = new ArrayList(); } 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