Accueil > Kinect > Kinect: reconnaissance de la main en 3D

Kinect: reconnaissance de la main en 3D

Dans mon précédent post nous avions utilisé une analyse 2D de la main afin d’enrichir les capacités de gestures. Etudions désormais une analyse 3D.

L’image de profondeur de Kinect renvoie un tableau en x et y de valeurs de profondeur. La méthode SkeletonEngine.SkeletonToDepthImage() du SDK Kinect permet de convertir chacune de ces coordonnées et profondeurs en coordonnées 3D (x,y,z) dans le repère de la caméra (x=0 et y=0 lorsque l’on est dans l’axe de la caméra). On est donc capable relativement facilement de récupérer une collection de points 3D (nuage de points).

Etudions une première problématique qui n’est déjà pas si simple : la recherche de plans.

Si pour l’œil humain il parait évident de reconnaitre lorsqu’une collection de points 3D rassemble à peu près les points d’un même plan, mathématiquement c’est un tout autre problème.

Il existe bon nombre de technologies de reconstruction 3D depuis des images 2D. Ce sont les technologies qui sont utilisées en réalité augmentée ou dans des logiciels tels que Photosynth. Les images 2D n’étant finalement que des collections de points de couleurs, ces algorithmes étudient les variations de couleurs, recherchent à détecter les bordures (ruptures de couleurs) et les lignes de fuite.

Dans l’analyse de nuages de points, nous sommes déjà dans un environnement 3D mais la recherche de surface est tout aussi complexe car il faut déduire les points qui sont potentiellement en « contact », segmenter les zones trouvées et enfin reconstruire les surfaces, rechercher des surfaces pour être plus exact (fitting).

Il existe un excellent projet open source sur le sujet que je vous recommande : http://pointclouds.org/

Vous trouverez également sur le net pas mal de littérature sur le sujet.

Dans notre cas, nous allons simplifier le problème car nous ne cherchons qu’une seule chose, le plan de la main et en plus nous avons un point de vue.

Pour sélectionner uniquement les points de la main, j’ai utilisé la même technique que dans l’article précédent.

La recherche du plan :

Pour simplifier les explications, posons-nous la même problématique en 2D : nous avons un nuage de points 2D à peu près alignés dans le plan et nous recherchons la droite qui représente au mieux cet ensemble.

Il existe une méthode d’approximation qui s’appelle la méthode des moindres carrés. (http://fr.wikipedia.org/wiki/M%C3%A9thode_des_moindres_carr%C3%A9s )

image

Sans trop entrer dans les détails, l’idée est de partir d’une droite quelconque passant par le centre de gravité du nuage de points et de calculer la sommes des écarts au carré de chacun des points par rapport à sa projection sur la droite. Le but est ensuite de minimiser cette valeur pour se rapprocher de la droite idéale.

Le calcul de minimum n’est pas simple car il faut faire une régression linéaire pour y parvenir. Notons que ça se complique bien plus encore si le modèle recherché est plus complexe qu’une droite (système non linéaire) ou si l’on veut définir des pondérations aux différents points.

J’ai adapté ces notions à notre cas et en le simplifiant pour la 3D.

Pour notre main, nous recherchons donc un plan. Pour rappel son équation cartésienne est a.x + b.y + c.z + d = 0.

Géométriquement parlant, un plan est caractérisé par son vecteur normal. L’idée est alors de calculer pour tous les triplets de points adjacents, le vecteur normal du plan qu’ils décrivent et de chercher à minimiser l’écart (l’angle) avec le vecteur normal du plan.

L’usage de Kinect simplifie une chose essentielle : nous avons un point de vue !

En effet, le nuage de points n’est pas juste une collection de points 3D quelconque, nous savons qu’il est issu de la vision d’une caméra. On peut en déduire des informations importantes :

– Il n’y a pas de points non visibles à la caméra (par exemple je ne peux pas avoir de points appartenant à mon dos si je suis face à la caméra).

– La recherche des points « adjacents » est aisée puisqu’il suffit de vérifier qu’ils sont voisins dans l’image de profondeur et que leur écart de profondeur ne dépasse pas un certain seuil.

– Le calcul de chaque plan élémentaire renvoie un vecteur normal qui peut être vers ou opposé à la caméra suivant l’ordre des 3 points choisis (règle de la main droite). Connaissant le point de vue de la caméra, il suffit de changer le signe du vecteur s’il est opposé à la caméra.

J’ai ajouté une petite option à cet algorithme qui est de conserver l’écart type des écarts ! Cela me permet alors de savoir lors du calcul du plan de la main si celle-ci est très à plat ou pas. Je considère même qu’au-delà un certain seuil mon plan n’est pas valide car la main n’est pas assez plate.

Voilà c’est à peu près tout. Au final le calcul est tout de même conséquent mais assez rapide et c’est le prix à payer pour faire une analyse basée sur les informations de profondeur.

Ci-dessous, le résultat en vidéo.

Catégories :Kinect

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s

%d blogueurs aiment cette page :