通过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

最新文章

  1. .NET面试题系列[12] - C# 3.0 LINQ的准备工作
  2. VS2015 + OpenCV 2.4.X 配置环境
  3. hdu 2586 How far away ?(离线求最近公共祖先)
  4. Stanford大学机器学习公开课(三):局部加权回归、最小二乘的概率解释、逻辑回归、感知器算法
  5. uva 10599 - Robots(II) (dp | 记忆化搜索)
  6. [转]HTTP请求模型和头信息参考
  7. Form 提交表单
  8. 网络语音视频技术浅议(附多个demo源码下载)
  9. Android最佳性能实践(四)——布局优化技巧
  10. Common-used commands in Docker
  11. 使用Docker部署javaWeb应用
  12. 查找第K小的数 BFPRT算法
  13. Apache Kafka监控之Kafka Web Console
  14. 吴裕雄 python神经网络 水果图片识别(5)
  15. (转) python学习笔记6--fraction
  16. 洛谷P3437 [POI2006]TET-Tetris 3D(二维线段树 标记永久化)
  17. Android 手机 无线 ADB
  18. 十二、curator recipes之双重屏障DoubleBarrier
  19. javascript 面向对象 new 关键字 原型链 构造函数
  20. 洛谷P3764 签到题 III

热门文章

  1. HTML5 本地文件操作之FileSystemAPI实例(四)
  2. 使用强大的 Mockito 测试框架来测试你的代码
  3. Error: Program type already present: android.arch.lifecycle.LifecycleRegistry$1
  4. scala编程第16章学习笔记(3)——List类的高阶方法
  5. CF 329B(Biridian Forest-贪心-非二分)
  6. AS 注解处理器 APT Processor MD
  7. 自定义View 可清除内容、设置图标、下划线的输入框 MD
  8. Spark 以及 spark streaming 核心原理及实践
  9. 【转载】.NET/C#-uploadify视频文件or大文件上传
  10. (转)Esfog_UnityShader教程_UnityShader语法实例浅析