MediaPipe 手势识别:“猜拳”游戏(基础篇)
作者 牟奕炫
发表于 2023年5月

在第14期的《基于MediaPipe的Python编程手势识别应用》一文中,我们借助MediaPipe实现了手部21个关键点的精准识别。MediaPipe不仅可以判断识别各个独立的关键点,如果结合某些点的区域划分进行相关的逻辑运算,就能够非常方便地进行很多手势信息的“解读”,比如识别0-9十个数,进而在树莓派中实现简易“猜拳”游戏。

1.五个指尖关键点与“凸包”区域

为了对单手所表示的十个数进行手势识别,判断五个指尖关键点(4、8、12、16、20)与手掌心范围的相互位置是非常重要的环节。手掌心范围的界定可以通过“凸包”(convexhull)来实现,建立列表变量round_points,其值为[0,1,2,3,6,10,14,19,18,17,10],表示从手腕根部0开始,向上沿大拇指依次经过1、2、3点位,转至食指的6、中指的10、无名指的14,最终从小拇指的19、18、17点位返回至手腕根部0,如此便构建了一个包含手掌心在内的闭合区域(如图1)。

通过对五个指尖点是否在“凸包”内的判断(单独的某个指尖或是几个指尖的不同组合),就能够表示出0-9这十个数字,并且将相关的代码封装成函数。

2.手势数字的判断函数

导入“mediapipeasmp”“cv2”“numpyasnp”“math”库模块。

计算两个矢量角度finger_angle(point1,point2)函数:借助numpy库再通过两次数学计算,建立变量two_angle,赋值为“np.dot(point1,point2)/(np.sqrt(np.sum(point1**2))*np.sqrt(np.sum(point2**2)))”,再赋值为“np.arccos(two_angle)/math.pi*180”,最后将该值返回即可。

判断并返回手势信息finger_sign(tip_finger,list_data)函数的编写:1和9的共同点是均通过单根食指(直立或弯曲)来表示,判断条件是“iflen(tip_finger)==1andtip_finger[0]==8:”(其中的tip_finger存储的是“凸包”外的指尖关键点),意思是“凸包”外只检测到有一个指尖(即一根手指)并且该指尖关键点是8(即食指指尖);建立两个矢量point1、point2,赋值为“list_data[6]-list_data[7]”“list_data[8]-list_data[7]”,分别计算食指关键点6至7、8至7的矢量值;再通过调用函数为变量two_angle赋值:“finger_angle(point1,point2)”,并且进行“iftwo_angle<160:”的判断,如果该角度值小于160度则认定为“弯曲的食指”,表示手势识别的结果是数字9;条件不成立,则认定为“直立的食指”,变量finger_sign存储的手势识别结果即为数字1。

本文刊登于《电脑报》2023年18期
龙源期刊网正版版权
更多文章来自
订阅