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

Posted

技术标签:

【中文标题】使用网络摄像头(不是 Kinect)确定骨骼关节【英文标题】:Determine skeleton joints with a webcam (not Kinect) 【发布时间】:2013-06-12 00:59:11 【问题描述】:

我正在尝试使用常规网络摄像头来确定骨骼关节(或至少能够追踪单个手掌)。我浏览了整个网络,似乎找不到这样做的方法。

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

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

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

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

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

给定一张图像(来自网络摄像头的一帧),计算可见关节的 X、Y 位置 [可选] 给定一个视频捕获流回调到我的代码中,其中包含关节位置的事件 不必非常精确,但希望它非常快(每帧处理时间不到 0.1 秒)

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

更新

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

【问题讨论】:

这对于单个网络摄像头来说真的很困难,在实时情况下更是如此。因此,Kinect。要仅跟踪单个手掌,您应该能够修改此实时跟踪器来完成这项工作:www4.comp.polyu.edu.hk/~cslzhang/CT/CT.htm。 IT 工作得非常好,他们的 C++ 代码使用 OpenCV。 这不是 *** 之类的问题,是吗? 如果你能提供更多的上下文会有所帮助,所以我们知道为什么它绝对不应该涉及 Kinect(并且可能会在这个上下文的范围内提出一个可行的替代方案) 既然您使用的是红外摄像机,我想您在某处有红外 LED? 您好,我只是想问一下您是否能够继续执行此操作。目前我也在研究骨架化,但不能使用 OpenNI 或任何其他针对 Kinect 使用的 NI 库。目前,我们已经能够使用基于收集到的数据的图像处理和分析来继续我们的项目,但我宁愿继续进行骨骼跟踪。 【参考方案1】:

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

M. de La Gorce、D. J. Fleet 和 N. Paragios,“来自单目视频的基于模型的 3D 手部姿势估计”,IEEE 模式分析和机器智能交易,卷。 2011 年 2 月 33 日。 R. Wang 和 J. Popović,“使用彩色手套进行实时手部跟踪”,ACM Transactions on Graphics (TOG),2009 年。 乙。 Stenger, A. Thayananthan, P. H. S. Torr 和 R. Cipolla,“使用分层贝叶斯滤波器的基于模型的手部跟踪”,IEEE 模式分析和机器智能交易,第一卷。 28,没有。 9,第 1372-84 页,2006 年 9 月。 J. M. Rehg 和 T. Kanade,“基于模型的自遮挡铰接对象跟踪”,载于 IEEE 计算机视觉国际会议论文集,1995 年,第 612-617 页。

第2章手部追踪文献调查:

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

很遗憾,我不知道一些免费提供的手部跟踪库。

【讨论】:

我不需要深度信息 - 只需要相机视图中对象的像素位置(或中心)。 跟踪一个铰接的 3D 对象,包括其关节的位置,据我所知,通常通过恢复完整的 3D 位置和方向来完成。即使您不需要它,您也可以轻松获得深度。 您所描述的需要立体视觉,这不是我在要求中列出的(单个网络摄像头) 我以为他们都在使用单相机,但是一些多相机的论文错误地通过了。我删除了一个使用多个相机的论文,并标记了 Campos 的论文,其中包括可能有用的文献调查。其余的实际上是手姿势和方向的单视图重建。但是实现起来会很困难,而且性能可能对您的应用程序不满意。 由于当前的限制,我正在寻找一个现成的已实施解决方案【参考方案2】:

有一种使用肤色检测手的简单方法。也许这会有所帮助......你可以在这个 youtube video 上看到结果。警告:背景不应该包含皮肤颜色的东西,比如木头。

代码如下:

''' 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()

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/

    C.德赛,D.拉马南。 “检测动作、姿势和物体 关系短语”欧洲计算机视觉会议 (ECCV),意大利佛罗伦萨,2012 年 10 月。 D.公园,D.拉马南。 “N-Best Maximal Decoders for Part Models”国际会议 关于计算机视觉 (ICCV),西班牙巴塞罗那,2011 年 11 月。 D.拉马南。 “学习解析关节物体的图像”神经信息。过程。 Systems (NIPS),加拿大温哥华,2006 年 12 月。

【讨论】:

谢谢,这很有帮助。不幸的是,它不能满足我的需求——我使用的是近红外波长,预测背景的“颜色”要困难得多。至于骨架化——我已经看过它(见我最初的帖子),到目前为止,我对将人体轮廓翻译成骨架的感觉并不好。这可能只有在我双腿张开站立时才有效;) nearIR 很有趣,但使用该光谱范围是否有特殊原因?我怀疑一台普通的相机应该可以完成这项工作。另一种方法是在您感兴趣的关节上放置“标记”并使用典型的相机来检测它们;使用opencv,您可以在检测到的点之间画一条线。有办法获取3d information from single camera。 @YePhIcK 更多关于铰接身体部位的信息已添加到答案中:) 类型是相机,颜色信息很重要。应将您使用的近红外波长相机添加到原始问题中。 @MattD 阈值的最初灵感来自:***.com/a/14756351/1463143【参考方案3】:

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

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

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

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

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

说了这么多;我认为 Kinect 是你最好的选择。是的,您不需要深度,但深度信息确实使检测手变得容易得多(使用深度信息进行分割)。

【讨论】:

感谢您的建议,但我特意寻找非 Kinect 的解决方案。非常具体:) 很遗憾,这些在您提供的参数中不存在。 @Nallath adobe 使用面部跟踪,我很确定只使用 1 个网络摄像头进行部分肢体跟踪用于 adobe 动画我很确定【参考方案4】:

鉴于您的限制,我的建议是使用如下内容: 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

请记住:即使您不需要使用深度信息,但拥有这些信息会使图书馆更容易识别手牌。

【讨论】:

【参考方案5】:

我终于找到了解决办法。原来dlib 开源项目有一个“形状预测器”,一旦经过适当的训练,它就完全符合我的需要:它猜测(以相当令人满意的准确度)“姿势”。 “姿势”被粗略地定义为“任何你训练它识别为姿势的东西”,方法是用一组图像训练它,并用从中提取的形状进行注释。

形状预测器是described in here on dlib's website

【讨论】:

也有可用的预训练模型,例如我前段时间使用了正面面部姿势检测器。 一定要谷歌一次,看看是否已经有一个模型可以满足你的需求。本质上,它只是经过训练的特征权重。【参考方案6】:

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

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

【讨论】:

我已经使用 OpenCV 的识别组件有一段时间了,不得不说它们往往相当庞大,而且不像我希望的那样准确。虽然到目前为止,这似乎是极少数可行的选择之一......不满足我需要的所有要求,但至少有点接近【参考方案7】:

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

【讨论】:

您在此处放置的 YouTube 链接令人瞠目结舌,真是令人惊叹。但与我需要的完全无关:( 它使用来自运动的结构。它利用您要“扫描”的对象与每帧的相机相比处于某个位置/方向这一事实来估计深度。 再一次 - 我不需要深度(我自己使用不同的方法进行深度),我只需要知道我正在寻找的对象在 2D 图像上的“位置”是:)【参考方案8】:

你听说过Eyesweb

我一直将它用于我的一个项目,但我认为它可能对您想要实现的目标有用。 这里有一些有趣的出版物LNAI 3881 - Finger Tracking Methods Using EyesWeb 和Powerpointing-HCI using gestures

基本上工作流程是:

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

不过,不知道有没有办法将 Eyes Web 的实时图像处理部分嵌入到软件库中。

【讨论】:

以上是关于使用网络摄像头(不是 Kinect)确定骨骼关节的主要内容,如果未能解决你的问题,请参考以下文章

如何在没有来自 Kinect Window SDK 的 Coordinatemapper 的情况下将 3D 骨骼关节映射回 2D 彩色图像

Kinect2.0获取关节姿态(Joint Orientation)

Kinect体感机器人—— 空间向量法计算关节角度

kinect2国行分辨

骨骼动画原理

Kinect关节识别