使用网络摄像头确定骨架关节(不是Kinect)

时间:2013-06-15 13:54:22

标签: opencv webcam tracking gesture-recognition human-interface

我正在尝试使用常规网络摄像头确定骨架关节(或者至少能够跟踪单个手掌)。我在网上看了一遍,似乎无法找到办法。

我发现的每个例子都是使用Kinect。我想使用一个网络摄像头。

我不需要计算关节的深度 - 我只需要能够识别它们在框架中的X,Y位置。这就是我使用网络摄像头而不是Kinect的原因。

到目前为止,我已经看过了:

  • OpenCV(其中的“骨架”功能是简化图形模型的过程,但它不是人体的检测和/或骨架化。)
  • OpenNI(使用NiTE) - 获取关节的唯一方法是使用Kinect设备,因此这不适用于网络摄像头。

我正在寻找一个C / C ++库(但此时会查看任何其他语言),最好是开源(但同样会考虑任何许可证),可以执行以下操作:

  • 给定图像(来自网络摄像头的帧)计算可见关节的X,Y位置
  • [可选]鉴于视频捕获流使用关节位置事件回调我的代码
  • 不一定非常准确,但更喜欢它非常快(每帧0.1秒的处理时间)

如果有人可以帮我解决这个问题,我真的很感激。我已经被困在这几天了,没有明确的路径可以继续。

更新

2年后,找到了一个解决方案:http://dlib.net/imaging.html#shape_predictor

8 个答案:

答案 0 :(得分:19)

使用没有深度信息的单个摄像机跟踪手是一项严肃的任务和正在进行的科学工作的主题。我可以为您提供一系列有趣和/或被高度引用的关于该主题的科学论文:

  • 微米。 de La Gorce,D。J. Fleet和N. Paragios,“基于模型的单眼视频3D手姿态估计。”,IEEE关于模式分析和机器智能的交易,第一卷。 33,2011年2月。
  • R上。 Wang和J.Popović,“使用彩色手套进行实时手动跟踪”,ACM Transactions on Graphics(TOG),2009。
  • B中。 Stenger,A。Thayananthan,P。H. S. Torr和R. Cipolla,“基于模型的手动跟踪使用分层贝叶斯过滤器。”,IEEE交易模式分析和机器智能,第一卷。 28,不。 9,pp.1332 - 84,2006年9月。
  • 学家M. Rehg和T. Kanade,“基于模型的自封闭关节对象跟踪”,载于IEEE国际计算机视觉会议论文集,1995年,第612-617页。

第2章中的手部跟踪文献调查:

  • 吨。 de Campos,“关节和物体的三维视觉跟踪”,2006年。

不幸的是,我不知道一些免费提供的手部追踪库。

答案 1 :(得分:7)

有一种使用肤色检测手部的简单方法。也许这可以帮助...你可以在这个youtube video上看到结果。警告:背景不应包含像木头一样的肤色。

这是代码:

''' Detect human skin tone and draw a boundary around it.
Useful for gesture recognition and motion tracking.

Inspired by: http://stackoverflow.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()

cv2.findContour非常有用,你可以在找到轮廓后使用cv2.moments找到“blob”的质心。看看shape descriptors上的opencv文档。

我还没弄明白如何制作位于轮廓中间的骷髅,但我想要“蚀刻”轮廓直到它是一条线。在图像处理过程中,该过程称为“骨架化”或“形态骨架”。这里有一些basic info on skeletonization

这是一个实现skeletonization in opencv and c++

的链接

这是skeletonization in opencv and python

的链接

希望有所帮助:)

---编辑----

我强烈建议您阅读Deva Ramanan撰写的这些文章(访问链接页面后向下滚动):http://www.ics.uci.edu/~dramanan/

  1. ℃。 Desai,D。Ramanan。 “检测动作,姿势和物体 关系短语“欧洲计算机视觉会议” (ECCV),意大利佛罗伦萨,2012年10月。
  2. d。 Park,D。Ramanan。 “部分模型的N最佳最大解码器”国际会议 计算机视觉(ICCV),西班牙巴塞罗那,2011年11月。
  3. d。 Ramanan。 “学习解析关节对象的图像”神经信息。 PROC。 系统(NIPS),加拿大温哥华,2006年12月。

答案 2 :(得分:2)

最常见的方法可以在以下YouTube视频中看到。 http://www.youtube.com/watch?v=xML2S6bvMwI

这种方法不太稳健,因为如果手旋转得太多(例如,如果相机正在看手侧或部分弯曲的手),它往往会失败。

如果你不介意使用两个相机,你可以看看Robert Wang的作品。他目前的公司(3GearSystems)使用这项技术,增加了一个kinect,以提供跟踪。他的原始论文使用了两个网络摄像头,但追踪效果更差

  

Wang,Robert,Sylvain Paris和JovanPopović。 “6d指针:用于计算机辅助设计的无标记手动跟踪。”第24届ACM年度用户界面软件和技术研讨会论文集。 ACM,2011。

另一种选择(如果可以使用“比”更多的“更多”),则使用IR发射器。你的手很好地反射红外光,而背景却没有。通过向网络摄像头添加过滤器来过滤正常光线(并移除相反的标准过滤器),您可以创建一个非常有效的手部跟踪。这种方法的优点是从背景中分割手部要简单得多。根据相机的距离和质量,您需要更多的红外线LED,以便将足够的光线反射回网络摄像头。跳跃动作使用这种技术来跟踪手指和手指。手掌(它使用2个红外摄像头和3个红外LED也可以获得深度信息)。

所有这一切;我认为Kinect是你最好的选择。是的,您不需要深度,但深度信息确实使检测手更容易(使用分割的深度信息)。

答案 3 :(得分:2)

根据你的限制,我的建议是使用这样的东西: http://docs.opencv.org/doc/tutorials/objdetect/cascade_classifier/cascade_classifier.html

以下是使用它进行人脸检测的教程: http://opencv.willowgarage.com/wiki/FaceDetection?highlight=%28facial%29|%28recognition%29

你所描述的问题非常困难,而且我不确定只使用网络摄像头试图这样做是一个合理的计划,但这可能是你最好的选择。如此处所述(http://docs.opencv.org/modules/objdetect/doc/cascade_classification.html?highlight=load#cascadeclassifier-load),您需要使用以下内容训练分类器:

http://docs.opencv.org/doc/user_guide/ug_traincascade.html

请记住:即使您不需要深度信息供您使用,使用此信息也可以让图书馆更容易识别出来。

答案 4 :(得分:2)

最后我找到了解决方案。事实证明,dlib开源项目有一个“形状预测器”,经过适当的训练,完全符合我的需要:它猜测(具有相当令人满意的准确性)“姿势”。 “姿势”被宽松地定义为“无论你训练什么来识别它作为姿势”,通过用一组图像进行训练,并用从中提取的形状进行注释。

described in here

上的形状预测器为dlib's website

答案 5 :(得分:0)

我不知道可能存在的解决方案。如果监督(或半监督)学习是一种选择,训练决策树或神经网络可能已经足够(kinect使用我所听到的随机森林)。在走这条路之前,尽一切可能找到现有的解决方案。获得机器学习正确需要花费大量时间和实验。

OpenCV有机器学习组件,你需要的是训练数据。

答案 6 :(得分:0)

使用开放源motion tracking featuresBlender project,可以基于2D素材创建3D模型。不需要kinect。由于blender是开源的,因此您可以在blender框架之外使用他们的pyton脚本用于您自己的目的。

答案 7 :(得分:0)

你听说过Eyesweb

吗?

我一直在将它用于我的一个项目,虽然它可能对你想要达到的目标有用。 以下是一些有趣的出版物LNAI 3881 - Finger Tracking Methods Using EyesWebPowerpointing-HCI using gestures

基本上工作流程是:

  1. 您在EyesWeb
  2. 中创建补丁
  3. 准备要通过网络客户端发送的数据
  4. 在您自己的服务器(您的应用程序)上使用这些已处理的数据
  5. 但是,我不知道是否有办法将Eyes Web的实时图像处理部分嵌入到软件库中。