Kinect & Processing

**Qu’est que la Kinect ?

**

La kinect est un périphérique destiné à la console de jeux vidéo Xbox 360 permettant de contrôler des jeux vidéo sans utiliser de manette.

On peut cependant l’utiliser sans la xbox360.

Avantages : la kinect est constituée d’un ensemble de capteurs (capteur de distance, de profondeur, une webcam classique, une webcam infra-rouge pour detecter dans le noir, detection de squelette(s) ) qui sont moins onéreux est plus rapides à mettre en place qu’en réalisant un protoype electronique DIY.

Elle nécessite une alimentation secteur et se branche sur l’ordinateur par prise USB.

Détails et emplacements des différents capteurs de la Kinect

Caractéristiques techniques :

  1. Capteur :
    1. Lentilles détectant la couleur et la profondeur
    2. Micro à reconnaissance vocale
    3. Capteur motorisé pour suivre les déplacements
  2. Champ de vision :
    1. Champ de vision horizontal : 57 degrés
    2. Champ de vision vertical : 43 degrés
    3. Marge de déplacement du capteur : ± 27 degrés
    4. Portée du capteur : 1,2 m – 3,5 m (à partir de 50 cm pour la version Kinect for Windows)
  3. Flux de données :
    1. 320×240 en couleur 16 bits à 30 images/sec
    2. 640×480 en couleur 32 bits à 30 images/sec
    3. Audio 16 bits à 16 kHz
  4. Système de reconnaissance physique :
    1. Jusqu’à 6 personnes et 2 joueurs actifs (4 joueurs actifs avec le SDK 1.0)
    2. 20 articulations par squelette
    3. Application des mouvements des joueurs sur leurs avatars Xbox Live
  5. Audio :
    1. Chat vocal Xbox Live et chat vocal dans les jeux (nécessite un compte Xbox Live Gold)
    2. Suppression de l’écho
    3. Reconnaissance vocale multilingue (pour les français, cette fonction est disponible depuis le 06 décembre 2011 via une MàJ de la Xbox ).

Kinect & Processing

3 bibliothèques externes existent pour relier la Kinect à Processing :

openKinect

Bibliothèque simple mais limitée. L’exemple le plus intéressant est RGB_depth .

Télécharger OpenKinect

 — dLibs

Bibliothèque puissante, mais qui ne fonctionne que sur Windows.

Installation de dLibs

I –
télécharger la bibliothèque : https://github.com/diwi/dLibs
ou
http://www.thomasdiewald.com/processing/libraries/dLibs_freenect/

II –
dézipper et déplacer le dossier dLibs_freenect dans le dossier libraries de Processing.
pour plus d’info : http://wiki.processing.org/w/How_to_Install_a_Contributed_Library

III –
brancher la kinect à l’ordinateur

IV –
installer les pilotes :
(… présents dans le dossier : dLibs_freenect/library/kinect_driver_windows/…)

SimpleOpenNI

Page de la bibliothèque SimpleOpenNI

Page détaillée pour l’installation sur différents systèmes d’exploitation

Bibliothèque plus avancée, multi plateforme (mac osx, windows, linux) et qui permet de faire plus de choses. Pour toutes ces raisons, je vais particulièrement m’y intéresser.

L’installation n’est pas forcément simple pour un novice. Le passage par le terminal peut effrayer. Ça mérite cependant le détour.

Installation SimpleOpenNI sur MAC OS X

Installée et testée sur macosx 10.6 +

I – Télécharger l’installer : lien de téléchargement

II – Dézipper l’installer

III – Installation à partir de Terminal

 

IV – Télécharger la bibliothèque SimpleOpenNI : lien de téléchargement

V – Faire glisser le dossier SimpleOpenNI (contenant les dossiers documentation, examples, library) dans votre dossier libraries.

Installation SimpleOpenNI sur Windows

I – Installation des différents pilotes :

Télécharger le paquet d’installation win64 ou le paquet d’installation win32

Ces paquets contiennent 4 installateurs de pilotes :

nite-win64-1.5.2.21-dev.msi (installation de Nite, modules de gestion et de reconnaissance de détection des mouvements . Complète OpenNI)

openni-win64-1.5.2.23-dev.msi (installation des pilotes openNI : framework opensource permettant les ‘interactions naturelles’)

sensor-win64-5.1.0.41-redist.msi (installateur des pilotes pour la détection de capteurs génériques)

SensorKinect091-Bin-Win64-v5.1.0.25.msi (installateur des pilotes pour la Kinect)

Installer ces pilotes dans cette ordre :

  1. installateur openni
  2. installateur nite
  3. installateur pilotes génériques pour capteurs
  4. installateur pilotes Kinect

Note : il est possible qu’il faille installer JAVA64bits. Il est également possible qu’il faille installer les pilotes 32bits si ça ne fonctionne pas.

II – Installation de la bibliothèque pour Processing

Télécharger la bibliothèque SimpleOpenNI : lien de téléchargement
Faire glisser le dossier SimpleOpenNI (contenant les dossiers documentation, examples, library) dans votre dossier libraries.

Exemples de la bibliothèque

NiteSlider2d

NiteHands

NiteCircle

UserScene3d

User3dOri

UserTest

 

Exemples créés à partir de la bibliothèque

Kinect Experiments

Kinect + Hand Held Icosahedron: Towards an Intelligent Healing Space

Kinect Zeichenmodule

Body Dysmorphic Disorder

Kinect Graffiti™

NITEtracking_Cloth

 

INTEGRARTE ENTREGARTE – kinect experiments

 

Exercice d’exemple de la bibliothèque simpleOpenNI (Hands 3D) commenté

// on importe la bibliothèque SimpleOpenNI
import SimpleOpenNI.*;

// création d'un contexte de captation pour la kinect
//on créée donc un objet SimpleOpenNI appelé 'conetxt'
SimpleOpenNI context;

float        zoomF =0.5f;
float        rotX = radians(180);  // by default rotate the hole scene 180deg around the x-axis, 
// the data from openni comes upside down
float        rotY = radians(0);
boolean      handsTrackFlag = false;
// variable vectorielle qui va nous permettre de
// dessiner le tracé et le point
// quand une main est détectée
PVector      handVec = new PVector();
// déclaration d'une variable de type tableau
//pour stocker les coordonnées des positions
// de la min
ArrayList    handVecList = new ArrayList();
int          handVecListSize = 30;
// declaration d'une varibale de chaine de caractere
// pour afficher le type de mouvement de la main
// détecté par la kinect
String       lastGesture = "";

void setup()
{
  //taille de la scene + activation de l'affichage en 3D (P3D)
  size(1024, 768, P3D); 

  // activation et paramètres de l'objet 'context'
  context = new SimpleOpenNI(this);

  // activer : context.setMirror(true); / désactiver :context.setMirror(false);
  // l'affichage en miroir
  context.setMirror(false);

  // si aucune profondeur n'est détectée 
  if (context.enableDepth() == false)
  {
    // on affiche le message suivant :
    println("Profondeur non activée, la kinect n'est peut être pas connectée !");
    exit();
    return;
  }

  // activation de la détection des mouvements
  context.enableGesture();
  // activation de la détection des mains
  context.enableHands();

  // activation de la détection de certains mouvement de la main
  // activation de la détection de mouvement type 'vague'
  context.addGesture("Wave");
  // activation de la détection de mouvement type 'clic' 
  context.addGesture("Click");
  // activation de la détection de mouvement type 'on lève la main'
  context.addGesture("RaiseHand");

  // réglage de la sensibilité de la detection de la main
  //context.setSmoothingHands(.5);

  smooth();

  perspective(radians(45),
  float(width)/float(height),
  10.0f, 150000.0f);
}

void draw()
{
  // rafraichissement de l'image 
  //capturée par la camera de la kinect
  context.update();

  //arriere plan noir
  background(0);

  // dans la representation générée par processing
  // on place notre point de vue
  translate(width/2, height/2, 0);
  rotateX(rotX);
  rotateY(rotY);
  scale(zoomF);

  // dessin des points blancs de la 'carte 3D'
  int[]   depthMap = context.depthMap();
  // pour accélerer l'affichage, on ne représente 
  // qu'un point blanc sur 3 
  int     steps   = 3;
  int     index;
  PVector realWorldPoint;

  // quand on deplace notre point de vue à l'aide des fleches du clavier
  // on le fait à partir d'un point qui est placé à 1000 de la camera
  translate(0, 0, -1000);

  // couleur des points de profondeur
  stroke(200); 

  // visualisation points 3D
  // a chaque point de profondeur sur la largeur détecté par la kinect
  for (int y=0;y < context.depthHeight();y+=steps)
  {
    // a chaque point de profondeur sur la hauteur détecté par la kinect
    for (int x=0;x < context.depthWidth();x+=steps)
    {
      // 
      index = x + y * context.depthWidth();
      // si 
      if (depthMap[index] &rt; 0)
      { 
        realWorldPoint = context.depthMapRealWorld()[index];
        // on dessine le point en recuperant les positions X, Y, Z
        // délivrés par la kinect
        point(realWorldPoint.x, realWorldPoint.y, realWorldPoint.z);
      }
    }
  } 

  // dessin de la main reconnue
  if (handsTrackFlag)
  {
    pushStyle();

    // couleur du tracé du mouvement de la main (jaune)
    stroke(255, 255, 0, 200);
    // on désactive la couleur de remplissage
    noFill();
    // on active un objet Iterator de la bibliothèque simpleOpenNI
    // qui permet de détecter le mouvement de la main dans le temps
    Iterator itr = handVecList.iterator(); 
    // commencement du dessin du tracé de mouvement
    beginShape();
    while ( itr.hasNext () )
    { 
      // création d'une variable PVector
      // pour le dessin du tracé du mouvment
      PVector p = (PVector) itr.next();
      // récupération des positions x, y, z
      // détectés par la kinect
      // et assignation aux coordonées pour le dessin du tracé
      vertex(p.x, p.y, p.z);
    }
    // fin du dessin du tracé de mouvement
    endShape();   

    // couleur et epaisseur du point rouge de la main
    stroke(255, 0, 0);
    strokeWeight(4);
    // récupération des positions x, y, z
    // détectés par la kinect
    // et assignation aux coordonées pour le dessin du point rouge
    point(handVec.x, handVec.y, handVec.z);
    popStyle();
  }

  // on dessine la camera et son volume de détection
  // (boite jaune)
  //context.drawCamFrustum();
}

// -----------------------------------------------------------------
// evenements et fonctions liés aux mains
// -----------------------------------------------------------------
// création de la detection d'une main par la kinect
void onCreateHands(int handId, PVector pos, float time)
{
  //println("onCreateHands - handId: " + handId + ", pos: " + pos + ", time:" + time);

  handsTrackFlag = true;
  handVec = pos;

  handVecList.clear();
  handVecList.add(pos);
}

// mise à jour de la detection d'une main par la kinect
void onUpdateHands(int handId, PVector pos, float time)
{
  //println("onUpdateHandsCb - handId: " + handId + ", pos: " + pos + ", time:" + time);
  handVec = pos;

  handVecList.add(0, pos);
  if (handVecList.size() &rt;= handVecListSize)
  { // remove the last point 
    handVecList.remove(handVecList.size()-1);
  }
}

// suppression de la detection d'une main par la kinect
void onDestroyHands(int handId, float time)
{
  //println("onDestroyHandsCb - handId: " + handId + ", time:" + time);

  handsTrackFlag = false;
  context.addGesture(lastGesture);
}

// -----------------------------------------------------------------
// evenement de mouvement
// -----------------------------------------------------------------
// reconnaissance de type de mouvements de la main par la kinect
void onRecognizeGesture(String strGesture, PVector idPosition, PVector endPosition)
{
  println("onRecognizeGesture - strGesture: " + strGesture + ", idPosition: " + idPosition + ", endPosition:" + endPosition);

  lastGesture = strGesture;
  context.removeGesture(strGesture); 
  context.startTrackingHands(endPosition);
}

void onProgressGesture(String strGesture, PVector position, float progress)
{
  //println("onProgressGesture - strGesture: " + strGesture + ", position: " + position + ", progress:" + progress);
}

// -----------------------------------------------------------------
// Evenement du clavier
// -----------------------------------------------------------------
void keyPressed()
{
  switch(key)
  {
    // si j'appuie sur la barre espace
    // j'active / je desactive l'affichage en miroir
  case ' ':
    context.setMirror(!context.mirror());
    break;
  }

  switch(keyCode)
  {
    // si j'appuie sur la fleche gauche
    // je deplace mon point de vue vers la gauche
  case LEFT:
    rotY += 0.1f;
    break;
    // si j'appuie sur la fleche droite
    // je deplace mon point de vue vers la droite
  case RIGHT:
    rotY -= 0.1f;
    break;
    // si j'appuie sur la fleche haut
    // je deplace mon point de vue vers le haut
  case UP:
    if (keyEvent.isShiftDown())
      zoomF += 0.01f;
    else
      rotX += 0.1f;
    break;
    // si j'appuie sur la fleche bas
    // je deplace mon point de vue vers le bas
  case DOWN:
    if (keyEvent.isShiftDown())
    {
      zoomF -= 0.01f;
      if (zoomF < 0.01)
        zoomF = 0.01;
    }
    else
      rotX -= 0.1f;
    break;
  }
}

Télécharger le sketch commenté 

Exercice technique

Diriger un objet 3D (sphere) généré par Processing avec la main détectée par la kinect

import processing.opengl.*;

// on importe la bibliothèque SimpleOpenNI
import SimpleOpenNI.*;

// création d'un contexte de captation pour la kinect
//on créée donc un objet SimpleOpenNI appelé 'conetxt'
SimpleOpenNI context;

float        zoomF =0.5f;
float        rotX = radians(180);  // by default rotate the hole scene 180deg around the x-axis, 
// the data from openni comes upside down
float        rotY = radians(0);
boolean      handsTrackFlag = false;
// variable vectorielle qui va nous permettre de
// dessiner le tracé et le point
// quand une main est détectée
PVector      handVec = new PVector();
// déclaration d'une variable de type tableau
//pour stocker les coordonnées des positions
// de la min
ArrayList    handVecList = new ArrayList();
int          handVecListSize = 30;
// declaration d'une varibale de chaine de caractere
// pour afficher le type de mouvement de la main
// détecté par la kinect
String       lastGesture = "";

void setup()
{
  //taille de la scene + activation de l'affichage en 3D (P3D)
  size(1024, 768, OPENGL); 

  // activation et paramètres de l'objet 'context'
  context = new SimpleOpenNI(this);

  // activer : context.setMirror(true); / désactiver :context.setMirror(false);
  // l'affichage en miroir
  context.setMirror(false);

  // si aucune profondeur n'est détectée 
  if (context.enableDepth() == false)
  {
    // on affiche le message suivant :
    println("Profondeur non activée, la kinect n'est peut être pas connectée !");
    exit();
    return;
  }

  // activation de la détection des mouvements
  context.enableGesture();
  // activation de la détection des mains
  context.enableHands();

  // activation de la détection de certains mouvement de la main
  // activation de la détection de mouvement type 'vague'
  context.addGesture("Wave");
  // activation de la détection de mouvement type 'clic' 
  context.addGesture("Click");
  // activation de la détection de mouvement type 'on lève la main'
  context.addGesture("RaiseHand");

  // réglage de la sensibilité de la detection de la main
  //context.setSmoothingHands(.5);

  smooth();

  perspective(radians(45),
  float(width)/float(height),
  10.0f, 150000.0f);

}

void draw()
{
  lights();
  // rafraichissement de l'image 
  //capturée par la camera de la kinect
  context.update();

  //arriere plan noir
  background(0);

  // dans la representation générée par processing
  // on place notre point de vue
  translate(width/2, height/2, 0);
  rotateX(rotX);
  rotateY(rotY);
  scale(zoomF);

  // dessin des points blancs de la 'carte 3D'
  int[]   depthMap = context.depthMap();
  // pour accélerer l'affichage, on ne représente 
  // qu'un point blanc sur 3 
  int     steps   = 3;
  int     index;
  PVector realWorldPoint;

  // quand on deplace notre point de vue à l'aide des fleches du clavier
  // on le fait à partir d'un point qui est placé à 1000 de la camera
  translate(0, 0, -1000);

  // couleur des points de profondeur
  stroke(200); 

  // visualisation points 3D
  // a chaque point de profondeur sur la largeur détecté par la kinect
  for (int y=0;y < context.depthHeight();y+=steps)
  {
    // a chaque point de profondeur sur la hauteur détecté par la kinect
    for (int x=0;x < context.depthWidth();x+=steps)
    {
      // 
      index = x + y * context.depthWidth();
      // si 
      if (depthMap[index] > 0)
      { 
        realWorldPoint = context.depthMapRealWorld()[index];
        // on dessine le point en recuperant les positions X, Y, Z
        // délivrés par la kinect
        point(realWorldPoint.x, realWorldPoint.y, realWorldPoint.z);
      }
    }
  } 

  // dessin de la main reconnue
  if (handsTrackFlag)
  {
    pushStyle();

    // couleur et epaisseur de la sphère qui suit la main
    noStroke();
    fill(255, 0, 255);
    // récupération des positions x, y, z
    // détectés par la kinect
    // et assignation aux coordonées pour le dessin dela sphère
    //point(handVec.x, handVec.y, handVec.z);
    translate(handVec.x-20, handVec.y-20, handVec.z-20);
    //ellipse(x[i], y[i], i, i);
    sphere(20);    

    popStyle();
  }

  // on dessine la camera et son volume de détection
  // (boite jaune)
  //context.drawCamFrustum();
}

// -----------------------------------------------------------------
// evenements et fonctions liés aux mains
// -----------------------------------------------------------------
// création de la detection d'une main par la kinect
void onCreateHands(int handId, PVector pos, float time)
{
  //println("onCreateHands - handId: " + handId + ", pos: " + pos + ", time:" + time);

  handsTrackFlag = true;
  handVec = pos;

  handVecList.clear();
  handVecList.add(pos);
}

// mise à jour de la detection d'une main par la kinect
void onUpdateHands(int handId, PVector pos, float time)
{
  //println("onUpdateHandsCb - handId: " + handId + ", pos: " + pos + ", time:" + time);
  handVec = pos;

  handVecList.add(0, pos);
  if (handVecList.size() >= handVecListSize)
  { // remove the last point 
    handVecList.remove(handVecList.size()-1);
  }
}

// suppression de la detection d'une main par la kinect
void onDestroyHands(int handId, float time)
{
  //println("onDestroyHandsCb - handId: " + handId + ", time:" + time);

  handsTrackFlag = false;
  context.addGesture(lastGesture);
}

// -----------------------------------------------------------------
// evenement de mouvement
// -----------------------------------------------------------------
// reconnaissance de type de mouvements de la main par la kinect
void onRecognizeGesture(String strGesture, PVector idPosition, PVector endPosition)
{
  println("onRecognizeGesture - strGesture: " + strGesture + ", idPosition: " + idPosition + ", endPosition:" + endPosition);

  lastGesture = strGesture;
  context.removeGesture(strGesture); 
  context.startTrackingHands(endPosition);
}

void onProgressGesture(String strGesture, PVector position, float progress)
{
  //println("onProgressGesture - strGesture: " + strGesture + ", position: " + position + ", progress:" + progress);
}

// -----------------------------------------------------------------
// Evenement du clavier
// -----------------------------------------------------------------
void keyPressed()
{
  switch(key)
  {
    // si j'appuie sur la barre espace
    // j'active / je desactive l'affichage en miroir
  case ' ':
    context.setMirror(!context.mirror());
    break;
  }

  switch(keyCode)
  {
    // si j'appuie sur la fleche gauche
    // je deplace mon point de vue vers la gauche
  case LEFT:
    rotY += 0.1f;
    break;
    // si j'appuie sur la fleche droite
    // je deplace mon point de vue vers la droite
  case RIGHT:
    rotY -= 0.1f;
    break;
    // si j'appuie sur la fleche haut
    // je deplace mon point de vue vers le haut
  case UP:
    if (keyEvent.isShiftDown())
      zoomF += 0.01f;
    else
      rotX += 0.1f;
    break;
    // si j'appuie sur la fleche bas
    // je deplace mon point de vue vers le bas
  case DOWN:
    if (keyEvent.isShiftDown())
    {
      zoomF -= 0.01f;
      if (zoomF < 0.01)
        zoomF = 0.01;
    }
    else
      rotX -= 0.1f;
    break;
  }
}

 

Télécharger le sketch

 

Importer un modele 3D et interagir avec lui par la Kinect

Pré requis : avoir un modèle 3D enregistré sous un fichier .obj

Isntallation de le bibliothèque objLoader

 

import processing.opengl.*;
// on importe la bibliothèque obj loader qui nous permet 
// d'importer le fichier .obj
import saito.objloader.*;

// on importe la bibliothèque SimpleOpenNI
import SimpleOpenNI.*;

// création d'un contexte de captation pour la kinect
//on créée donc un objet SimpleOpenNI appelé 'conetxt'
SimpleOpenNI context;

float        zoomF =0.5f;
float        rotX = radians(180);  // by default rotate the hole scene 180deg around the x-axis, 
// the data from openni comes upside down
float        rotY = radians(0);
boolean      handsTrackFlag = false;
// variable vectorielle qui va nous permettre de
// dessiner le tracé et le point
// quand une main est détectée
PVector      handVec = new PVector();
// déclaration d'une variable de type tableau
//pour stocker les coordonnées des positions
// de la min
ArrayList    handVecList = new ArrayList();
int          handVecListSize = 30;
// declaration d'une varibale de chaine de caractere
// pour afficher le type de mouvement de la main
// détecté par la kinect
String       lastGesture = "";

// on créée un objet dans cette bibliotheque
// on le nomme model
OBJModel model;

void setup()
{
  //taille de la scene + activation de l'affichage en 3D (P3D)
  size(1024, 768, OPENGL); 

  // activation et paramètres de l'objet 'context'
  context = new SimpleOpenNI(this);

  // activer : context.setMirror(true); / désactiver :context.setMirror(false);
  // l'affichage en miroir
  context.setMirror(false);

  // si aucune profondeur n'est détectée 
  if (context.enableDepth() == false)
  {
    // on affiche le message suivant :
    println("Profondeur non activée, la kinect n'est peut être pas connectée !");
    exit();
    return;
  }

  // activation de la détection des mouvements
  context.enableGesture();
  // activation de la détection des mains
  context.enableHands();

  // activation de la détection de certains mouvement de la main
  // activation de la détection de mouvement type 'vague'
  context.addGesture("Wave");
  // activation de la détection de mouvement type 'clic' 
  context.addGesture("Click");
  // activation de la détection de mouvement type 'on lève la main'
  context.addGesture("RaiseHand");

  // réglage de la sensibilité de la detection de la main
  //context.setSmoothingHands(.5);

  smooth();

  perspective(radians(45),
  float(width)/float(height),
  10.0f, 150000.0f);

  //on appelle notre objet model
  // et on lui donne ses caracteristiques (le fichier .obj lié...)
  model = new OBJModel(this, "map_ground_path_s.obj", "relative", QUADS);
  // activation mode debug
  // model.enableDebug();

  //on indique l'echelle de notre objet
  model.scale(200);
  //on le déplace au centre de notre scène
  model.translateToCenter();
}

void draw()
{
  lights();
  // rafraichissement de l'image 
  //capturée par la camera de la kinect
  context.update();

  //arriere plan noir
  background(0);

  // dans la representation générée par processing
  // on place notre point de vue
  translate(width/2, height/2, 0);
  rotateX(rotX);
  rotateY(rotY);
  scale(zoomF);

  // dessin des points blancs de la 'carte 3D'
  int[]   depthMap = context.depthMap();
  // pour accélerer l'affichage, on ne représente 
  // qu'un point blanc sur 3 
  int     steps   = 3;
  int     index;
  PVector realWorldPoint;

  // quand on deplace notre point de vue à l'aide des fleches du clavier
  // on le fait à partir d'un point qui est placé à 1000 de la camera
  translate(0, 0, -1000);

  // couleur des points de profondeur
  stroke(200); 

  // visualisation points 3D
  // a chaque point de profondeur sur la largeur détecté par la kinect
  for (int y=0;y < context.depthHeight();y+=steps)
  {
    // a chaque point de profondeur sur la hauteur détecté par la kinect
    for (int x=0;x < context.depthWidth();x+=steps)
    {
      // 
      index = x + y * context.depthWidth();
      // si 
      if (depthMap[index] > 0)
      { 
        realWorldPoint = context.depthMapRealWorld()[index];
        // on dessine le point en recuperant les positions X, Y, Z
        // délivrés par la kinect
        point(realWorldPoint.x, realWorldPoint.y, realWorldPoint.z);
      }
    }
  } 

  // dessin de la main reconnue
  if (handsTrackFlag)
  {
    pushStyle();

    // couleur et epaisseur de la sphère qui suit la main
    noStroke();
    fill(255, 0, 255);
    // récupération des positions x, y, z
    // détectés par la kinect
    // et assignation aux coordonées pour le dessin dela sphère
    //point(handVec.x, handVec.y, handVec.z);
    translate(handVec.x-20, handVec.y-20, handVec.z-20);
    // je fais subir une rotation
    // à mon modele 3D pour qu'il soit affiché
    // dans une position visible et intéressante
    rotateY(1.5);
    rotateZ(1.5);

    //en appliquant la fonction draw à notre objet 'model'
    // on le fait se dessiner
    model.draw(); 

    popStyle();
  }

  // on dessine la camera et son volume de détection
  // (boite jaune)
  //context.drawCamFrustum();
}

// -----------------------------------------------------------------
// evenements et fonctions liés aux mains
// -----------------------------------------------------------------
// création de la detection d'une main par la kinect
void onCreateHands(int handId, PVector pos, float time)
{
  //println("onCreateHands - handId: " + handId + ", pos: " + pos + ", time:" + time);

  handsTrackFlag = true;
  handVec = pos;

  handVecList.clear();
  handVecList.add(pos);
}

// mise à jour de la detection d'une main par la kinect
void onUpdateHands(int handId, PVector pos, float time)
{
  //println("onUpdateHandsCb - handId: " + handId + ", pos: " + pos + ", time:" + time);
  handVec = pos;

  handVecList.add(0, pos);
  if (handVecList.size() >= handVecListSize)
  { // remove the last point 
    handVecList.remove(handVecList.size()-1);
  }
}

// suppression de la detection d'une main par la kinect
void onDestroyHands(int handId, float time)
{
  //println("onDestroyHandsCb - handId: " + handId + ", time:" + time);

  handsTrackFlag = false;
  context.addGesture(lastGesture);
}

// -----------------------------------------------------------------
// evenement de mouvement
// -----------------------------------------------------------------
// reconnaissance de type de mouvements de la main par la kinect
void onRecognizeGesture(String strGesture, PVector idPosition, PVector endPosition)
{
  println("onRecognizeGesture - strGesture: " + strGesture + ", idPosition: " + idPosition + ", endPosition:" + endPosition);

  lastGesture = strGesture;
  context.removeGesture(strGesture); 
  context.startTrackingHands(endPosition);
}

void onProgressGesture(String strGesture, PVector position, float progress)
{
  //println("onProgressGesture - strGesture: " + strGesture + ", position: " + position + ", progress:" + progress);
}

// -----------------------------------------------------------------
// Evenement du clavier
// -----------------------------------------------------------------
void keyPressed()
{
  switch(key)
  {
    // si j'appuie sur la barre espace
    // j'active / je desactive l'affichage en miroir
  case ' ':
    context.setMirror(!context.mirror());
    break;
  }

  switch(keyCode)
  {
    // si j'appuie sur la fleche gauche
    // je deplace mon point de vue vers la gauche
  case LEFT:
    rotY += 0.1f;
    break;
    // si j'appuie sur la fleche droite
    // je deplace mon point de vue vers la droite
  case RIGHT:
    rotY -= 0.1f;
    break;
    // si j'appuie sur la fleche haut
    // je deplace mon point de vue vers le haut
  case UP:
    if (keyEvent.isShiftDown())
      zoomF += 0.01f;
    else
      rotX += 0.1f;
    break;
    // si j'appuie sur la fleche bas
    // je deplace mon point de vue vers le bas
  case DOWN:
    if (keyEvent.isShiftDown())
    {
      zoomF -= 0.01f;
      if (zoomF < 0.01)
        zoomF = 0.01;
    }
    else
      rotX -= 0.1f;
    break;
  }
}

Télécharger le sketch et ses fichiers liés

Pour aller plus loin

Une application la Kinect pour la détection de mouvements et la génération de formes : TUIOKINECT

 

Pour aller plus loin

Une bonne page (en français) expliquant les différents pilotes et possibilités de la Kinect.