2010-12-16 14 views
7

Tengo Kinect y controladores para Windows y MacOSX. ¿Hay algún ejemplo de reconocimiento de gestos transmitido desde Kinect utilizando OpenCV API? Estoy tratando de lograr algo similar a DaVinci prototype on Xbox Kinect pero en Windows y MacOSX.¿Dónde puedo aprender/encontrar ejemplos de reconocimientos gestuales transmitidos desde Kinect, usando OpenCV?

+0

Este es un problema interesante. Creo que las posibilidades de encontrar una solución serán mayores si se rompe el problema y se reconsideran las opciones para cada problema. ¿Qué datos espera obtener del Kinect? ¿Es solo un flujo de video que debes procesar? En este caso, esto se simplifica a un problema general de reconocimiento de gestos, que probablemente sea un área de investigación bastante activa. ¿O de alguna manera desea aprovechar el software de reconocimiento de gestos en el dispositivo? En cualquier caso, hablar con los chicos que implementaron la demostración en tu enlace probablemente sería un buen paso inicial. – misha

+0

¿Puede proporcionar la fuente de origen en C# ? Será de gran ayuda – Rikki

Respuesta

-1

Creo que no será así de simple, principalmente porque los datos de la imagen de profundidad de kinect no son tan sensibles. Entonces, después de una distancia de 1m a 1.5m, todos los dedos se fusionarán y, por lo tanto, no podrá obtener contornos claros para detectar los dedos

+2

A una distancia de 1.5m aún puedo ver mis dedos en mi kinect. También tenga en cuenta que en el video compartido por OP el presentador está más cerca que eso. Y finalmente, ¿cómo responde eso a la pregunta? –

15

La demostración de su enlace no parece utilizar gesto reconocimiento real. Simplemente distingue entre dos posiciones diferentes de la mano (abierta/cerrada), que es mucho más fácil, y rastrea la posición de la mano. Dada la forma en que sostiene sus manos en la demostración (frente al cuerpo, mirando al cine cuando están abiertas), probablemente esto sea lo que está haciendo. Como no precisó qué idioma está usando, usaré los nombres de las funciones C en openCV, pero deberían ser similares en otros idiomas. También supondré que puedes obtener el mapa de profundidad del kinect (probablemente a través de una función de devolución de llamada si usas libfreenect).

  1. Umbral de la profundidad para seleccionar sólo los puntos lo suficientemente cerca (las manos). Puede lograrlo usted mismo o directamente usando openCV para obtener una imagen binaria (cvThreshold() con CV_THRESH_BINARY). Muestra la imagen que obtienes después del umbral y ajusta el valor del umbral para que se ajuste a tu configuración (trata de evitar estar demasiado cerca del cinemático ya que hay más interferencia en esta área).

  2. Consigue el contorno de las manos con cvFindContour()

Este

la base. Ahora que tienes los contornos de las manos, dependiendo de lo que quieras hacer, puedes tomar diferentes direcciones. Si lo que desea es no detectar entre la mano abierta y cerrada, es probable que pueda hacer:

  1. Consigue la envolvente convexa de las manos usando cvConvexHull2()

  2. Obtener los defectos de convexidad usando cvConvexityDefect() en el contornos y el casco convexo que obtuviste antes.

  3. Analice los defectos de convexidad: si hay defectos grandes, la mano está abierta (porque la forma es cóncava entre los dedos), si no la mano está cerrada.

¡Pero también podría hacer la detección de los dedos! Eso es lo que hice la semana pasada, que no requiere mucho más esfuerzo y ¡probablemente impulsaría tu demo! Una forma barata pero bastante confiable de hacerlo es:

  1. Aproximar los contornos de las manos con un polígono. Use cvApproxPoly() en el contorno. Tendrás que ajustar el parámetro de precisión para tener un polígono lo más simple posible pero que no combine los dedos (alrededor de 15 debería ser bastante bueno, pero dibuja sobre tu imagen usando cvDrawContours() para verificar lo que obtienes) .

  2. Analice el contorno para encontrar ángulos convexos nítidos. Tendrás que hacer eso a mano. Esta es la parte más complicada, porque:

    • Las estructuras de datos utilizadas en openCV pueden ser un poco confusas al principio. Si lucha demasiado con la estructura CvSeq, cvCvtSeqToArray() podría ayudar.
    • Finalmente puedes hacer algunos cálculos (básicos) para encontrar los ángulos convexos.Recuerde que puede usar un producto de puntos para determinar qué tan nítido es un ángulo y un producto vectorial para distinguir entre ángulos convexos y cóncavos.
  3. ¡Aquí está, los ángulos convexos agudos son su alcance!

Este es un algoritmo simple para detectar los dedos, pero hay muchas maneras de aumentarlo. Por ejemplo, puede intentar aplicar un filtro de mediana en el mapa de profundidad para "suavizar" un poco todo, o tratar de usar una aproximación de polígono más precisa, pero luego filtrar el contorno para combinar los puntos que se van a cerrar en las puntas de los dedos, etc.

¡Buena suerte y diviértete!

0

mage dest = new Image (this.bitmap.Width, this.bitmap. Altura); CvInvoke.cvThreshold (src, dest, 220, 300, Emgu.CV.CvEnum.THRESH.CV_THRESH_BINARY); Bitmap nem1 = new Bitmap (dest.Bitmap); this.bitmap = nem1; Gráficos 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); 

        } 

lo hice como por su algoritmo, pero no funciona Lo que se retuercen?

Cuestiones relacionadas