[Kinect 2] Utiliser la Camera de Profondeur

Les semaines précédentes, nous avons vu comment utiliser les caméras couleur et infrarouge de la Kinect 2 au travers des API que nous fournis le SDK. L’article qui va suivre sera le dernier dans lequel nous choisirons d’adapter l’exemple consistant à retranscrire les données du flux dans des samples vidéo. Nous allons donc voir comment utiliser les données de la caméra de profondeur ou « Depth Camera » avant d’attaque d’autres aspects du SDK dans les semaines qui suivront.

Afficher le rendu

Comme pour la caméra infrarouge, il suffira donc de remplacer quelques portions de codes par d’autres afin de faire un simple affichage. Pour ouvrir le flux, il faudra utiliser la DepthFrameSource :

using (var reader = sensor.DepthFrameSource.OpenReader())

La ligne suivante permettra d’obtenir la description des frames que renverra la Kinect :

var frameDesc = reader.DepthFrameSource.FrameDescription;

Le type de handler permettant de s’abonner à l’évènement FrameArrived de l’objet reader :

TypedEventHandler<DepthFrameReader, DepthFrameArrivedEventArgs> nextFrameArrived = null;

Pour calculer une intensité à afficher, il est possible de réutiliser les mêmes principes qu’avec la caméra infrarouge, mais le rendu peut manquer de contraste. Microsoft propose dans les samples du SDK une constante qui rendra l’affichage bien plus intéressant pour l’œil humain :

var data = bufferSource[i];
const int MapDepthToByte = 8000 / 256;
byte intensity = (byte)(data / MapDepthToByte);
streamConverted.WriteByte(intensity);
streamConverted.WriteByte(intensity);
streamConverted.WriteByte(intensity);

Identifier une forme

L’une des principales fonctionnalités que je voie à la caméra de profondeur est sa capacité à dégager une forme d’une autre. En effet, la donnée brute qui est retourné correspond à l’éloignement du point (ou du pixel) par rapport au capteur. On peut donc supposer que tous les pixels contigus ayant une valeur proche appartiennent à la même forme.

Une façon de jouer avec cela est de choisir un pixel de référence, comme celui de référence et de n’afficher que les pixels qui ont une valeur proche, en choisissant une couleur unique pour les autres. On verra ainsi une forme ressortir : celle de l’objet se trouve pile au milieu du champs de vision du capteur.

Il faut pour cela modifier un peu la boucle de transformation de la frame pour dégager les informations de coordonnées en abscisses et en ordonnées :

for (var i = 0; i < bufferSource.Length; ++i)

deviendra :

for (var h = 0; h < height; ++h)
{
    for (var w = 0; w < width; ++w)
    {
        var i = (h * width) + w;

où height et width peuvent être obtenue ainsi :

var width = frameDesc.Width;
var height = frameDesc.Height;

Pour obtenir la valeur du pixel du milieu :

var middlePixel = bufferSource[(height / 2 * width) + width / 2];

Dans la boucle for imbriqué, on pourra afficher un carré bleu pour représenter le centre du champs de vision de la Kinect, et un pixel rouge pour tout pixel dont la valeur est trop éloignée de celle du pixel du milieu :

const ushort tolerance = 200;

if (h > height / 2 - 10 && h < height / 2 + 10 &&
    w > width / 2 - 10 && w < width / 2 + 10)
{
    streamConverted.WriteByte(255); // bleu
    streamConverted.WriteByte(0);
    streamConverted.WriteByte(0);
}
else if (data > middlePixel - tolerance && data < middlePixel + tolerance)
{
    const int MapDepthToByte = 8000 / 256;
    byte intensity = (byte)(data / MapDepthToByte);

    streamConverted.WriteByte(intensity);
    streamConverted.WriteByte(intensity);
    streamConverted.WriteByte(intensity);
}
else
{
    streamConverted.WriteByte(0);
    streamConverted.WriteByte(0);
    streamConverted.WriteByte(255); // rouge
}

Voici un exemple de ce que cela peut donner :

depth

On voit clairement que le corps de la personne qui se trouve face à l’objectif ressort.

Nous verrons comment exploiter cela plus précisément dans un prochain article !

Ces billets pourraient aussi vous intéresser

Vous nous direz ?!

Commentaires

comments powered by Disqus