2010-12-16 156 views
7

J'ai Kinect et les pilotes pour Windows et MacOSX. Existe-t-il des exemples de reconnaissance de gestes diffusés depuis Kinect à l'aide de l'API OpenCV? J'essaye de réaliser semblable à DaVinci prototype on Xbox Kinect mais dans Windows et MacOSX.Où puis-je apprendre/trouver des exemples de reconnaissance de gestes diffusés à partir de Kinect, en utilisant OpenCV?

+0

Ceci est un problème intéressant. Je pense que vos chances de trouver une solution seront plus grandes si vous cassez le problème, et reconsidérez vos options pour chaque problème. Quelles données prévoyez-vous de sortir de la Kinect? Est-ce juste un flux vidéo que vous devez traiter? Dans ce cas, cela simplifie à un problème général de reconnaissance de geste - susceptible d'être un domaine de recherche assez actif. Ou voulez-vous en quelque sorte profiter du logiciel de reconnaissance gestuelle sur l'appareil? Dans les deux cas, parler aux gars qui ont implémenté la démo dans votre lien serait probablement une bonne étape de départ. – misha

+0

Pouvez-vous fournir la source doe pour cela dans C# il sera d'une grande aide – Rikki

Répondre

-1

Je pense que ce ne sera pas si simple, principalement parce que les données d'image de profondeur de kinect ne sont pas si sensibles. Donc, après une distance de 1m à 1.5m tous les doigts seront fusionnés et donc vous ne serez pas en mesure d'obtenir des contours clairs pour détecter les doigts

+2

À une distance de 1,5 m, je peux toujours voir mes doigts sur mon kinect. Notez également que sur la vidéo partagée par OP, le présentateur est plus proche que cela. Et enfin, comment cela répond-il à la question? –

15

La démo de votre lien ne semble pas utiliser la reconnaissance gestuelle réelle. Il distingue simplement deux positions de mains différentes (ouverte/fermée), ce qui est beaucoup plus facile, et suit la position de la main. Compte tenu de la façon dont il tient ses mains dans la démo (devant le corps, face à la kinect quand elles sont ouvertes), voici probablement ce qu'il fait. Puisque vous n'avez pas précisé la langue que vous utilisez, j'utiliserai les noms des fonctions C dans openCV, mais ils devraient être similaires dans d'autres langues. Je suppose également que vous êtes en mesure d'obtenir la carte de profondeur de la kinect (probablement via une fonction de rappel si vous utilisez libfreenect).

  1. Seuil sur la profondeur pour sélectionner uniquement les points suffisamment proches (les aiguilles). Vous pouvez le faire vous-même ou directement avec openCV pour obtenir une image binaire (cvThreshold() avec CV_THRESH_BINARY). Affichez l'image obtenue après le seuil et ajustez la valeur de seuil en fonction de votre configuration (essayez d'éviter d'être trop proche de la kinect car il y a plus d'interférences dans cette zone).

  2. Obtenez le contour des mains avec cvFindContour()

Cette base. Maintenant que vous avez les contours des mains, en fonction de ce que vous voulez faire, vous pouvez prendre des directions différentes. Si vous voulez juste ne détectent entre la main ouverte et fermée, vous pouvez probablement faire:

  1. Obtenez la coque convexe des mains à l'aide cvConvexHull2()

  2. Obtenir les défauts de convexité en utilisant cvConvexityDefect() sur la les contours et la coque convexe que vous avez avant.

  3. Analyser les défauts de convexité: s'il y a de gros défauts, la main est ouverte (parce que la forme est concave entre les doigts), sinon la main est fermée.

Mais vous pouvez également faire la détection des doigts! C'est ce que j'ai fait la semaine dernière, ça ne demande pas beaucoup d'effort et ça boosterait probablement votre démo! Une façon peu coûteuse mais assez fiable de le faire est:

  1. Approximer les contours de la main avec un polygone. Utilisez cvApproxPoly() sur le contour. Vous devrez ajuster le paramètre de précision pour avoir un polygone aussi simple que possible mais qui ne mélange pas les doigts ensemble (environ 15 devrait être assez bon, mais dessinez-le sur votre image en utilisant cvDrawContours() pour vérifier ce que vous obtenez) .

  2. Analysez le contour pour trouver des angles convexes nets. Vous devrez le faire à la main. C'est la partie la plus délicate, car:

    • Les structures de données utilisées dans openCV peuvent être un peu déroutantes au début. Si vous avez trop de mal avec la structure CvSeq, cvCvtSeqToArray() peut vous aider.
    • Vous pouvez enfin faire des calculs (de base) pour trouver les angles convexes.Rappelez-vous que vous pouvez utiliser un produit scalaire pour déterminer la précision d'un angle et un produit vectoriel pour distinguer les angles convexe et concave.
  3. Ici vous êtes, les angles convexes pointus sont vos doigts!

Ceci est un algorithme simple pour détecter les doigts, mais il existe plusieurs façons de le renforcer. Par exemple, vous pouvez essayer d'appliquer un filtre médian sur la carte de profondeur pour "lisser" tout un peu, ou essayer d'utiliser une approximation de polygone plus précise, puis filtrer le contour pour fusionner les points qui doivent se fermer sur le bout des doigts, etc.

Bonne chance et amusez-vous!

0

mage dest = new Image (this.bitmap.Width, this.bitmap. La taille); CvInvoke.cvThreshold (src, dest, 220, 300, Emgu.CV.CvEnum.THRESH.CV_THRESH_BINARY); Bitmap nem1 = nouveau bitmap (dest.Bitmap); this.bitmap = nem1; Graphiques g = Graphics.FromImage (this.bitmap);

   using (MemStorage storage = new MemStorage()) //allocate storage for contour approximation 
        for (Contour<Point> contours = dest.FindContours(); contours != null; contours = contours.HNext) 
        { 
         g.DrawRectangle(new Pen(new SolidBrush(Color.Green)),contours.BoundingRectangle); 
         // CvInvoke.cvConvexHull2(contours,, Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE, 0); 
         IntPtr seq = CvInvoke.cvConvexHull2(contours,storage.Ptr, Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE, 0); 
         IntPtr defects = CvInvoke.cvConvexityDefects(contours, seq, storage); 
         Seq<Point> tr= contours.GetConvexHull(Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE); 

         Seq<Emgu.CV.Structure.MCvConvexityDefect> te = contours.GetConvexityDefacts(storage, Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE); 
         g.DrawRectangle(new Pen(new SolidBrush(Color.Green)), tr.BoundingRectangle); 
         //g.DrawRectangle(new Pen(new SolidBrush(Color.Green)), te.BoundingRectangle); 

        } 

j'ai fait selon votre algorithme, mais il ne fonctionne pas Qu'est-ce que essorer?