opencv - Determine las articulaciones del esqueleto con una cámara web(no Kinect)
kinect python (8)
¿Alguna vez has oído hablar de Eyesweb
Lo he estado usando para uno de mis proyectos y creo que podría ser útil para lo que quiere lograr. Aquí hay algunas publicaciones interesantes LNAI 3881 - Métodos de seguimiento de dedo usando EyesWeb y Powerpointing-HCI usando gestos
Básicamente, el flujo de trabajo es:
- Usted crea su parche en EyesWeb
- Prepare los datos que desea enviar con un cliente de red
- Utilice estos datos procesados en su propio servidor (su aplicación)
Sin embargo, no sé si hay una forma de integrar la parte del procesamiento de imágenes en tiempo real de Eyes Web en una biblioteca suave.
Estoy tratando de determinar las articulaciones esqueléticas (o al menos poder rastrear una sola palma) usando una cámara web normal . He buscado en toda la web y parece que no puedo encontrar la forma de hacerlo.
Cada ejemplo que he encontrado es usar Kinect. Quiero usar una sola cámara web.
No es necesario que calcule la profundidad de las juntas, solo necesito reconocer su posición X, Y en el marco. Por eso estoy usando una cámara web, no un Kinect.
Hasta ahora he visto:
- OpenCV (la funcionalidad "esqueleto" en él es un proceso de simplificación de modelos gráficos, pero no es una detección y / o esqueletización de un cuerpo humano).
- OpenNI (con NiTE): la única forma de obtener las articulaciones es usar el dispositivo Kinect, por lo que esto no funciona con una cámara web.
Estoy buscando una biblioteca de C / C ++ (pero en este momento miraría cualquier otro idioma), preferiblemente de código abierto (pero, de nuevo, considerará cualquier licencia) que pueda hacer lo siguiente:
- Dada una imagen (un cuadro de una cámara web) calcule las posiciones X, Y de las uniones visibles
- [Opcional] Dado un flujo de captura de video, vuelva a llamar a mi código con eventos para posiciones de articulaciones
- No tiene que ser súper preciso, pero preferiría que fuera muy rápido (tiempo de procesamiento de menos de 0.1 segundos por cuadro)
Realmente apreciaría si alguien puede ayudarme con esto. Estuve atascado en esto por unos días sin un camino claro para proceder.
ACTUALIZAR
2 años después se encontró una solución: http://dlib.net/imaging.html#shape_predictor
Con las características de seguimiento de movimiento del proyecto Blender de código abierto, es posible crear un modelo 3D basado en material de archivo 2D. No se necesita kinect Dado que blender es de código abierto, es posible que pueda utilizar sus scripts de pyton fuera del marco de blender para sus propios fines.
El enfoque más común se puede ver en el siguiente video de youtube. http://www.youtube.com/watch?v=xML2S6bvMwI
Este método no es bastante robusto, ya que tiende a fallar si se gira la mano demasiado (por ejemplo, si la cámara mira hacia un lado de la mano o hacia una mano parcialmente doblada).
Si no te importa usar dos cámaras, puedes mirar el trabajo de Robert Wang. Su compañía actual ( 3GearSystems ) usa esta tecnología, aumentada con un kinect, para proporcionar seguimiento. Su documento original usa dos cámaras web pero tiene un seguimiento mucho peor.
Wang, Robert, Sylvain Paris y Jovan Popović. "6d manos: seguimiento de mano sin marcador para diseño asistido por computadora". Actas del 24º simposio anual de ACM sobre software y tecnología de interfaz de usuario. ACM, 2011.
Otra opción (de nuevo si es posible usar "más" que una sola cámara web es posible), es usar un emisor IR. Su mano refleja la luz IR bastante bien mientras que el fondo no. Al agregar un filtro a la cámara web que filtra la luz normal (y eliminando el filtro estándar que hace lo contrario) puede crear un seguimiento de la mano bastante efectivo. La ventaja de este método es que la segmentación de la mano desde el fondo es mucho más simple. Dependiendo de la distancia y la calidad de la cámara, necesitaría más leds IR para reflejar la luz suficiente en la cámara web. El movimiento de salto utiliza esta tecnología para seguir los dedos y las palmas (utiliza 2 cámaras IR y 3 LED IR para obtener también información de profundidad).
Todo eso dicho; Creo que el Kinect es tu mejor opción en esto. Sí, no necesita la profundidad, pero la información de profundidad hace que sea mucho más fácil detectar la mano (usando la información de profundidad para la segmentación).
Mi sugerencia, dadas tus limitaciones, sería usar algo como esto: http://docs.opencv.org/doc/tutorials/objdetect/cascade_classifier/cascade_classifier.html
Aquí hay un tutorial para usarlo para la detección de rostros: http://opencv.willowgarage.com/wiki/FaceDetection?highlight=%28facial%29|%28recognition%29
El problema que ha descrito es bastante difícil, y no estoy seguro de que tratar de hacerlo utilizando solo una cámara web sea un plan razonable, pero esta es probablemente su mejor opción. Como se explica aquí ( http://docs.opencv.org/modules/objdetect/doc/cascade_classification.html?highlight=load#cascadeclassifier-load ), tendrá que entrenar al clasificador con algo como esto:
http://docs.opencv.org/doc/user_guide/ug_traincascade.html
Recuerde: aunque no requiera la información de profundidad para su uso, tener esta información hace que sea más fácil para la biblioteca identificar una mano.
No sé sobre posibles soluciones existentes. Si el aprendizaje supervisado (o semi-supervisado) es una opción, los árboles de decisión de capacitación o las redes neuronales ya pueden ser suficientes (kinect usa bosques aleatorios a partir de lo que he escuchado). Antes de seguir ese camino, haga todo lo posible para encontrar una solución existente. Hacer que el Machine Learning funcione correctamente requiere mucho tiempo y experimentación.
OpenCV tiene componentes de aprendizaje automático, lo que necesitaría son datos de entrenamiento.
Por fin he encontrado una solución. Resulta que un proyecto de código abierto dlib
tiene un "predictor de forma" que, una vez entrenado adecuadamente, hace exactamente lo que necesito: estima (con una precisión bastante satisfactoria) la "pose". Una "pose" se define vagamente como "lo que entrenas para reconocer como una pose" entrenando con un conjunto de imágenes, anotadas con las formas para extraerlas.
El predictor de forma se http://dlib.net/imaging.html#shape_predictor en el sitio web de dlib
Seguir una mano usando una sola cámara sin información de profundidad es una tarea seria y un tema de trabajo científico en curso. Puedo proporcionarle un grupo de artículos científicos interesantes y / o altamente citados sobre el tema:
- M. de La Gorce, DJ Fleet y N. Paragios, "Estimación de la postura de la mano 3D basada en modelos de Monocular Video.", Transacciones IEEE sobre análisis de patrones e inteligencia artificial, vol. 33, febrero de 2011.
- R. Wang y J. Popović, "Seguimiento de mano en tiempo real con un guante de color", ACM Transactions on Graphics (TOG), 2009.
- B. Stenger, A. Thayananthan, PHS Torr, y R. Cipolla, "Seguimiento de mano basado en modelo utilizando un filtro Bayesiano jerárquico.", Transacciones IEEE en análisis de patrones e inteligencia de máquina, vol. 28, no. 9, pp. 1372-84, septiembre de 2006.
- JM Rehg y T. Kanade, "Seguimiento basado en modelos de objetos articulados auto-oclusivos", en Proceedings of IEEE International Conference on Computer Vision, 1995, págs. 612-617.
Seguimiento manual de la literatura en el segundo capítulo:
- T. de Campos, "Seguimiento visual 3D de objetos y manos articulados", 2006.
Lamentablemente, no conozco ninguna biblioteca de rastreo de manos disponible gratuitamente.
hay una forma simple de detectar la mano usando el tono de la piel. quizás esto podría ayudar ... puede ver los resultados en este video youtube. advertencia: el fondo no debe contener cosas de color de piel como la madera.
aquí está el código:
'''''' Detect human skin tone and draw a boundary around it.
Useful for gesture recognition and motion tracking.
Inspired by: http://.com/a/14756351/1463143
Date: 08 June 2013
''''''
# Required moduls
import cv2
import numpy
# Constants for finding range of skin color in YCrCb
min_YCrCb = numpy.array([0,133,77],numpy.uint8)
max_YCrCb = numpy.array([255,173,127],numpy.uint8)
# Create a window to display the camera feed
cv2.namedWindow(''Camera Output'')
# Get pointer to video frames from primary device
videoFrame = cv2.VideoCapture(0)
# Process the video frames
keyPressed = -1 # -1 indicates no key pressed
while(keyPressed < 0): # any key pressed has a value >= 0
# Grab video frame, decode it and return next video frame
readSucsess, sourceImage = videoFrame.read()
# Convert image to YCrCb
imageYCrCb = cv2.cvtColor(sourceImage,cv2.COLOR_BGR2YCR_CB)
# Find region with skin tone in YCrCb image
skinRegion = cv2.inRange(imageYCrCb,min_YCrCb,max_YCrCb)
# Do contour detection on skin region
contours, hierarchy = cv2.findContours(skinRegion, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# Draw the contour on the source image
for i, c in enumerate(contours):
area = cv2.contourArea(c)
if area > 1000:
cv2.drawContours(sourceImage, contours, i, (0, 255, 0), 3)
# Display the source image
cv2.imshow(''Camera Output'',sourceImage)
# Check for user input to close program
keyPressed = cv2.waitKey(1) # wait 1 milisecond in each iteration of while loop
# Close window and camera after exiting the while loop
cv2.destroyWindow(''Camera Output'')
videoFrame.release()
el cv2.findContour es bastante útil, puedes encontrar el centroide de un "blob" usando cv2.moments después de encontrar los contornos. eche un vistazo a la documentación de opencv sobre los descriptores de formas .
Todavía no he descubierto cómo hacer los esqueletos que se encuentran en el medio del contorno, pero estaba pensando en "erosionar" los contornos hasta que sea una sola línea. en el procesamiento de imágenes, el proceso se denomina "esqueletización" o "esqueleto morfológico". aquí hay información básica sobre esqueletización .
aquí hay un enlace que implementa la esqueletización en opencv y c ++
aquí hay un enlace para skeletonization en opencv y python
Espero que ayude :)
--- EDITAR ----
Le recomiendo que revise estos documentos de Deva Ramanan (desplácese hacia abajo después de visitar la página enlazada): http://www.ics.uci.edu/~dramanan/
- C. Desai, D. Ramanan. "Detección de acciones, poses y objetos con frases relacionales" Conferencia Europea sobre Visión por Computador (ECCV), Florencia, Italia, octubre de 2012.
- D. Park, D. Ramanan. "N-Mejores decodificadores máximos para modelos de piezas" Conferencia internacional sobre visión artificial (ICCV) Barcelona, España, noviembre de 2011.
- D. Ramanan. "Aprendiendo a analizar imágenes de objetos articulados" Información neuronal. Proc. Systems (NIPS), Vancouver, Canadá, diciembre de 2006.