通过Kinect获取到关节的三维坐标点后可以根据向量点积或叉积公式计算出关节角度:

$$\vec{a}\cdot \vec{b} = |\vec{a}||\vec{b}|cos\theta$$

vector1.Normalize();
vector2.Normalize();
double cosinus = DotProduct(vector1, vector2); double angle = (Math.Acos(cosinus) * (180.0 / Math.PI));

  在DirectXMath数学库中也有现成的计算向量夹角的函数XMVector3AngleBetweenVectors

XMVECTOR  XMVector3AngleBetweenVectors( XMVECTOR V1, XMVECTOR V2 ); //返回向量V1、V2间的夹角[angle, angle,angle, angle],单位为弧度

  下面的部分代码将获取到的骨骼数据进行平滑,然后计算出关节角度:

/// Handle new body data
void CBodyBasics::ProcessBody(IBody* pBody)
{
HRESULT hr;
BOOLEAN bTracked = false;
hr = pBody->get_IsTracked(&bTracked); // Retrieves a boolean value that indicates if the body is tracked if (SUCCEEDED(hr) && bTracked) // 判断是否追踪到骨骼
{
Joint joints[JointType_Count];
HandState leftHandState = HandState_Unknown;
HandState rightHandState = HandState_Unknown; DepthSpacePoint *depthSpacePosition = new DepthSpacePoint[_countof(joints)]; // 存储深度坐标系中的关节点位置 pBody->get_HandLeftState(&leftHandState); // 获取左右手状态
pBody->get_HandRightState(&rightHandState); hr = pBody->GetJoints(_countof(joints), joints); // 获得25个关节点
if (SUCCEEDED(hr))
{
// Filtered Joint
filter.Update(joints);
const DirectX::XMVECTOR* vec = filter.GetFilteredJoints(); // Retrive Filtered Joints float angle = Angle(vec, JointType_WristRight, JointType_ElbowRight, JointType_ShoulderRight); // Get ElbowRight joint angle
char s[];
sprintf_s(s, "%.0f", angle);
std::string strAngleInfo = s;
putText(skeletonImg, strAngleInfo, cvPoint(, ), CV_FONT_HERSHEY_COMPLEX, 0.5, cvScalar(, , )); // 屏幕上显示角度信息 for (int type = ; type < JointType_Count; type++)
{
if (joints[type].TrackingState != TrackingState::TrackingState_NotTracked)
{
float x = 0.0f, y = 0.0f, z = 0.0f;
// Retrieve the x/y/z component of an XMVECTOR Data and storing that component's value in an instance of float referred to by a pointer
DirectX::XMVectorGetXPtr(&x, vec[type]);
DirectX::XMVectorGetYPtr(&y, vec[type]);
DirectX::XMVectorGetZPtr(&z, vec[type]); CameraSpacePoint cameraSpacePoint = { x, y, z };
m_pCoordinateMapper->MapCameraPointToDepthSpace(cameraSpacePoint, &depthSpacePosition[type]); //将关节点坐标从摄像机坐标系转到深度坐标系以显示
}
} DrawBody(joints, depthSpacePosition);
DrawHandState(depthSpacePosition[JointType_HandLeft], leftHandState);
DrawHandState(depthSpacePosition[JointType_HandRight], rightHandState);
} delete[] depthSpacePosition;
} cv::imshow("skeletonImg", skeletonImg);
cv::waitKey(); // 延时5ms
} FLOAT CBodyBasics::Angle(const DirectX::XMVECTOR* vec, JointType jointA, JointType jointB, JointType jointC)
{
float angle = 0.0; XMVECTOR vBA = XMVectorSubtract(vec[jointB], vec[jointA]);
XMVECTOR vBC = XMVectorSubtract(vec[jointB], vec[jointC]); XMVECTOR vAngle = XMVector3AngleBetweenVectors(vBA, vBC); angle = XMVectorGetX(vAngle) * 180.0 * XM_1DIVPI; // XM_1DIVPI: An optimal representation of 1 / π return angle;
}

  国外有个公司vitruvius已经将关节角度获取、背景去除、手势识别、Avateering等功能做的简单易用,可以在其网站上下载免费的版本试用:

参考:

https://vitruviuskinect.com/

DirectXMath Library 3D Vector Geometric Functions

Using the Kinect Sensor to Calculate Body Segment Angles

Find the angle between two line segments

LightBuzz.Vitruvius/Core/Vector3.cs

How to select the users to track in C++

【D3D11游戏编程】学习笔记二:XNAMath之XMVECTOR

Kinect2.0关节角度获取的更多相关文章

  1. 使用Kinect2.0获取点云以在GLUT中显示

    这篇文章用来记录Kinect2.0如何生成点云. 以下示例源自Kinect提供的example修改完成,其名称会在小标题下方注解. 首先,要获取点云需要获取图像的深度数据和颜色数据.最后再将深度数据与 ...

  2. Kinect2.0获取数据

    最近事情真是多,今天抽空研究一下Kinec2.0的数据获取! 系统要求 https://developer.microsoft.com/en-us/windows/kinect/hardware-se ...

  3. 使用Kinect2.0控制VREP中的虚拟模型

    VREP中直接设置物体姿态的函数有3个: simSetObjectOrientation:通过欧拉角设置姿态 simSetObjectQuaternion:通过四元数设置姿态 simSetObject ...

  4. Kinect2.0骨骼跟踪与数据平滑

    Kinect v1和Kinect v2传感器的配置比较:   Kinect v1 Kinect v2           颜色(Color) 分辨率(Resolution) 640×480 1920× ...

  5. Kinect2.0点云数据获取

    接上一篇:Kinect2.0获取数据 http://blog.csdn.net/jiaojialulu/article/details/53087988 博主好细心,代码基本上帖过来就可以用,注释掉的 ...

  6. Swift3.0语言教程获取字符串编码与哈希地址

    Swift3.0语言教程获取字符串编码与哈希地址 Swift3.0语言教程获取字符串编码与哈希地址,以下将讲解字符串中其它内容的获取方法. 1.获取字符串编码 在NSString中可以使用2个属性获取 ...

  7. Swift3.0语言教程获取C字符串

    Swift3.0语言教程获取C字符串 Swift3.0语言教程获取C字符串,为了让Swift和C语言可以实现很好的交互,开发者可以使用NSString的cString(using:)方法在指定编码格式 ...

  8. Swift3.0语言教程获取字符

    Swift3.0语言教程获取字符 Swift3.0语言教程获取字符,在字符串中获取某一下标位置(下标索引)处的字符是很常见的功能,在NSString中使用character(at:)方法实现,其语法形 ...

  9. Swift3.0语言教程获取字符串长度

    Swift3.0语言教程获取字符串长度 Swift3.0语言教程获取字符串长度,当在一个字符串中存在很多的字符时,如果想要计算字符串的长度时相当麻烦的一件事情,在NSString中可以使用length ...

随机推荐

  1. golang导入包的几个说明:import

    导入包: 标准包使用的是给定的短路径,如"fmt"."net/http" 自己的包,需要在工作目录(GOPATH)下指定一个目录,improt 导入包,实际上就 ...

  2. Java NIO SocketChannel

    A Java NIO SocketChannel is a channel that is connected to a TCP network socket. It is Java NIO's eq ...

  3. ARM、X86/Atom、MIPS、PowerPC

    关注Android的时候,有一些CPU架构方面的术语知识,主要有:ARM.X86/Atom.MIPS.PowerPC1)ARM/MIPS/PowerPC均是基于精简指令集(RISC,Reduced I ...

  4. Unique Paths leetcode java

    题目: A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below). ...

  5. ARDC Android 远程桌面助手 录屏 演示 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  6. ES8新特性——ES8 was Released and here are its Main New Features

    原文: https://hackernoon.com/es8-was-released-and-here-are-its-main-new-features-ee9c394adf66 -------- ...

  7. c#:对两个字符串大小比较(不使用c#/java内部的比较函数),按升序排序

    题目:首先需要实现一个函数:两个字符串大小比较(不得使用c#/java系统函数)的自定义函数:之后对一个字符串数据进行按升序排序(在排序过程中使用字符串大小比较时,使用自定义的字符串大小比较函数). ...

  8. ASP入门(十八)-访问Access中的数据库

    Northwind 数据库 这是一个微软为软件的使用者提供的一个练习用的数据库,它模拟了一个商贸公司日常业务流程所需要的一些数据. 并且网络上大部分的 SQL 语句的讲解都是以这个数据库为例子讲解的. ...

  9. Direct2D教程VI——转换(Transform)

    目前博客园中成系列的Direct2D的教程有 1.万一的 Direct2D 系列,用的是Delphi 2009 2.zdd的 Direct2D 系列,用的是VS中的C++ 3.本文所在的 Direct ...

  10. 安装ecshop2.7时候的错误处理 php版本不兼容引起

    装ECShop2.7.3出现了一堆问题,主要是因为PHP版本过高引起的,不愿意降低版本,则只能一个个解决啦!这些问题包括:preg_replace.cls_image::gd_version.end( ...