于方军 山东省淄博市博山区山头中心学校
孙燕 山东省淄博市博山区基础教育发展研究中心
孙丽君 山东省淄博第二中学
人体姿态识别(Pose Estimation)是检测图像或者视频中人体关键点的位置、构建人体骨架图的过程。在常见的人体姿态识别算法中,OpenPose算法采用“自底向上”的检测算法,是先检测关键点,再把相关关键点连成人体。最新版MMPose算法复现了多种人体姿态分析模型,其中包括“自顶向下”算法和“自底向上”算法(先识别人体,再检测关键点),还开发了多种动物姿态识别算法。MediaPipe的姿态检测采用的是BlazePose算法,这是一个轻量级的卷积神经网络架构,是为移动设备上的实时检测量身定做的,即把人体姿态图像抽象为33个关键点(如图1),用它完成人体姿态快速检测、体育课上“深蹲”“俯卧撑”“引体向上”等动作检测及分析指导。
下面,笔者就从获取关键点坐标入手,借助开源硬件完成一个深蹲到位检测器,通过拍摄“俯卧撑”图片作为数据集,并采用K-NN算法完成一个“俯卧撑”计数器设计。
在本案例中,在完成深蹲到位检测时,硬件选用的是arduino板,并用pinpong库进行控制。
(1)在做“深蹲”动作时,人体臀部关键点(图1中的23.left_hip、24.right_hip)坐标、膝部关键点(图1中的25.left_knee、26.right_knee)坐标都会有明显变化,本案例为了简化代码,只获取了左臀、左膝关键点坐标,站立时,左臀左膝的x坐标差值很小,y坐标差值很大,蹲下时,x差值变大,y坐标差值变小。通过实践调试,设置x坐标差值大于10、y坐标差值小于10为蹲下姿态,反之为站立姿态,如表1所示。
图1
表1 左臀左膝关键点坐标读取及应用
(2)设置arduino板的11脚为输出,LED灯接到该脚,同时用pinpong库控制arduino,用pip install pinpong安装该库,使用时需要定义好输出脚,并运行代码,进而根据实时采集到的左臀左膝关键点坐标差值控制接在arduino板11脚的灯亮灭。代码设置蹲下时点亮LED灯,如图2所示。
要进行复杂动作的识别检测,可以将计算不同姿态时关键点之间的距离特征作为判断依据,即使用K-NN最近邻算法实现姿态检测的原理。
下面,以俯卧撑为例,拍摄“俯卧”姿态和“撑起”姿态的照片,每个姿态拍摄20张以上,每隔一定角度拍一张,采集人体姿态关键点的数据信息作为训练数据集。使用这些关键点的坐标信息构建的数据集,通过计算关键点相对距离,判断不同姿态。计算过程可以在CPU模式下高效完成训练和识别。
在本例中,根据姿态照片将关键点的信息采集后存为CSV文件,并用K-NN最近邻算法,完成神经网络训练和识别。
(1)将把拍摄的图片放入“pushup”和“pushdown”两个姿态文件夹,并把文件夹名作为姿态标签名称。需要的数据为图片、带关键点信息图片、姿态标签,具体如下页表2所示。
表2
接着,用代码分析标记采集的图片数据集,用push_up.csv、push_down.csv保存对应文件夹中每张图片关键点坐标信息,第一列记录是一张图片的名称信息,后面99个信息代表人体33个特征点,每个特征点记录x、y、z三个坐标信息,如下页图3所示。
图3
(2)K-NN最近邻算法采用测量不同特征值之间的距离方法进行分类,在本例中被判断的姿态样本,要和训练集提供的“撑起”“俯卧”动作姿态进行比较,找到最接近的目标姿态,即与“撑起”特征接近就判断为撑起,与“俯卧”的姿态接近就判断为俯卧,达到一个俯卧、撑起设定数值就表示完成一个俯卧撑。
这两种姿态特征可以通过计算各个关键点的距离来表示,如撑起时手腕和肩膀、肘部和肩膀、脚踝和臀部以及两个手腕之间的距离。然后通过计算被预测图片的这些距离和训练集中的撑起、俯卧数据进行判断,如果数据接近撑起的多就是撑起,反之就是俯卧。需要注意的是,在选择时,可以根据运动的特点选择所要计算的距离对,如引体向上可能更加关注上半身的距离对,如下页图4所示。
图4
在输入需要判断的姿态图片后,就可以将姿态图片的关键点坐标数据与训练集中数据对应的特征进行比较,然后算法提取样本集中特征最相似数据(最近邻)的分类标签。一般来说,会选择样本集中前K个(本例中是前10个)最相似的数据,这就 是K近 邻算法中K的出处,选择K个最相似姿态数据中出现次数最多的分类,作为新姿态的分类。
(3)为了获得更好的分类结果,笔者使用不同的距离度量调用了两次K-NN搜索:先按最大距离过滤掉训练集中的异常图片,然后使用平均坐标距离找到最接近的姿态类型。K-NN算法分类过程部分代码如图5所示。
图5
与经典的K-NN算法数据集相比,本案例中对人体姿态的判别,既能与学生日常学习生活有关联,又能方便地采集并生成自己的数据集,在培养学生计算思维的同时也有助于学生对人工智能算法的理解。