首页 > 代码库 > 使用Kinect2测量身高

使用Kinect2测量身高

在做体感操作检测的时候, 常常会用到很多阀值, 比如移动了多少距离, 距离某个部位多么远等等

但是对于不同的人来说, 这些值通常是不一样的. 像胳膊长的人跟胳膊短的人在手的移动范围上也是有比较大的差异的

如果想做到比较好的适应性, 就需要针对不同体形(身高)的人做适配, 所以就有了使用Kinect估算身高的想法


先看看Kinect2的API都提供了哪些数据:

  • 底层
    • YUV ColorBuffer (1080p)
    • Depth Buffer (512x424)
    • IR Buffer (512x424)
  • 中层
    • 每个骨骼的CameraSpacePoint
  • 高层
    • 语音/表情/手势识别等
比较直接的思路就是使用(Head.Position.Y - Foot.Position.Y)来进行身高的估算. 如果需要更精确的数值, 可以访问DepthBuffer里人的边界点, 本文不展开讨论
那么我们来看一下这个CameraSpacePoint中各分量的取值范围:
  • X: 约[-1.3, 1.3]
  • Y: [-1, 1]
  • Z: 约[0.5, 4.5]
显然取Y差值的做法行不通了. 回过头来看看Kinect的原理:

有图形学经验的人可以一眼看出这其中的透视变换原理, 简单点说Kinect就是使用IR和Depth数据进行骨架检测, 再转换成CameraSpacePoint
再结合Kinect2的各项参数可以大概弄明白CameraSpacePoint是怎么来的了:


 Version 1Version 2
Depth range0.4m → 4.0m0.4m → 4.5m
Color stream640×4801920×1080
Depth stream320×240512×424
Infrared streamNone512×424
Audio stream4-mic array4-mic array
USB2.03.0

虽然X,Y并不是传统意义上的ProjectionSpace, 但结合FOV和DepthBuffer的宽高比来看, X方向可以看做是在[-1,1]范围外多加了一部分, 因此X,Y分量还是可以看做是投影变换后的相对坐标
至于Z分量, 很明显就是实际的距离(米), 我们可以手动把它转换为[-1, 1]的范围:
		XMVECTOR headP = XMVectorSet(head.X, head.Y, (head.Z - 0.4f) / 4.1f, 1.0f);
		XMVECTOR footP = XMVectorSet(foot.X, foot.Y, (foot.Z - 0.4f) / 4.1f, 1.0f);
那把投影空间的坐标转换成相机空间的坐标就很简单了,  直接乘上Projection的逆矩阵即可
那么, 怎么构造这个逆矩阵呢?
参考上图和硬件参数, 可以估算出AspectRatio应该是1, 而不是(512/424). 而Near/Far Clip则是现成的:
		XMMATRIX project = XMMatrixPerspectiveFovRH(60.0f / 180.0f * XM_PI, 1.0f, 0.4f, 4.5f);
		XMMATRIX inverse = XMMatrixInverse(nullptr, project);
转换成以米为单位后的坐标后, 身高数据就很空间计算了:
		XMVECTOR headW = XMVector3Transform(headP, inverse);
		XMVECTOR footW = XMVector3Transform(footP, inverse);
		XMVECTOR height = XMVector3Length(XMVectorSubtract(headW, footW));
有了这个数据, 其它阀值之类的就可以按一定比例计算相对值进行适配了, 初步解决不同体形身高人体验差异太大的问题
另外, 如果需要识别坐姿, 可以改为估算Spine到Head的距离代替, 因为这个值比较稳定, 不会受腿部动作影响
以下是Demo效果:


结果虽然有误差(约5cm范围内), 但做为适配参数来说够用了
另外, 可以使用JointFilter算法做一下过滤, 避免抖动产生不稳定的结果


参考资料:
Kinect for Windows version 2: overview
http://pterneas.com/2014/02/08/kinect-for-windows-version-2-overview/
Skeletal Joint Smoothing White Paper
http://msdn.microsoft.com/en-us/library/jj131429.aspx

使用Kinect2测量身高