kinect-depth-featured

Kinect + Processing : image des profondeurs (depthImage)

Nous allons, dans cet article, nous inté­res­ser à la fonc­tion dep­thI­mage de la Kinect.

Pré-requis

Ins­tal­ler la biblio­thèque OpenNI

Des­crip­tion

Exemple d'ime de profondeur (depth image)

Exemple d’image de pro­fon­deur (depth image)

La Kinect uti­lise un pro­jec­teur et une camera infra­rouge pour pro­duire une image repré­sen­tant les dif­fé­rentes pro­fon­deurs de la scène qu’elle capte. Contrai­re­ment à une camera clas­sique, où les images enre­gistrent la cou­leur de chaque pixel capté, l’image des pro­fon­deurs déli­vrée par la Kinect enre­gistre la dis­tance entre les dif­fé­rentes par­tie de la scène et la Kinect. En regar­dant l’image des pro­fon­deurs, on l’interprète comme une image en noir et blanc dis­tor­due. Elle semble étrange parce que la cou­leur des dif­fé­rentes par­ties de l’image n’indiquent pas à quel point les objets sont lumi­neux, mais à quelle dis­tance ils sont. Les par­ties les plus claires indiquent les objets proches, les plus sombres les plus loin­tains. Ce type d’image faci­lite l’interprétation d’une scène à un ordinateur.

Ces valeurs de pro­fon­deur en noir et blanc cor­res­pon­dant à la dis­tance des objets dans l’espace, elles sont plus pra­tiques pour déter­mi­ner où un objet com­mence, où il se ter­mine, où se trouvent les utilisateurs.

La manière dont l’image des pro­fon­deurs est géné­rée (cf Expli­ca­tion tech­nique) per­met de s’abstraire des condi­tions d’éclairage de la scène cap­tée. Que la salle soit éclai­rée ou non, les mêmes infor­ma­tions de pro­fon­deurs seront déli­vrées. Ce qui rend ces images beau­coup plus stables et facile à trai­ter par le cal­cul. Tout cela per­met, par exemple, de cap­ter un usa­ger et d’en iso­ler la posi­tion dans l’espace.

Expli­ca­tion technique

kinect-IR

1 – Pro­jec­teur infra­rouge 2 – Camera infrarouge

Le secret de la kinect est son “troi­sième œil”. Les 2 cercles cen­traux de la Kinect sont des came­ras, celui qui est plus excen­tré est en fait un pro­jec­teur infra­rouge. La lumière infra­rouge a une lon­gueur d’onde qui ne la rend pas per­cep­tible pour l’œil humain. Le pro­jec­teur infra­rouge de la Kinect pro­jette une grille de points lumi­neux sur toute la scène en face de lui. Même si ces points nous sont invi­sibles, ils peuvent être détec­tés grâce à une caméra infra­rouge, ce dont dis­pose éga­le­ment la Kinect.

Grille de points lumineux créés par le projecteur infrarouge

Grille de points lumi­neux créés par le pro­jec­teur infrarouge

Pratique

Exemple 1 : accé­der à l’image de pro­fon­deur de la Kinect

Capture d’écran 2013-12-30 à 20.49.13

// importation de la bibliothèque externe SimpleOpenNI
import SimpleOpenNI.*;
// declaration de l'objet SimpleOpenNI nommé context
SimpleOpenNI context;

void setup() {
  // initialisation de l'objet SimpleOpenNI nommé context
  context = new SimpleOpenNI(this);
  // initialisation de la vue profondeur
  context.enableDepth();
  // dimensions de la scene, identiques à celles de l'image délivrée par la Kinect
  size(context.depthWidth(), context.depthHeight());

  // si la Kinect ne fonctionne pas correctement (si la led verte de la kinect ne clignote pas), …
  if (!context.enableScene()) {
    // … on indique dans la console de Processing que la kinect n'est pas branchée
    println("Kinect not connected!");
    // et on sort du programme
    exit();
  } 
  // si ça fonctionne…
  else {
    //… on met l'image de la kinect en mirroir
    context.setMirror(true);
  }
}

void draw() {
  // On met à jour l'objet nommé context à chaque execution de la boucle draw()
  context.update();
  // on affiche l'image profondeur
  image(context.depthImage(), 0, 0);
}

Télé­char­ger le sketch

Exemple 2 : accé­der au point le plus proche de la scène

Capture-2014-01-08 à 13.22.15

// importation de la bibliothèque externe SimpleOpenNI
import SimpleOpenNI.*;
// declaration de l'objet SimpleOpenNI nommé context
SimpleOpenNI context;

//création de varible pour pouvoir récupérer 
// la valeur de plusieurs informations
int valeurPlusProche; 
int valeurXPlusProche;
int valeurYPlusProche;
int valeurProfondeurActuelle;

void setup()
{
  // dimensions de l'applet
  size(640, 480);
  // initialisation de l'objet SimpleOpenNI nommé context
  context = new SimpleOpenNI(this);
  // initialisation de la vue profondeur
  context.enableDepth();
}
void draw() {
  valeurPlusProche = 8000; 
  // initialisation de la vue profondeur
  context.update();
  // obtenir le tableau contenant toutes les valeurs de distances de l'image
  // création d'un tableau de nombres entier nommé valeursProfondeurs
  int[] valeursProfondeurs = context.depthMap();
  // pour chaque ligne du tableau des valeurs de l'image
  for (int y = 0; y < 480; y++) { 
    // analyser chaque pixel de la ligne
    for (int x = 0; x < 640; x++) { 

// stocker la valeur du pixel dans la case du tableau correspondante
      int i = x + y * 640; 
      //
      valeurProfondeurActuelle = valeursProfondeurs[i];
      // si ce pixel est le plus proche comparativement à tous ceux analysés
      if (valeurProfondeurActuelle > 0 && valeurProfondeurActuelle < valeurPlusProche) { 
        //on stocke sa valeur comme étant celle la plus proche
        valeurPlusProche = valeurProfondeurActuelle;
        // et on stocke ses coordonnées X et Y dans les variables valeurXPlusProche et valeurYPlusProche
        valeurXPlusProche = x;
        valeurYPlusProche = y;
      }
    }
  }
  //affichage de l'image des profondeurs à l'écran
  image(context.depthImage(), 0, 0);
  //dessin d'une ellipse rouge positionnée 
  // au coordonnées les plus proches (valeurXPlusProche et valeurYPlusProche)
  // que nous avons sauvegardé auparavant
  fill(255, 0, 0);
  ellipse(valeurXPlusProche, valeurYPlusProche, 25, 25);
}

Télé­char­ger le sketch

0