TraKERS (Tracking using Kinect and Extracting Robust Skeletons) est une interface basée sur la détection de gestures / positions du squelette envoyé par le SDK Microsoft (1.0) de Kinect. Il est composé d'un Middleware assurant l'interaction avec Kinect, un rendu visuel et l'envoi de notifications sous forme de messages OSC. Le deuxième module de ce projet est un Front en Processing doté d'un client TUIO et récupérant les messages OSC (sous forme d'objets tels que des Curseurs ou des Strings).

Ce tutoriel concerne ce second module et a pour but d'expliquer le fonctionnement général d'un sketch Processing et la récupération des notifications du Middleware. Il sera agrémenté d'exemples fonctionnels créés pour les besoins de ce tutoriel ou inspirés d'exemples réels disponibles sur le site processing.org.

1. Installation de Processing
2. Structure d'un sketch
3. Fonctions principales de Processing
4. Récupérer les objets envoyés par le Middleware TraKERS via un Client TUIO
5. Interactions entre les objets TUIO récupérés et des fonctions de dessin basiques
6. Quelques exemples d'implémentation
7. Références

1. Installation de Processing

Avant de pouvoir modifier les sketches Processing fournis dans l'installateur, il est nécessaire d'installer Processing.
Vous trouverez l'archive ici :

Processing pour Windows avec Java
Processing pour Windows sans Java

Une fois téléchargé, il vous suffit de le dézipper, et d'affecter tous les types de fichiers .pde à l'exécutable Processing fourni dans l'archive.

Si ce n'est pas déjà fait, il peut être utile de spécifier dans le path Windows l'emplacement du répertoire où vous avez extrait l'archive.

2. Structure d'un sketch

Un sketch est représenté par un dossier, contenant plusieurs choses :

- Un ou plusieurs fichiers d'extension .pde (Qui contiennent le code Processing). Le .pde principal doit avoir le même nom que le dossier qui les contient.
- Un dossier code, contenant les libraries appelées dans les fichiers .pde.

Si le sketch a été exporté en application, le dossier principal contient également jusqu'à trois dossiers, qui sont :

- application.linux (si l'option Linux a été cochée durant l'export).
- application.macosx (si l'option Mac OS X a été cochée durant l'export).
- application.windows (si l'option Windows a été cochée durant l'export).

Ceux-ci contiennent les applications compilées du code source des fichiers .pde.
Il est également possible d'exporter un applet. On obtiendra donc :

- applet (si l'option Linux a été cochée durant l'export).

Concernant le projet TraKERS, les sketches fournis peuvent contenir différents fichiers .pde (un pour chaque classe), un fichier TuioFunctions.pde permettant de récupérer les objets TUIO envoyés par le Middleware et un fichier principal du même nom que le sketch.

3. Fonctions principales de Processing

En Processing, les variables déclarées absolues (en dehors d'une fonction ou d'une classe) sont visibles dans tous les autres fichiers .pde du sketch. Il en va de même pour les classes et fonctions (et non méthodes de classe, qui est une fonction appartenant à la classe et donc ne pouvant être appelée qu'en créant un objet de cette classe).

Il existe deux fonctions principales, qui sont :

- void setup() : Initialise les différentes variables du sketch.
- void draw() : Fonction rappelée automatiquement, destinée à contenir des instructions de dessin ou des appels de fonctions.

La gestion des événements souris est naturelle, comme l'indique l'exemple ci-dessous:
`public void setup()
{
size(200,200);
background(0);
}
public void draw()
{
stroke(255);
if(mousePressed)
{
line(mouseX,mouseY,pmouseX,pmouseY);
}
}
`

4. Récupérer les objets envoyés par le Middleware TraKERS via un Client TUIO

Les objets TUIO exploités dans le cadre de TraKERS sont de deux types :

- TuioCursor : Les curseurs sont utilisés pour transmettre des points au Front Processing. On récupère leurs coordonnées sous forme de TuioPoint, qui possèdent comme attributs les valeurs du point en X, Y et Z.
- TuioString : Elles comportent une String ayant pour valeur la notification du Middleware en cas de détection de gesture par exemple.

Voici les différentes implémentations permettant d'accéder à ces objets via le client. On appelle dans cet exemple plusieurs fonctions si des curseurs on été reçus par le client.
Un curseur représente une main dans la zone de recherche des mains présente dans le Middleware.
`void tuioInput()
{
Vector tuioCursorList = tuioClient.getTuioCursors();
if(tuioCursorList.size() <= 0)
{
//Code si on ne reçoit pas de curseurs <=> que aucune main n'est dans la zone de recherche des mains.
}
if(tuioCursorList.size() == 1)
{
//Code si une main est détectée.
//Par exemple, on peut faire appel à une fonction qu'on nommera arbitrairement handleOneHand et qui prendra en paramètre le curseur.
handleOneHand(tuioCursorList.elementAt(0));
}
else if(tuioCursorList.size() == 2)
{
//Code si les deux mains sont détectées.
//Par exemple, on peut faire appel à une fonction qu'on nommera arbitrairement handleBothHands et qui prendra en paramètre la liste des curseurs récupérés par le client.
handleBothHands(tuioCursorList);
}
}
` Le code suivant montre comment on peut extraire le point contenu dans le curseur.
`void handleOneHand(TuioCursor handCursor)
{
TuioPoint pt = handCursor.getPosition();//(TuioPoint)pointList.get(j);
//Code manipulant le point.
//Par exemple un affichage de texte.
text(pt.getX() + " " + pt.getY() + " " + pt.getZ());
}
` Le code suivant montre comment on peut extraire les points contenus dans une liste de deux curseurs.
`void handleBothHands(Vector tuioCursorList)
{
TuioCursor handLeftCursor = (TuioCursor)tuioCursorList.elementAt(0);
TuioCursor handRightCursor = (TuioCursor)tuioCursorList.elementAt(1);
TuioPoint pt;
pt = (TuioPoint)handLeftCursor.getPosition();
//Code pour traiter la position de la première main.
//Par exemple un affichage de texte.
text(pt.getX() + " " + pt.getY() + " " + pt.getZ());
pt = (TuioPoint)handRightCursor.getPosition();
//Code pour traiter la position de la seconde main.
//Par exemple un affichage de texte.
text(pt.getX() + " " + pt.getY() + " " + pt.getZ());
}
`

On appelle dans cet exemple une fonction si un message a été reçu par le client.
Un message représente un événement notifié par le Middleware.
`void tuioInput()
{
Vector tuioStringList = tuioClient.getTuioStrings();
if(tuioStringList.size() <= 0)
{
text("Gesture non détectée.");
}
else
{
TuioString message = (TuioString)tuioStringList.elementAt(0);
text(message.getMessage());
}
}
`

5. Interactions entre les objets TUIO récupérés et des fonctions de dessin basiques

Dans les exemples de code vu précédemment, nous aurions pu remplacer la fonction text() par une fonction de votre cru, comme celle-ci :
`//Cette fonction dessine une ellipse à la position (x;y;z) et prend en paramètre la fait qu'il s'agisse de la main droite ou gauche.
void drawEllipse(float x, float y, float z, boolean leftHand)
{
//On met la couleur de ce qui va venir en bleu.
fill(0, 0, 255);
//On ne met pas de bordure à ce qu'on va afficher.
stroke(0,0,0);
//On créer un point, une épaisseur de forme.
//Z est la distance de la main par rapport à Kinect. La zone de recherche des mains est toujours comprise entre minDistHands et maxDistHands
float weight = map(z, minDistHands, maxDistHands, 50, 1);
float redColor = map(z, minDistHands, maxDistHands, 255, 80);
//S'il s'agit de la main gauche, on colore en tons de rouge.
if(leftHand)
fill(redColor,0,0);
//Sinon en tons de vert.
else
fill(0,redColor,0);
//Si le trait est assez gros, on color en tons de bleu.
if(weight >= 30)
{
fill(0, 0, redColor);
}
//On dessine une ellipse.
ellipse(x+20, y+100, weight, weight);
}
`

6. Quelques exemples d'implémentation

Les exemples fournis dans l'installeur sont répartis dans 4 dossiers principaux :

- Trakers : Permet d'afficher des ellipses sur le passage d'une ou deux mains se situant à une certaine distance de Kinect.
- Trakers_gestures : Permet d'afficher le code des gestures détectées par Kinect et notifiées depuis le Middleware.
- Fluid_manipulation (code importé de processing.org) : Simule l'action des mains sur un fluide.
- Smoke_manipulation (code importé de processing.org) : Simule l'action des mains sur de la fumée.
- Interaction examples (code importé de processing.org) : Quelques petits exemples utilisant des formes basiques et réagissant à la position de la main la plus proche de Kinect.

7. Références

Voici quelques liens utiles où se trouvent les dépendances trop lourdes pour être incluses dans cet installeur. Ils vont permettront également d'approfondissant vos connaissances sur Processing ou TUIO. Il vous est possible d'utiliser eclipse pour compiler du Processing.

- SDK Kinect 1.0 de Microsoft
- TUIO
- Processing.org
- Autres exemples en Processing
- Processing sous eclipse