本文为稀土掘金技术社区首发签约文章,30天内禁止转载,30天后未获授权禁止转载,侵权必究!
beginning
上节和大家一起学习实现了基于Mediapipe的三维手部关键点检测,代码实战之后,相信大家也想进一步了解这有趣神奇的模型背后的思想,那本文就结合原始论文,用通俗易懂的语言给大家介绍一下Mediapipe手部关键点检测和追踪模型的原理。废话不多说啦,如果你也对此有兴趣,咱们一起快乐的学习叭🎈🎈🎈
1.模型的结构
论文链接:MediaPipe Hands: On-device Real-time Hand Tracking
在这篇论文中,提出了一个实时的在终端设备上的手部检测的解决方案,可以预测出手部的骨架,并不需要其他的传感器,而只需要RGB的彩色图像就可以啦。可以用来开发增强现实和虚拟现实的应用。整个的工作流包含两个模型:1.手掌检测器color{blue}{手掌检测器},它可以用来预测手掌的预测框的;2.手部关键点检测的模型color{blue}{手部关键点检测的模型},它可以预测出手部的骨架,包含21个关键点,是通过mediapipe实现的🌻🌻🌻
整个模型可以预测出2.5D的手部关键点,它并不是完全3D的,也就是说所谓的深度(即每个关键点与手腕的相对距离)是它猜出来的,并不是真正的距离,而是仅供参考的。是不是还是不太懂2.5D腻,没关系,下面这张图呢就生动具体地展示了2.5D是啥意思,帮助我们更好地理解:除了21个关键点的xy坐标之外(也就是2D嘛),它还加了一个与根部手腕点的相对距离,也就是左图中类似小铜钱的东西越亮或越暗,越大或越小,就表明了它与手腕距离的远近。是不是恍然大悟辽。右侧的图展示了一个多个手的手部21个关键点检测的预测结果,可以看到里面存在一些遮挡情况,但仍然能够比较好的预测出来🧸🧸🧸
下面呢让我们对包含的两个组件——手掌检测器和手部关键点检测模型进行更详细的学习叭
1.1手掌检测器
因为我们先使用的手掌检测器,所以手掌检测器的质量对于手部关键点检测而言是非常重要的,如果检测器的质量足够高的话,那么数据增强的需要就降低了。这里的数据增强就是通过旋转、平移、缩放等来扩充数据集,防止过拟合,让模型适应各种变化。好的手掌检测器能够提高后续的关键点检测定位的准确率🌴🌴🌴
那么在真实的实时检测追踪场景下,我们是怎么做的腻?我们先是从上一帧的关键点来提取出一个bounding box,再把这个bounding box喂给下一帧,作为下一帧的输入。这样的话我们就不需要每一帧都去重复运行手掌检测啦,是能够用上一帧的关键点检测的结果预测出手掌的区域,就不需要再去运行手掌检测啦,那小伙伴们想一想什么时候再运行手掌检测腻🧐🧐🧐只有在第一帧(启动时)或者当画面中没有检测到手的时候,才需要再运行这个手掌检测器。那这样就大大地节省了时间,提升了性能(太妙了呀)。其实这也是手掌检测器的精髓所在。
为了检测出初始的手掌位置,我们使用了SSD目标检测模型,这个模型是专门针对移动端优化的。检测手是一个非常复杂的任务,因为手有很多种尺寸,存在遮挡和自遮挡的情况;与人脸检测不同,人脸是一个有高对比度的模式(嘴巴眼睛等可以辅助来检测人脸),而手是一个动态的复杂模式,仅仅从视觉特征来预测手是很困难的。为了解决这一问题呢,我们使用了不同的策略:
- 首先我们训练了一个手掌的检测器,而不是整个手部的检测器。因为手掌是一个方形的类似刚体的物体,并不会像手指那样灵活乱动,是一个比较稳定的特征;而且手掌更小,所以非极大值抑制算法可以在两只手握手或者自遮挡的情况下性能会更好;同时,正方形的手掌不需要再考虑其他的长宽比,所以可以减少不需要的anchor锚框。
- 使用了编码器-解码器的特征提取方案(类似FPN)。
- 在训练时最小化了focal loss,这样就能够从有不同大小尺度的、非常多的anchor里学习到特征。
下图是手掌检测器的模型结构。可以看出是一个编码解码器,中间有一些skip、shortcut跳跃连接,不是很复杂滴🌟🌟🌟
1.2手部关键点检测模型
再运行了手掌检测模型之后,输入全图,输出手掌的预测框。接下来的任务呢就是把手掌的预测框喂给手部关键点检测的模型,来预测出21个关键点的2.5D坐标(坐标自然是一个回归问题,预测出连续的数值)。
下图是手部关键点检测模型的结构。可以看出,手部关键点检测模型有三个输出:第一个输出是关键点的x、y和相对深度z坐标,也就是图中输出端的绿色部分;第二个输出是手的置信度,也就是说有百分之多少的概率来判断它是一只手;第三个输出是handedness,也就是左手还是右手🌈🌈🌈
21个手部关键点检测模型包含了三个维度。x、y的2D坐标是对真实拍摄到的手的图片进行标注,然后得到的;也有包含一部分电脑生成的假手图像,这在后面的数据集部分详细说明。而关键点相对于手腕的深度坐标z通过自然拍摄到的图像是没法标注的,你并不知道关键点离手腕到底有多远,但是电脑三维模型生成的图像你是知道的,所以相对深度z坐标是通过生成的图像来获取的标签。
为了防止预测错误呢,还在模型中加了一个输出头来输出手的置信度,如果它的置信度低于某个阈值,那么手掌检测器就被重新启动啦。整个模型就实现了在移动CPU上的实时检测。
2.数据集
数据决定了性能的上限,而算法则是去逼近这个上限,所以数据集是很重要滴。为了获取标注的数据,我们构建了下面这三个子数据集来从各个角度解决数据问题:
- 实际拍摄的数据集:现场真实的图片包含了6000张,都分布在不同的地区、不同的光照下和不同手的出现度。这个数据集的一个缺点是它并不包含手的复杂动作(比如魔术师的一些手部复杂动作)。
- 实验室的数据集:是在特定条件下拍的10000张图片,包含各种角度和不同的手部姿势。这个数据集的缺点是只包含了30个人的手,而且这个数据集的背景是比较单一的,缺少些变化。(发现没,数据集1和2是互补的,这样可以提升鲁棒性)
- 生成图片的数据集:前两个数据集是真人和真手的图片,而这个数据集是用电脑三维模型生成的图片,特别是它能够提供深度。前两个数据集的标注并不知道深度,但是三维模型是知道深度的。我们渲染了一系列的高质量手的三维模型,用这个模型来生成视频,然后从视频中截取了10万张图片,并且它的背景是不同角度和光照条件。
下图就展示了数据集。上面一行是真人真手的图片以及只有二维的标注,下面一行图是使用三维模型生成的视频,然后从视频中截取下来的图片,包含了三维深度标注。
对于手掌检测器,我们只使用现场真人真手的数据集,已经足够用于定位手部的位置,而且能够提供高鲁棒性;那么我们用啥训练手部关键点检测模型腻?是用所有的数据集,既有真实的,也有生成的。至于手的置信度的模型是怎么训练的呢,我们使用了真实训练中的一些图片做正样本,再用不包含手的区域的图做负样本,用这样的正负样本来训练出一个二分类模型,来判断手出现的置信度。对于左右手呢,我们标注了真实世界中的一小部分图片,标注了左手还是右手,用这个小数据集去训练二分类模型,输出的是左手还是右手🍭🍭🍭
3.把算法部署在Mediapipe上
在Mediapipe里面,整个的工作流可以被视为下面的图。它包含了很多模块,Mediapipe为这些模块提供了一系列跨平台和跨设备的可扩展功能,比如模型的推断、媒体数据的处理、数据的变换等。单一的模块(比如裁剪、渲染、神经网络的运算)已经被Mediapipe高度优化了,用于部署在GPU的加速。
现有的工作流也包含两部分,第一部分是手掌的检测HandDetection,第二部分是手部关键点的检测HandLandmark。手掌检测只有在第一帧或是手消失的时候才会启动,一旦它启动了之后(手掌的位置获取了之后),就由HandLandmark来接管了,不需要再去重复的每一帧调用手掌的检测,这也是它核心加速的一个措施。那它是怎么实现的腻?上文有讲,是通过上一帧关键点的检测结果来预测出手掌的区域,再把手掌的区域喂给下一帧手部关键点检测的模型。
4.应用案例
手部追踪的solution呢可以快捷的用于很多增强现实的效果里,比如姿势识别。在我们预测的手部21个关键点的骨架上可以轻松的构建一个手势识别算法(如下图)。除了静态识别呢,还可以用在动态的图片序列上。另外,增强现实也大大的应用了这一模型(如下图所示)🌟🌟🌟
ending
看到这里相信盆友们都对Mediapipe手部关键点检测和追踪模型有了一个全面深入的了解啦!后续还会出一系列关于人工智能、深度学习、计算机视觉方面的文章,请多多关注我叭🌴🌴🌴很开心能把学到的知识以文章的形式分享给大家。如果你也觉得我的分享对你有所帮助,please一键三连嗷!!!下期见