Outils pour utilisateurs

Outils du site


wiki:tutoriels:kinect-dessiner-avec-la-main:accueil

Dessiner avec la main avec la kinect

Exemple de la librairie OpenKinect for Processing

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 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

wiki/tutoriels/kinect-dessiner-avec-la-main/accueil.txt · Dernière modification: 2020/11/27 12:19 (modification externe)