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

28
我正在尝试使用普通网络摄像头确定骨架关节位置(或者至少可以跟踪单个手掌)。我已经在网上搜索了很久,但似乎找不到方法。
我找到的所有示例都使用Kinect。我想使用单个网络摄像头。
我不需要计算关节的深度-我只需要能够识别它们在画面中的X、Y位置。这就是为什么我使用网络摄像头而不是Kinect。
到目前为止,我已经看过:
OpenCV(其中“skeleton”功能是简化图形模型的过程,但不是人体检测和/或骨架化)。
OpenNI(带有NiTE)-获取关节的唯一方法是使用Kinect设备,因此无法与网络摄像头一起使用。
我正在寻找一个C / C ++库(但这时将考虑任何其他语言),最好是开源的(但是,再次,将考虑任何许可证),它可以执行以下操作:
给定图像(来自网络摄像头的框架),计算可见关节的X、Y位置
【可选】给定视频捕获流,在我的代码中回调事件以获取关节位置
不必非常精确,但最好非常快(每帧处理时间小于0.1秒)
如果有人能帮忙解决这个问题,我真的会非常感激。我已经陷入了几天的困境,找不到明确的解决方案。
更新
两年后找到了解决方案:http://dlib.net/imaging.html#shape_predictor

2
这对于一个单独的网络摄像头来说确实很困难,尤其是在实时情况下。因此有了Kinect。如果你只想追踪一个手掌,你应该能够修改这个实时追踪器来完成任务:http://www4.comp.polyu.edu.hk/~cslzhang/CT/CT.htm。它的效果非常好,他们的C++代码使用了OpenCV。 - Bull
这不是类似于StackOverflow的问题,对吧? - Janusz Lenar
1
如果您能提供更多的上下文信息,那将会很有帮助,这样我们就可以了解为什么绝对不应该涉及Kinect(并且在此上下文范围内可能建议可行的替代方案)。 - Grimace of Despair
既然你正在使用红外相机,我想你的某处应该有红外LED灯吧? - Menelaos
你好,我想问一下你是否已经能够继续进行这个项目了。目前我也在研究骨架化技术,但无法使用OpenNI或其他专门针对Kinect使用的NI库。目前我们已经通过图像处理和数据分析来推进我们的项目,但我更希望能够实现骨架跟踪。 - IBG
显示剩余6条评论
8个回答

19
使用单个没有深度信息的相机跟踪手部是一项艰巨的任务,也是当前科学研究的主题。我可以为你提供关于该主题的一些有趣和/或高引用量的科学论文:
  • M. de La Gorce, D. J. Fleet, and N. Paragios,“基于模型的单目视频3D手部姿态估计”,IEEE图案识别与机器智能交易,第33卷,2011年2月。
  • R. Wang和J. Popović,“带有彩色手套的实时手部跟踪”,ACM图形交易(TOG),2009年。
  • B. Stenger,A. Thayananthan,P. H. S. Torr和R. Cipolla,“使用分层贝叶斯滤波器的基于模型的手部追踪”,IEEE图案识别与机器智能交易,第28卷,第9期,2006年9月,pp. 1372-84。
  • J. M. Rehg和T. Kanade,“基于模型的自遮挡关节物体跟踪”,在IEEE国际计算机视觉会议论文集中,1995年,pp. 612-617。

第二章中有关于手部跟踪文献调查:

  • T. de Campos,“关节物体和手部的3D视觉跟踪”,2006年。

不幸的是,我不知道是否有一些可供免费使用的手部跟踪库。


2
我不需要深度信息 - 只需要相机视野中物体的像素位置(或中心)。 - YePhIcK
据我所知,跟踪一个关节式三维物体,包括其关节位置,通常是通过恢复完整的三维位置和方向来完成的。简单地说,即使您不需要它,也会得到深度信息。 - Matěj Šmíd
您所描述的需要立体视觉,而这并不是我所列出的要求(只有一个网络摄像头)。 - YePhIcK
我本以为所有的论文都是使用单一摄像头的,但一些使用多个摄像头的论文误打进来了。我删掉了其中一个使用多个摄像头的论文,并标注了Campos的博士论文,其中包括可能有用的文献调查。其余的论文都只涉及手部姿势和方向的单视图重建。但是实现将会很困难,而且性能对于你的应用可能不尽如人意。 - Matěj Šmíd
由于目前的限制,我正在寻找一个已实现的、可直接使用的解决方案。 - YePhIcK

9

有一种简单的方法可以使用肤色来检测手部。也许这可以帮助... 您可以在此 YouTube 视频 上查看结果。注意:背景不应包含像木材之类的肤色物品。

以下是代码:

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

Inspired by: https://dev59.com/ZmUq5IYBdhLWcg3wJNHg#14756351

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”的质心。请查看关于形状描述符的opencv文档。

我还没有想出如何制作位于轮廓中间的骨架,但我正在考虑将轮廓“腐蚀”直到成为一条线。在图像处理中,这个过程称为“骨架化”或“形态学骨架”。这是一些关于骨架化的基本信息

这里是一个实现opencv和c ++中的骨架化的链接。

这里是一个opencv和python中的骨架化的链接。

希望能对你有所帮助:)

---编辑----

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

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

谢谢,这很有帮助。不幸的是,它并不适合我的需求——我正在使用近红外波长,预测背景的“颜色”要困难得多。至于骨架化——我已经看过它了(请参见我的最初的帖子),到目前为止,我对将人的轮廓转换成骨架没有好的感觉。那可能只有在我分开双腿和双臂站立时才起作用;) - YePhIcK
nearIR很有趣,但是使用那个光谱范围有特殊的原因吗?我猜普通相机也可以完成任务。另一种选择是在你感兴趣的关节上放置“标记”,然后使用普通相机来检测它们;使用OpenCV可以在检测到的点之间画出一条线。有一些方法可以从单个相机获取三维信息。 - samkhan13
@YePhIcK,关于关节身体部位的更多信息已添加到答案中 :) - samkhan13
你有没有想过使用OpenCV来计算头发数量? - Haresh Chhelana
1
@MattD 阈值的数值最初是从以下网址得到启发的:https://dev59.com/ZmUq5IYBdhLWcg3wJNHg#14756351 - samkhan13
显示剩余4条评论

2
最后我找到了一个解决方案。原来开源项目 dlib 有一个“形状预测器”,一旦正确训练,它可以准确地猜测“姿势”。 “姿势”被宽泛地定义为“您通过一组图像训练它识别的任何姿势”,并用注释的形状从中提取出来进行训练。
dlib网站这里描述了形状预测器。

还有一些预训练模型可供使用,例如我之前使用过一个正面人脸姿态检测器。 - Divij Sehgal
1
一定要先谷歌一下,看看是否已经有现成的模型可以实现你想要的功能。本质上,它只是训练好的特征权重。 - Divij Sehgal

2
最常见的方法可以在以下YouTube视频中看到。http://www.youtube.com/watch?v=xML2S6bvMwI 这种方法不太健壮,因为它往往会在手转动太多时失败(例如;如果相机朝向手侧面或部分弯曲的手)。
如果您不介意使用两个摄像头,可以研究Robert Wang的工作。他目前的公司(3GearSystems)使用这项技术,辅以Kinect,提供跟踪。他最初的论文使用了两个网络摄像头,但跟踪效果要差得多。
王,罗伯特,帕里斯,西尔万和约万波波维奇。 "6d hands:计算机辅助设计的无标记手部跟踪。"第24届年度ACM用户界面软件和技术研讨会。ACM,2011。
另一个选择(如果可能使用“更多”单个网络摄像头),是使用IR发射器。您的手相当好地反射红外光,而背景则没有。通过向过滤普通光的网络摄像头添加滤镜(并删除执行相反操作的标准滤镜),可以创建相当有效的手部跟踪。这种方法的优点是手与背景的分割要简单得多。根据距离和相机的质量,您需要更多的红外LED才能将足够的光反射回网络摄像头。Leap Motion使用此技术来跟踪手指和手掌(它使用2个红外摄像头和3个红外LED还可获取深度信息)。
话虽如此;我认为Kinect是您最好的选择。是的,您不需要深度,但深度信息确实使检测手部(使用深度信息进行分割)变得容易得多。

2
谢谢你的建议,但我特别寻找一个非Kinect的解决方案。非常具体 :) - YePhIcK
1
很不幸,这些并不存在于你所给定的参数之内。 - Nallath
@Nallath Adobe使用面部跟踪和我认为只使用1个网络摄像头进行部分肢体跟踪,用于Adobe Animate。 - B''H Bi'ezras -- Boruch Hashem

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

记住:即使您不需要深度信息,但拥有这些信息可以让图书馆更容易地识别手。

0

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

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


我已经玩了一段时间OpenCV的识别组件,不得不说它们往往相当笨重,准确性也不如我所希望的那样高。尽管到目前为止,这似乎是极少数可行的选择之一...... 它不能满足我所有的需求,但至少在某种程度上接近。 - YePhIcK

0

通过开源Blender项目运动跟踪功能,可以基于2D素材创建3D模型,无需Kinect。由于Blender是开源的,您可能能够在Blender框架之外使用它们的Python脚本来实现自己的目的。


你在这里放的指向YouTube的链接令人惊叹,真是太棒了。但是与我所需的完全无关 :( - YePhIcK
它使用运动结构。它利用每个帧相机与要“扫描”的对象的位置/方向之间的关系来估计深度。 - Nallath
再次强调 - 我不需要深度信息(我会使用另一种方法获取深度信息),我只需要知道在二维图像上我要找的物体“在哪里” :) - YePhIcK

0

你听说过Eyesweb吗?

我在我的一个项目中使用它,认为它可能对你想要实现的目标有用。 这里有一些有趣的出版物 LNAI 3881 - Finger Tracking Methods Using EyesWebPowerpointing-HCI using gestures

基本上工作流程如下:

  1. 在EyesWeb中创建您的补丁
  2. 准备要使用网络客户端发送的数据
  3. 在您自己的服务器(您的应用程序)上使用这些处理过的数据

但是,我不知道是否有一种方法将Eyes Web的实时图像处理部分嵌入软件库中。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接