使用Kinect进行手指/手势识别

时间:2014-02-14 11:12:54

标签: opencv image-processing computer-vision kinect openni

在解释问题之前,让我解释一下我的需要。 我期待着一个手控应用程序。 使用手掌和点击使用抓取/拳击导航。

目前,我正在使用Openni,这听起来很有前途,并且很少有例子在我的案例中证明是有用的,因为它在样本中构建了手动跟踪器。这符合我的目的。

我想问的是,

1)使用拳头/抓取探测器的最佳方法是什么?

我在提取的RGB数据上训练并使用了Adaboost拳头分类器,这非常好,但是,它有太多的错误检测才能继续前进。

所以,在这里我再提出两个问题

2)是否有其他优秀的图书馆能够使用深度数据来满足我的需求?

3)我们可以训练自己的手势,尤其是使用手指,因为有些论文指的是HMM,如果是的话,我们如何处理像OpenNI这样的图书馆?

是的,我尝试使用OpenNI中的中间件库,例如抓取探测器,但是,它们不能满足我的目的,因为它既不是开源也不符合我的需要。

除了我的问题,如果你认为有什么东西可以帮助我,我会被接受作为一个好建议。

8 个答案:

答案 0 :(得分:7)

您不需要训练您的第一个算法,因为它会使事情复杂化。 不要使用颜色,因为它不可靠(与背景混合并根据照明和视点不可预测地变化)

  1. 假设您的手是最近的物体,您可以简单地 按深度阈值划分出来。您可以手动设置阈值,使用最近的深度直方图区域,或者在深度图上执行connected component以先在有意义的部分上将其分解(然后根据其深度选择对象,还可以使用其尺寸,动作,用户输入等)。以下是连接组件方法的输出: depth image connected components hand mask improved with grab cut
  2. 从opencv库中应用convex defects以找到手指;

  3. 跟踪手指而不是在3D中重新发现它们。这将增加稳定性。我大约3年前成功实施了这种手指检测。

答案 1 :(得分:4)

阅读我的论文:) http://robau.files.wordpress.com/2010/06/final_report_00012.pdf

我已经完成了对手部手势识别的研究,并评估了几种对比例,旋转等具有鲁棒性的方法。您有深度信息是非常有价值的,因为对我来说最难的问题是实际将手分开。图像。

我最成功的方法是追踪手的轮廓,并对轮廓上的每个点,取距离到手的质心。这给出了一组可用作许多训练算法的输入的点。

我使用分割手的图像时刻来确定其旋转,因此手部轮廓上有一个很好的起点。很容易确定拳头,伸出的手和伸出的手指的数量。

请注意,虽然它可以正常工作,但是你的手臂往往会因为指向空气而感到疲倦。

答案 2 :(得分:2)

您似乎没有意识到Point Cloud Library (PCL)。它是一个开源库,专门用于处理点云和RGB-D数据,它基于OpenNI进行低级操作,并提供a lot of high-level algorithm,例如执行注册,分段和识别

一种非常有趣的形状/对象识别算法通常称为隐式形状模型。为了检测全局对象(例如汽车或开放式手),首先要检测它的可能部分(例如车轮,行李箱等,或手指,手掌,手腕)等)使用局部特征检测器,然后通过考虑其部分的密度和相对位置来推断全局对象的位置。例如,如果我可以在给定的邻域中检测到五个手指,一个手掌和一个手腕,那么我很有可能看到一只手,但是,如果我只检测到一个手指和一个手腕,它可能是一对错误的检测。关于这种隐式形状模型算法的学术研究文章可以找到here

在PCL中,有一个couple专门用于形状识别主题的教程,幸运的是,one它们涵盖了隐式形状模型,在PCL中实施。我从未测试过这个实现,但是根据我在本教程中可以阅读的内容,您可以指定自己的点云来训练分类器。

就是说,你没有在你的问题中明确提到它,但由于你的目标是编写一个手动控制的应用程序,你可能实际上对 real-感兴趣时间形状检测算法。您必须测试PCL中提供的隐式形状模型的速度,但我认为这种方法更适合离线形状识别。

如果你确实需要实时形状识别,我认为你应该首先使用手/臂跟踪算法(通常比完全检测更快),以便知道在图像中查看的位置,而不是尝试执行在RGB-D流的每个帧处进行完整的形状检测。例如,您可以通过分割深度图来跟踪手部位置(例如,使用深度上的适当阈值),然后检测外部因素。

然后,一旦你大致知道手的位置,就应该更容易确定手是否正在做一个与你的应用相关的手势。我不确定你用拳头/抓握手势的确是什么意思,但我建议你定义并使用一些应用程序控制手势,容易快速来区分另一个。

希望这有帮助。

答案 3 :(得分:2)

快速回答是:是的,您可以使用深度数据训练自己的手势探测器。这很简单,但这取决于手势的类型。

假设您想要检测手部动作:

  1. 检测手位置(x,y,x)。使用OpenNi是直截了当的,因为你手上有一个节点
  2. 执行手势并收集手势期间手的所有位置。
  3. 使用位置列表训练一个HMM。例如,您可以使用MatlabCPython
  4. 对于您自己的手势,您可以测试模型并检测手势。
  5. Here你可以找到一个很好的教程和代码(在Matlab中)。代码(test.m非常容易理解)。这是一个snipet:

    %Load collected data
    training = get_xyz_data('data/train',train_gesture);
    testing = get_xyz_data('data/test',test_gesture); 
    
    %Get clusters
    [centroids N] = get_point_centroids(training,N,D);
    ATrainBinned = get_point_clusters(training,centroids,D);
    ATestBinned = get_point_clusters(testing,centroids,D);
    
    % Set priors:
    pP = prior_transition_matrix(M,LR);
    
    % Train the model:
    cyc = 50;
    [E,P,Pi,LL] = dhmm_numeric(ATrainBinned,pP,[1:N]',M,cyc,.00001);
    

    处理手指几乎是相同的,但不是检测手,而是需要检测手指。由于Kinect没有手指点,您需要使用特定代码来检测它们(使用分割或轮廓跟踪)。使用OpenCV的一些示例可以找到herehere,但最有希望的是具有指状节点的ROS库(参见示例here)。

答案 4 :(得分:2)

如果您只需要检测拳/抓状态,则应该给微软一个机会。 Microsoft.Kinect.Toolkit.Interaction包含检测手的抓握/抓握释放状态的方法和事件。请查看InteractionHandPointer HandEventType。这对于拳头/抓取检测非常有效,但不会检测或报告单个手指的位置。

下一个kinect(kinect one)每手检测3个关节(手腕,手,拇指)并有3个基于手的手势:打开,关闭(握拳/拳头)和套索(指针)。如果这对你来说已经足够了,你应该考虑微软库。

答案 5 :(得分:0)

1)如果存在大量错误检测,您可以尝试扩展分类器的负样本集,并再次训练它。扩展的负片图像集应该包含这样的图像,其中拳头是错误检测到的。也许这有助于创建更好的分类器。

答案 6 :(得分:0)

我在http://www.threegear.com/提供的中间件库方面取得了相当大的成功。它们提供了几种手势(包括抓取,捏住和指向)和6DOF头部跟踪。

答案 7 :(得分:0)

您可能对本文感兴趣&开源代码:

用于实时手部跟踪的稳健的铰接式ICP

代码:https://github.com/OpenGP/htrack

屏幕截图:http://lgg.epfl.ch/img/codedata/htrack_icp.png

YouTube视频:https://youtu.be/rm3YnClSmIQ

论文PDF:http://infoscience.epfl.ch/record/206951/files/htrack.pdf