推荐运行环境
使用anaconda创建环境,以免污染原来的python开发环境
conda install python=3.9
pip install -q mediapipe==0.10.0
pip install pyautogui
Python: version 3.8 - 3.11
PIP: version 20.3+
请注意以下的坑
以下为我测试过程中的大坑,请及时避开!!!
出现如下错误:
RuntimeError: File loading is not yet supported on Windows
mediapipe0.9 版本太低
出现如下错误:
RuntimeError: Unable to open file at gesture_recognizer.task
base_options = python.BaseOptions(model_asset_path='gesture_recognizer.task')
gesture_recognizer.task 所在路径不能包含中文名称
项目概述:
通过手势识别实现了控制 PowerPoint 播放幻灯片的功能。在识别到特定手势("Open_Palm")时,会模拟按下 "Page Down" 键,从而使幻灯片向下翻页。同时,通过 PyAutoGui(用python 实现朋友圈自动点赞_python朋友圈自动点赞-CSDN博客) 控制鼠标和键盘进行交互操作。整个流程包括捕获视频帧、进行手势识别、根据识别结果执行相应操作等步骤。
原项目帮助文档:
https://developers.google.com/mediapipe/solutions/vision/gesture_recognizer
-
Mediapipe 库介绍
Mediapipe 是由 Google 开发的一个开源库,旨在简化构建实时视觉和机器学习应用程序的过程。这个库提供了一系列预训练模型、工具和流水线,能够帮助开发者快速地开发各种涉及计算机视觉、姿态估计、手部追踪、物体检测、语义分割等任务的应用。
以下是 Mediapipe 库的一些特点和功能:
-
实时性:Mediapipe 库专注于实时应用程序的开发,能够在较短的时间内处理视频流或摄像头输入,并输出相应的结果。这使得它适用于实时交互应用、增强现实(AR)、虚拟现实(VR)等领域。
-
预训练模型:Mediapipe 提供了多个预训练模型,包括人体姿态估计、手部关键点检测、面部检测、物体识别等,为开发者提供了便捷的解决方案,无需从头开始训练模型。
-
模块化设计:Mediapipe 的设计是模块化的,允许开发者根据需求自由组合各种组件,构建出符合自己应用需求的流水线。
-
跨平台:Mediapipe 支持在不同平台上运行,包括桌面端、移动设备、嵌入式设备等,使得开发者可以轻松地将其应用部署到不同的环境中。
-
易于使用:Mediapipe 提供了丰富的文档、示例代码和教程,帮助用户快速上手并构建自己的视觉应用程序。同时,它还支持多种编程语言,包括 Python、C++ 等。
通过 Mediapipe 库,开发者可以快速实现复杂的计算机视觉任务,加速应用程序的开发过程,同时享受到高效、稳定的模型性能和准确度。这使得 Mediapipe 成为一个强大的工具,为开发者在视觉和机器学习领域提供了丰富的功能和资源。
这个模型能识别七种手势:
0 - Unrecognized gesture, label: Unknown 1 - Closed fist, label: Closed_Fist ✊ 2 - Open palm, label: Open_Palm 👋 3 - Pointing up, label: Pointing_Up ☝️ 4 - Thumbs down, label: Thumb_Down 👎 5 - Thumbs up, label: Thumb_Up 👍 6 - Victory, label: Victory ✌️ 7 - Love, label: ILoveYou 🤟
在线演示地址:
http:// https://mediapipe-studio.webapps.google.com/studio/demo/gesture_recognizer
-
Hand landmark模型
Hand landmark 模型是 Mediapipe 库中的一种模型,专门用于手部姿势估计和手势识别。该模型可以检测手部关键点,包括手指、手掌、手腕等部位,并提供准确的手部姿势信息。通过 Hand landmark 模型,开发者可以实现精细的手部动作追踪、手势识别、手语翻译等应用。
以下是 Hand landmark 模型的一些特点和功能:
-
关键点检测:Hand landmark 模型能够检测手部关键点,包括21个关键点,涵盖手掌、手指和手腕等部位。这些关键点对于描述手部姿势和手势非常重要。
-
精准度:Hand landmark 模型在识别手部关键点方面具有很高的精准度,可以准确地捕捉手部各部位的位置和姿势。
-
实时性:Hand landmark 模型可以在实时视频流中运行,实现实时的手部姿势估计和跟踪,适用于实时交互应用。
-
多手支持:该模型支持检测多只手,可以同时处理多只手部的姿势并提取出相应的关键点信息。
-
模型优化:Hand landmark 模型经过优化,能够在移动设备上高效运行,提供良好的性能和准确度。
通过使用 Hand landmark 模型,可以构建各种基于手部姿势的应用程序,如手势控制、手部动作追踪游戏、手势识别交互界面等。这个模型为开发者提供了一个强大的工具,帮助他们在视觉和交互领域创造更加丰富、生动的体验。
-
手势辨识模型gesture_recognizer.task下载地址
https://storage.googleapis.com/mediapipe-models/gesture_recognizer/gesture_recognizer/float16/1/gesture_recognizer.task
PowerPoint 常用快捷鍵
【Page Up】或【↑】或【←】 上一张
【Page Down】或【↓】或【→】 下一张
【F5】 开始播放幻灯片
【Home】 回到幻灯片第一页
【Esc】 结束放映
以下为完整程序,给出了详尽的注释
"""
gesture_control_ppt.py
"""
import mediapipe as mp
from mediapipe.tasks import python
from mediapipe.tasks.python import vision
from mediapipe.framework.formats import landmark_pb2
import cv2
import numpy
import pyautogui as ag
mp_hands = mp.solutions.hands # 检测手势
mp_drawing = mp.solutions.drawing_utils # 在图像上绘制检测到的结果,如手势、特征点等
mp_drawing_styles = mp.solutions.drawing_styles # 定义绘制样式的模块
def display_gesture_and_hand_landmarks(images, gestures, hand_landmarks):
# 将图像 images 转换为 NumPy 数组
image = images.numpy_view()
# 提取最顶层手势信息和手部特征点列表
# “最顶层”可能表示检测到的主要手势或优先级最高的手势。通过选择第一个手势或者根据算法返回的置信度来确定最顶层手势。
top_gestures = [gestures for gestures in gestures]
hand_landmarks_list = [hand_landmarks for hand_landmarks in hand_landmarks] # 存储了手部特征点的坐标数据
title = '' # 初始化标题字符串
gesture_name = '' # 初始化手势名称字符串
'''
当检测到手势信息时,从第一个手势中提取手势的名称和置信度得分,
然后构建一个带有手势名称和置信度的标题字符串,
以便将这些信息显示在图像上。这样做可以帮助用户了解检测到的主要手势类型及其对应的置信度评分。
'''
if numpy.size(top_gestures) != 0:
gesture_name = top_gestures[0][0].category_name
gesture_score = top_gestures[0][0].score
title = f"{gesture_name}({gesture_score:.2f})"
# 创建图像的副本以进行标注
annotated_image = image.copy()
# 如果检测到手部特征点列表,则对每个手部特征点列表进行处理
if numpy.size(hand_landmarks_list) != 0:
for hand_landmarks in hand_landmarks_list:
hand_landmarks_proto = landmark_pb2.NormalizedLandmarkList()
hand_landmarks_proto.landmark.extend([
landmark_pb2.NormalizedLandmark(x=landmark.x, y=landmark.y, z=landmark.z) for landmark in hand_landmarks
]) # 通过使用列表推导式,将每个手部特征点的 x、y、z 坐标数据添加到 hand_landmarks_proto 中。
# 在图像上绘制手部特征点和连接线
mp_drawing.draw_landmarks(
annotated_image, # 表示要在其上绘制手部特征点和连接线的图像对象
hand_landmarks_proto, # 包含手部特征点坐标数据的对象
mp_hands.HAND_CONNECTIONS, # 指定手部特征点之间的连接关系,以便绘制连接线
mp_drawing_styles.get_default_hand_landmarks_style(), # 表示用于绘制手部特征点的样式,包括颜色、线宽等信息
mp_drawing_styles.get_default_hand_connections_style()) # 表示用于绘制手部连接线的样式,同样包括颜色、线宽等信息
# 在图像上添加标题文本
cv2.putText(annotated_image, f"{title}",
(20, 30), cv2.FONT_HERSHEY_DUPLEX,
1, (0, 0, 255), 1, cv2.LINE_AA)
# 返回带有标注信息和手势名称的图像及手势名称
return annotated_image, gesture_name
# 移动鼠标指针,点击并按 F5 键
ag.moveTo(852, 125, 1) # 幻灯片坐标的确定可以使用截图软件Snipaste, 这是我笔记本上的坐标
ag.click()
ag.press('f5')
# 创建一个 GestureRecognizer 对象
# 帮助文档 https://developers.google.com/mediapipe/api/solutions/python/mp/tasks/vision
base_options = python.BaseOptions(model_asset_path='gesture_recognizer.task') # 该文件路径不能包含中文名
options = vision.GestureRecognizerOptions(base_options=base_options)
recognizer = vision.GestureRecognizer.create_from_options(
options)
cap = cv2.VideoCapture(0)
# 以下实时处理来自摄像头的视频流并进行手势识别
while True: # 无限循环,持续从摄像头读取帧,并进行手势识别和处理
ret, frame = cap.read() # 从摄像头(或视频文件)中读取一帧图像数据
mp_image = mp.Image(image_format=mp.ImageFormat.SRGB, data=frame) # 将读取的图像帧转换为 Mediapipe 图像对象
recognition_result = recognizer.recognize(mp_image) # 使用手势识别器(recognizer)对图像进行手势识别,返回手势识别的结果
top_gesture = recognition_result.gestures # 提取手势识别结果中的顶层手势信息
hand_landmarks = recognition_result.hand_landmarks # 提取手势识别结果中的手部特征点信息
annotated_image, gesture_name = display_gesture_and_hand_landmarks(mp_image, top_gesture,
hand_landmarks) # 调用显示函数,生成带有标注的图像并获取手势名称
cv2.imshow('frame', annotated_image) # 在窗口中显示带有手势标注的图像
# 可以将手势换成 "Closed_Fist", "Open_Palm", "Pointing_Up", "Thumb_Down", "Thumb_Up", "Victory"
if gesture_name == "Open_Palm":
ag.press('pagedown')
ag.PAUSE = 1
# 按Esc键退出循环
if cv2.waitKey(1) == 27:
break
cap.release()
cv2.destroyAllWindows()
程序运行
1、如果单屏(多屏,两个应用程序可以在不同屏上演示更好),先打开幻灯片,我是用PowerPoint打开的。如果你用其它软件打开,请自己确定打开的坐标,修改ag.moveTo(852, 125, 1) 中坐标的值。
2、运行gesture_control_ppt.py,最小化pycharm窗口,PPT程序在最上面
3、当摄像头亮起时,用Open_Palm👋手势控制。
4、切换到视频窗口点击,按ESC退出程序。
幻灯片坐标的确定可以使用截图软件Snipaste来确定。
演示,因为只能上传gif,只是意思一下