基于openpose和目标检测手势识别方案的设计

序言

最近在接触手势识别这方面的项目,在做的同时,记录下自己的方案思路,作为笔记分享和学习。只是讲大概的思路,细节不多阐述,如果有更好的方案可以私聊我一起交流。

码字不易,未经同意,请勿转载。

一、手势识别概述

谈起手势识别技术,由简单粗略的到复杂精细的,大致可以分为三个等级:二维手型识别、二维手势识别、三维手势识别。在具体讨论手势识别之前,我们有必要先知道二维和三维的差别。二维只是一个平面空间,我们可以用(X坐标,Y坐标)组成的坐标信息来表示一个物体在二维空间中的坐标位置,就像是一幅画出现在一面墙上的位置。三维则在此基础上增加了“深度”(Z坐标)的信息,这是二维所不包含的。这里的“深度”并不是咱们现实生活中所说的那个深度,这个“深度”表达的是“纵深”,理解为相对于眼睛的“远度”也许更加贴切。就像是鱼缸中的金鱼,它可以在你面前上下左右的游动,也可能离你更远或者更近。

前两种手势识别技术,完全是基于二维层面的,它们只需要不含深度信息的二维信息作为输入即可。就像平时拍照所得的相片就包含了二维信息一样,我们只需要使用单个摄像头捕捉到的二维图像作为输入,然后通过计算机视觉技术对输入的二维图像进行分析,获取信息,从而实现手势识别。

而第三种手势识别技术,是基于三维层面的。三维手势识别与二维手势识别的最根本区别就在于,三维手势识别需要的输入是包含有深度的信息,这就使得三维手势识别在硬件和软件两方面都比二维手势识别要复杂得多。相比于前两种二维手势识别技术,三维手势识别不能再只使用单个普通摄像头,因为单个普通摄像头无法提供深度信息。对于一般的简单操作,比如只是想在播放视频的时候暂停或者继续放映,二维手势也就足够了。但是对于一些复杂的人机交互,比如玩游戏或者应用在VR(虚拟现实)上,三维手势实在是居家旅行必备、舍我其谁的不二之选。

因为在我们的项目中并不涉及太复杂的交互功能,所以仅采用了基于二维的手势识别,和简单的石头、剪刀、布手势识别不同,诸如此类的手势识别更多的是用来玩,而本文说的手势识别希望应用在智慧屏上,也就是通过手势识别功能实现无接触的屏幕滑动、翻页、开关文件夹等操作。脑补一下,如果你前面有一个大屏幕,如果你要去操作它,你是打算使用鼠标?还是走到它前面用手指触摸去操作它呢?能想象出来有多不方便,所以就需要一种无接触的屏幕交互功能,这时候手势识别就派上用场了。

二、设计思路

首先想到的是开源的OpenPose,OpenPose人体姿态识别项目是美国卡耐基梅隆大学(CMU)基于卷积神经网络和监督学习并以caffe为框架开发的开源库。可以实现人体动作、面部表情、手指运动等姿态估计。适用于单人和多人,具有极好的鲁棒性。是世界上首个基于深度学习的实时多人二维姿态估计应用。因为该项目能够回归出人体关键点、手部关键点和人脸关键点,基于这个项目自然也可以实现手势识别的功能。
在这里插入图片描述

OpenPose项目Github链接:https://github.com/CMU-Perceptual-Computing-Lab/openpose

但是如果你深入了解openpose,就会发现,它的效果虽然好,但是你要想应用它,就难免要考虑它模型的大小、算法的复杂度、实时性等问题,而且要想优化它的话,还是需要一点功底的。所以为了方便改进,这里采用一分为二的思想,采用骨骼关节点+目标检测,这样一来我们就可以从两个方向去进行优化。

首先是骨骼关键点,这里还是采用了openpose作为关键点检测,但是不是使用它的原生版本,而是采用了轻量型基于pytorch的openpose,并且只检测人体的18个关节点,虽然精度相对于原生的openpose有一定下降,但是速度上是非常快的,并且在一些简单的场景下是完全够用的,效果如下所示:
在这里插入图片描述
看到这里,你可能会有疑问,手势识别不识别手部关键点,只识别骨骼关键点有什么作用?不急,往下看。

第二部分是目标检测部分,这部分是通过目标检测去检测定义的手部动作,比如我这里定义了如下7种动作手势,分别是上、下、左、右、拳头、手掌、1。然后使用目标检测去检测这几种手势,考虑到实时性和精度,这里的目标检测采用了yolo去做。
在这里插入图片描述
这里使用目标检测(YOLO)的结果如下所示:
在这里插入图片描述
看到这里可能就会疑惑,明明精度还不错,为什么还要结合openpose去做?而不是单纯只使用目标检测就好了呢?其实目标检测在实际的场景中,精度通常是我们最关心的一点,正常的手势检测出来肯定是没有问题的,但是你训练的是手部姿势检测啊,难免会把其他动作的手势也给误检进去,所以我们就需要一个起始检测条件控制检测的误检率,当触发这个条件时,就送入目标检测网络中进行检测,如果不触发,就不检测手势。这样一来,误检率是不是大大降低了呢。所以这时候就需要想一想,这个起始的检测条件设置为什么样是最合理的呢?

为了更好的想象,来看一张openpose的关节点的完全展示图。先思考一下…
在这里插入图片描述

再结合我们实际场景中openpose的关节点识别图来看,是不是看出了什么规律?即当人在做手势时,碗关节的点是要高于肘关节的,这样一来,我们就可以在第一步中定义:当 **碗关节点(4、7)在二维坐标系上y坐标高于肘关节点(3、6)**时(通常只选一边即可,因为考虑到有可能存在左撇子的情况),触发手部手势检测的条件,否则不检测,这样一来,误检率就得到了很好的控制。
在这里插入图片描述
回到目标检测,模型训练可以参考我之前的文章,只不过之前的文章是用的nanodet去训练,效果一般,最后还是用的yolov5和yolo-fastest。yolo的训练大同小异,网上很多教程,数据集的准备参考nanodet训练手势识别模型即可。

三、效果展示

说到这里应该已经清楚了openpose+yolo的手势识别是怎么做了吧。最后把两个模型给串起来,在GPU下可以看到模型是可以达到30FPS以上的,并且还没有在tensorrt等其他推理加速的框架上优化,先放个效果图
在这里插入图片描述
那么接下来的工作就是模型压缩加速、精度优化了,因为两个部分都是可以单独的拿出来优化,所以分开实现起来也相对要容易一些。openpose使用的是轻量型的骨干,还可以继续对其进行压缩,或者选用其他更轻量的人体姿态估计网络,目标检测部分同理。这里就不再多说了,这也是我后面要做的工作,后面如果有机会再介绍。

四、需要考虑的问题

如果一个项目像说的这么简单就好了,可是啊,偏偏还是会有很多大大小小的问题,这里罗列几点给供大家思考,也是后续要注意的问题:

  1. 如果在检测部分还是检测到了多个手(精度不够带来的误检),该如何筛选其中发指令的那个手?或者用什么方法可以进一步提升模型的识别精度?
  2. 如果屏幕前的人不是站着,手不是垂直向下摆放,碗关节点高于肘关节点的起始检测条件是否适用?是否考虑预设另一种起始检测条件?
  3. 如果屏幕前有多个人,怎么确定谁的手才是发指令的那个?
  4. 太灵敏的检测效果需要设置一个手势识别动作的响应条件或者响应时间,比如连续多少帧识别到该手势则指令生效等等。
  5. 其他问题。

五、代码参考

代码就不开源了,文中提到的一些参考代码链接如下,结合实现起来并不难。

https://github.com/CMU-Perceptual-Computing-Lab/openpose
https://github.com/ultralytics/yolov5
https://github.com/RangiLyu/nanodet
https://github.com/dog-qiuqiu/Yolo-Fastest
https://codechina.csdn.net/mirrors/Daniil-Osokin/lightweight-human-pose-estimation.pytorch
https://codechina.csdn.net/mirrors/YuliangXiu/MobilePose-pytorch
https://codechina.csdn.net/EricLee/handpose_x

  • 15
    点赞
  • 125
    收藏
    觉得还不错? 一键收藏
  • 16
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值