Hand drawing / Processing + Kinect


TraceHandsPositionAndSpeed
Génération de dessin à partir de données Kinect;
Traitement de la position des mains de l'utilisateur (x, y, z);

Sources: KinectHandDrawing.pde v1.0 / Processing 3.0.1 + Librairie Kinect4WinSDK / Kinect v1 modèle 1414 / KinectSDK v1.8

/*  - KinectHandDrawing.pde v 1.0 - processing 3.0.1 - transat@stephanecabee.net
    - Generation de dessin a partir des donnees de Kinect v1 modele 1414
*/

import kinect4WinSDK.Kinect;
import kinect4WinSDK.SkeletonData;
 
Kinect kinect;
ArrayList <SkeletonData> bodies;

float[] leftHandOldPos = {0, 0, 0}; // x, y, z
float[] rightHandOldPos = {0, 0, 0}; // x, y, z
boolean startL=false;
boolean startR=false;
 
void setup()
{
  size(1280, 960, P3D);
  frameRate(30);
  colorMode(HSB); // Valeur de couleur au format HSB (Hue Saturation Brightness)
  background(50);
  kinect = new Kinect(this);
  smooth(4);
  bodies = new ArrayList<SkeletonData>();

}

void draw()
{
  //image(kinect.GetImage(), 0, 0, width, height);
  // Boucle pour chaque corps détécté.
  for (int i=0; i<bodies.size(); i++) 
  {
    getPos(bodies.get(i));
  }
}

void getPos(SkeletonData skel) 
{
   // Renvoie le squelette et la position de la main gauche
  DrawLeftHandPos(skel, Kinect.NUI_SKELETON_POSITION_HAND_LEFT);
 
  // Renvoie le squelette et la position de la main droite
  DrawRightHandpos(skel, Kinect.NUI_SKELETON_POSITION_HAND_RIGHT);
}

// Function de dessin sur la main gauche; Generation de lignes dont épaisseur et luminosité dépendent de la profondeur
void DrawLeftHandPos(SkeletonData skel, int j) 
{
  noFill();
  if(startL == false){
    println("Left hand OK;");
    // Initialisation de la valeur de départ
    leftHandOldPos[0] = skel.skeletonPositions[j].x;
    leftHandOldPos[1] = skel.skeletonPositions[j].y;
    leftHandOldPos[2] = skel.skeletonPositions[j].z;
    startL = true;
  }
  else if (skel.skeletonPositionTrackingState[j] != Kinect.NUI_SKELETON_POSITION_NOT_TRACKED) {
    // Couleur du trait avec valeur de luminosité en fonction de la profondeur
    stroke(150, 30, 255 - skel.skeletonPositions[j].z/100);
    // Epaisseur du trait en fonction de la profondeur
    strokeWeight(20 - skel.skeletonPositions[j].z/1000);
    line(leftHandOldPos[0]*width, leftHandOldPos[1]*height, leftHandOldPos[2]/100, skel.skeletonPositions[j].x*width, skel.skeletonPositions[j].y*height, skel.skeletonPositions[j].z / 100);
    
    // Stockage de l'ancienne position de la main
    leftHandOldPos[0] = skel.skeletonPositions[j].x;
    leftHandOldPos[1] = skel.skeletonPositions[j].y;
    leftHandOldPos[2] = skel.skeletonPositions[j].z;
  }
}

// Function de dessin sur la main droite; Generation de points dont la grosseur dépend de la vitesse et la luminosité de la profondeur
void DrawRightHandpos(SkeletonData skel, int j) 
{
  noStroke();
  fill(150, 30, 120);
  if(startR == false){
    println("Right hand OK;");
    // Initialisation de la valeur de départ
    rightHandOldPos[0] = skel.skeletonPositions[j].x;
    rightHandOldPos[1] = skel.skeletonPositions[j].y;
    rightHandOldPos[2] = skel.skeletonPositions[1].z;
    startR = true;
  }
  else if (skel.skeletonPositionTrackingState[j] != Kinect.NUI_SKELETON_POSITION_NOT_TRACKED) {
    // Definition de la vitesse de déplacement de la main
    float vectWidth = dist(rightHandOldPos[0], rightHandOldPos[1], skel.skeletonPositions[j].x, skel.skeletonPositions[j].y);
    float vectSpeed = vectWidth * 300;
    // Couleur du remplissage avec valeur de luminosité en fonction de la profondeur
    fill(150, 30, 255 - skel.skeletonPositions[j].z/100);
    ellipse(skel.skeletonPositions[j].x*width, skel.skeletonPositions[j].y*height, vectSpeed, vectSpeed);
    
    // Stockage de l'ancienne position de la main
    rightHandOldPos[0] = skel.skeletonPositions[j].x;
    rightHandOldPos[1] = skel.skeletonPositions[j].y;
    rightHandOldPos[2] = skel.skeletonPositions[j].z;
  }
}

//Function de gestion des evenements liés au suivi du squelette
void appearEvent(SkeletonData skel) 
{
  if (skel.trackingState == Kinect.NUI_SKELETON_NOT_TRACKED) 
  {
    return;
  }
  synchronized(bodies) {
    bodies.add(skel);
  }
}
 
void disappearEvent(SkeletonData skel) 
{
  synchronized(bodies) {
    for (int i=bodies.size ()-1; i>=0; i--) 
    {
      if (skel.dwTrackingID == bodies.get(i).dwTrackingID) 
      {
        bodies.remove(i);
      }
    }
  }
}
 
void moveEvent(SkeletonData _b, SkeletonData _a) 
{
  if (_a.trackingState == Kinect.NUI_SKELETON_NOT_TRACKED) 
  {
    return;
  }
  synchronized(bodies) {
    for (int i=bodies.size()-1; i>=0; i--) 
    {
      if (_b.dwTrackingID == bodies.get(i).dwTrackingID) 
      {
        bodies.get(i).copy(_a);
        break;
      }
    }
  }
}