`
什么世道
  • 浏览: 222457 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
社区版块
存档分类
最新评论

Kinect开发之简单姿势识别

阅读更多

 姿势(POSE)识别方案(含简单算法)

    简析:身体以及各个关节点的位置定义了一个姿势。更具体的来说,是某些关节点相对于其他关节点的位置定义了一个姿势。 姿势的类型和复杂度决定了识别算法的复杂度。 通过关节点位置的交叉或者关节点之间的角度都可以进行姿势识别。

 

    通过关节点交叉进行姿势识别就是对关节点进行命中测试。在上一篇博文中,我们可以确定某一个关节点的位置是否在 UI 界面上某一个可视化元素的有效范围内。我们可以对关节点做同样的测试。 但是需要的工作量要少的多, 因为所有的关节点都是在同一个坐标空间中, 这使得计算相对容易。 例如叉腰动作(hand-on-hip) , 可以从骨骼追踪的数据获取左右髋关节和左右手的位置。然后计算左手和左髋关节的位置。如果这个距离小于某一个阈值,就认为这两个点相交。那么,这样就变得简单多了。

 

    但是,由于Kinect的精度问题,但即使通过一些平滑参数设置,从 Kinect 中获取的关节点数据要完全匹配也不太现实。另外,不可能期望用户做出一些连贯一致的动作, 或者保持一个姿势一段时间。 简而言之, 用户运动的精度以及数据的精度使得这种简单计算不适用。 因此, 计算两个点的长度, 并测试长度是否在一个阈值内是唯一的选择。角度原理也与之类似。

 

    当两个关节点比较接近时, 会导致关节点位置精度进一步下降, 这使得使用骨骼追踪引擎判断一个关节点的开始是否是另一个关节点的结束点变得困难。比如,很难将手放在脸的前面,手放在头上, 和手捂住耳朵这几个姿势区分开来。  要摆出一个确切的姿势也很困难, 用户是否会按照程序显示的姿势来做也是一个问题。

 

    一些姿势使用其他方法识别精度会更高。例如,用户伸开双臂和肩膀在一条线上这个姿势,称之为 T 姿势。可以使用节点相交技术,判断手、肘、以及肩膀是否在 Y 轴上处于近乎相同的位置。另一种方法是计算某些关节点连线之间的角度。骨骼追踪引擎能够识别多达20个关节点数据。任何三个关节点就可以组成一个三角形。使用三角几何就可以计算出他们之间的角度。

 

    实际上我们只需要根据两个关节点即可绘制一个三角形, 第三个点有时候可以这两个关节点来决定的。 知道每个节点的坐标就可以计算每个边长的值。 然后使用余弦定理就可以计算出角度了。公式如下图

     

 

 

    为了演示使用关节点三角形方法来识别姿势, 考虑在健美中常看到了展示肱二头肌姿势。用户肩部和肘在一条线上并且和地面平行,手腕与肘部与胳膊垂直。在这个姿势中,可以很容易看到有一个直角或者锐角三角形。 我们可以使用上面所说的方法来计算三角形的每一个角度,如下图所示:



    上图中, 组成三角形的三个关节点为。肩膀, 轴和手腕。根据这三个关节点的坐标可以计算三个角度。

 

    有两种使用节点三角形的方法。 最明显的如上面的例子那样, 使用三个节点来构造一个三角形。 另一个方法就是使用两个节点, 第三个节点手动指定一个点。 这种方法取决于姿势的限制和复杂度。 在上面的例子中, 我们使用三个及节点的方法, 因为需要的角度可以由手腕-肘- 肩部构成。不论其他部位如何变化,这三者所构成的三角形相形状相对不变。

    此文论述第二种方法,因为方法简单明了,不需太多的计算,方便以后开发调用。

 

获取每一个节点在主 UI 布局空间中的坐标的方法,由于Kinect精确度的原因和便于日后进一步开发,所以添加一个位置偏移坐标offset。

 

        /// <summary>
        /// 获取每一个节点在主 UI 布局空间中的坐标的方法
        /// </summary>
        /// <param name="kinectDevice"></param>
        /// <param name="joint"></param>
        /// <param name="containerSize"></param>
        /// <param name="offset"></param>
        /// <returns></returns>
        private static Point GetJointPoint(KinectSensor kinectDevice, Joint joint, Point offset)
        {
            //得到节点在主 UI 布局空间中的坐标
            //DepthImagePoint point = kinectDevice.MapSkeletonPointToDepth(joint.Position, kinectDevice.DepthStream.Format);
            DepthImagePoint point = kinectDevice.CoordinateMapper.MapSkeletonPointToDepthPoint(joint.Position, kinectDevice.DepthStream.Format);
            point.X = (int)(point.X - offset.X);
            point.Y = (int)(point.Y  - offset.Y);

            return new Point(point.X, point.Y);
        }
 

 

利用数学算法,计算两关节点与水平X轴间的夹角。如下图



 

 关键代码如下:

        /// <summary>
        /// 计算2关节点之间的夹角
        /// </summary>
        /// <param name="centerJoint"></param>
        /// <param name="angleJoint"></param>
        /// <returns></returns>
        private double GetJointAngle(Joint centerJoint, Joint angleJoint)
        {

            Point primaryPoint = GetJointPoint(this.kinect, centerJoint, new Point());
            Point anglePoint = GetJointPoint(this.kinect, angleJoint, new Point());
            Point x = new Point(primaryPoint.X + anglePoint.X, primaryPoint.Y);

            double a;
            double b;
            double c;

            a = Math.Sqrt(Math.Pow(primaryPoint.X - anglePoint.X, 2) + Math.Pow(primaryPoint.Y - anglePoint.Y, 2));
            b = anglePoint.X;
            c = Math.Sqrt(Math.Pow(anglePoint.X - x.X, 2) + Math.Pow(anglePoint.Y - x.Y, 2));

            double angleRad = Math.Acos((a * a + b * b - c * c) / (2 * a * b));
            double angleDeg = angleRad * 180 / Math.PI;

            //如果计算角度大于180度,将其转换到0-180度
            if (primaryPoint.Y < anglePoint.Y)
            {
                angleDeg = 360 - angleDeg;
            }

            return angleDeg;
        }
 

 

 

检测并判断姿势:循环遍历,直到找到满足条件的角度值。 

 /// <summary>
 /// 判断与指定姿势是否匹配的方法
 /// </summary>
 /// <param name="skeleton"></param>
 /// <param name="pose"></param>
 /// <returns></returns>
 private bool IsPose(Skeleton skeleton, Pose pose)
 {
     bool isPose = true;
     double angle;
     double poseAngle;
     double poseThreshold;
     double loAngle;
     double hiAngle;

     //遍历一个姿势中所有poseAngle,判断是否符合相应的条件
     for (int i = 0; i < pose.Angles.Length && isPose; i++)
     {
         poseAngle = pose.Angles[i].Angle;
         poseThreshold = pose.Angles[i].Threshold;
         //调用 GetJointAngle 方法来计算两个关节点之间的角度
         angle = GetJointAngle(skeleton.Joints[pose.Angles[i].CenterJoint], skeleton.Joints[pose.Angles[i].AngleJoint]);

         hiAngle = poseAngle + poseThreshold;
         loAngle = poseAngle - poseThreshold;

         //判断角度是否在360范围内,如果不在,则转换到该范围内
         if (hiAngle >= 360 || loAngle < 0)
         {
             loAngle = (loAngle < 0) ? 360 + loAngle : loAngle;
             hiAngle = hiAngle % 360;

             isPose = !(loAngle > angle && angle > hiAngle);
         }
         else
         {
             isPose = (loAngle <= angle && hiAngle >= angle);
         }
     }
     //如果判断角度一致,则返回true
     return isPose;
 }
 

 

这样,我们就可以定义一个玩家伸开双臂的姿势,T字型,阈值角度为10,如下图 

 
 
            //Pose - 伸开双臂 Arms Extended
            this.startPose = new Pose();//自定义姿势类
            this.startPose.Title = "Start Pose";
            this.startPose.Angles = new PoseAngle[4];
            this.startPose.Angles[0] = new PoseAngle(JointType.ShoulderLeft, JointType.ElbowLeft, 180, 10);
            this.startPose.Angles[1] = new PoseAngle(JointType.ElbowLeft, JointType.WristLeft, 180, 10);
            this.startPose.Angles[2] = new PoseAngle(JointType.ShoulderRight, JointType.ElbowRight, 0, 10);
            this.startPose.Angles[3] = new PoseAngle(JointType.ElbowRight, JointType.WristRight, 0, 10);
          }

 

友情提示:该项目需要有Kinect SDK的支持才能运行。

Kinect SDK下载地址:http://www.microsoft.com/en-us/kinectforwindowsdev/default.aspx

 

下一篇博客将会把这个用姿势识别控制小游戏,从而脱离键盘鼠标。
希望大家多多支持和指正。 
 

Kinect开发系列博文:

Kinect开发之结合Unity3D进行游戏应用开发
 
Kinect开发之体感举起手来程序设计(Kinect俄罗斯方块)
 
Kinect开发之简单姿势识别
 
Kinect开发之获取骨骼关节数据并绘制成火柴人
 
Kinect开发之获取彩色摄像头数据 
  • 大小: 39 KB
  • 大小: 66.4 KB
  • 大小: 4.7 KB
  • 大小: 5.3 KB
分享到:
评论
2 楼 什么世道 2014-05-28  
Stephanie_1 写道
楼主。你的程序在CSDN没有了呀,可不可以发我邮箱???1325341041@qq.com。。。这一块不知道怎么开始搞头大死了。谢谢了

下载地址已更新
1 楼 Stephanie_1 2014-05-27  
楼主。你的程序在CSDN没有了呀,可不可以发我邮箱???1325341041@qq.com。。。这一块不知道怎么开始搞头大死了。谢谢了

相关推荐

    基于Kinect的姿势识别与应用研究

    因此,开发高效、准确的姿势识别技术对提高虚拟实验的使用效率和用户体验至关重要。 二、基于Kinect的姿势识别方法 本文提出了一种基于Kinect的姿势识别方法,该方法利用Kinect传感器得到的二十多个关节点信息,...

    基于Kinect的骨架提取及姿势识别

    在实际应用中,基于Kinect的姿势识别技术可以实现简单的体感控制。比如在游戏场景中,玩家可以通过手势来操作游戏,无需物理控制器;在康复训练中,医生可以远程监控患者的运动状态,确保其遵循正确的康复动作;在...

    Kinect手势识别

    本文主要探讨利用Kinect传感器收集的数据进行更小尺度的手势识别的可能性,即专注于识别个体通过手部执行的简单手势(如抓握、指向等)。为了实现这一目标,首先利用现有的全身追踪技术确定手部的位置,然后基于手部...

    kinect 人脸识别2d

    Kinect 2.0 是微软开发的一种体感设备,它在初代的基础上进行了重大升级,尤其是在人脸识别和人体骨架追踪方面。在"Kinect 人脸识别2d"这一主题中,我们将深入探讨如何使用Kinect 2.0进行二维人脸识别,以及如何获取...

    基于Kinect的Python与C#双语言太极姿势识别设计源码

    本项目是一款基于Kinect的太极姿势识别系统,采用C#和Python双语言开发,共计包含151个文件,涵盖30个DLL库文件、26个XML配置文件、19个PNG图像文件、13个缓存文件、7个C#源代码文件、5个Python脚本文件、5个可执行...

    Kinect2.0开发文档

    最后,Kinect2.0强大的人体骨骼追踪功能也是其亮点之一,能够实现对人体姿势的精确识别与追踪。 综上所述,Kinect2.0不仅提供了丰富的API接口,还涵盖了从基础数据读取到高级应用实现的多个方面,为开发者提供了...

    openNI的kinect开发

    "openNI的kinect开发" 这个标题揭示了我们要讨论的核心主题,即使用openNI框架进行Kinect传感器的开发工作。openNI是一个开源的开发平台,它为各种自然交互设备(如Microsoft Kinect)提供了一个统一的接口,方便...

    体感编程系列(一)Kinect开发入门理论知识点概述

    综上所述,Kinect开发涉及硬件原理、软件接口、图像处理、骨骼追踪、语音识别等多个领域的知识,开发者需要具备一定的编程基础和对计算机视觉的理解,才能充分利用Kinect进行创新应用的开发。通过不断的实践和学习,...

    基于Kinect的人体姿势识别算法及应用

    基于Kinect的人体姿势识别算法及应用研究主要关注点是在利用Kinect深度图像传感器采集的数据基础上进行人体骨骼识别,进而分析人体姿势,这在人工智能和计算机视觉领域属于一个重要研究课题。人体姿势识别通过人体...

    基于Kinect的人体动作识别小游戏

    Kinect是微软为Xbox游戏主机开发的一款外设,同时也适用于Windows平台。它通过红外传感器、RGB摄像头和麦克风阵列,实现对用户3D体态的捕捉、语音识别以及环境感知。在人体识别方面,Kinect可以检测到人体的关键关节...

    kinect_开发入门2

    ### Kinect开发入门精要:深度探索与骨骼追踪 在深入探讨Kinect开发的过程中,第二阶段的学习尤为关键,它标志着从基础知识向高级应用的过渡。本文将聚焦于Kinect的骨骼追踪技术及其在用户交互设计中的创新应用,...

    kinect 景深识别

    Kinect 深度识别技术是微软开发的Kinect设备的核心功能之一,它允许设备捕捉到3D空间中的场景信息,从而实现对人或物体的深度感知。在WPF(Windows Presentation Foundation)环境下,我们可以利用Kinect SDK来开发...

    kinect手势识别

    总的来说,"kinect手势识别" 是一个利用Kinect设备和C#编程语言开发的交互技术,通过对特定手势的识别,提供了一种非接触式的交互方式。这一技术在游戏、教育、医疗等许多领域都有潜在的应用价值,而且随着计算机...

    Kinect for Windows SDK开发入门(十二):语音识别 上1

    【Kinect for Windows SDK开发入门(十二):语音识别 上1】 在开发基于Kinect的应用程序时,语音识别是一项强大的特性,它使用户能够通过自然语言与设备交互。Kinect的麦克风阵列位于设备的下方,由四个独立的麦克风...

    KinectSDK2.0面形查看

    通过骨骼跟踪和深度图像处理,Kinect可以准确地识别用户的手部和手臂姿势,然后通过Gesture Recognizer组件来解析这些动作,实现与应用的交互。 在"KinectGesture"这个压缩包文件中,可能包含了关于如何使用Kinect...

    Kinect_SalopuroPresentation 开发引入门 引导

    #### 二、Kinect开发系统设置 ##### 2.1 开发环境搭建 - **软件库需求**:安装Microsoft Kinect for Windows runtime & SDK v1.7 & Developer Toolkit([官网链接]...

    Kinect人机交互开发实践

    Kinect人机交互开发实践是基于微软的Kinect设备进行的一种创新性技术应用,它将人体动作识别与计算机系统相结合,实现非接触式的用户输入方式。这种技术在游戏、教育、医疗、工业等多个领域有着广泛的应用前景。在这...

    关于kinect的一些论文

    4. "面向人机交互的单目视频三维人体姿态估计研究_李娜.caj" - 李娜的论文可能关注的是如何从单个摄像头(如Kinect)的视频流中估计人体的三维姿势,这对于实时的人机交互应用至关重要。她可能提出了新的算法或改进...

    Using Kinect for Windows with XNA

    通过传感器,系统可以识别用户的姿势、手势,甚至语音命令。 1.2 Kinect传感器内部结构 Kinect传感器包含一个RGB摄像头、深度传感器(红外投影仪和接收器)以及麦克风阵列。这些组件协同工作,为用户提供3D空间中...

    Kinect for unity sdk v2.9.unitypackage

    3. **医疗健康**:如康复训练、姿势矫正等领域,Kinect能够提供精准的人体动作分析。 4. **零售业**:例如顾客行为分析、产品展示互动等。 5. **教育**:Kinect可以用于创造互动式学习体验,提升学生的学习兴趣。 #...

Global site tag (gtag.js) - Google Analytics