用Python+MediaPipe+OpenCV做个手势识别小游戏:5分钟搞定石头剪刀布
5分钟用Python打造手势识别游戏石头剪刀布实战指南手势识别技术正在改变人机交互的方式。想象一下只需对着摄像头比划手势就能与计算机进行游戏对战——这不再是科幻电影的场景而是你可以在短短几分钟内实现的Python项目。本文将带你从零开始利用MediaPipe和OpenCV构建一个完整的石头剪刀布手势识别游戏让技术学习变得生动有趣。1. 环境准备与基础配置1.1 安装必要库文件开始前需要确保Python环境已就绪推荐3.7版本。打开终端执行以下命令安装核心依赖pip install opencv-python mediapipe numpy这三个库各司其职OpenCV处理摄像头输入和图像显示MediaPipe提供高精度手势识别模型NumPy进行坐标计算和游戏逻辑处理注意MediaPipe对版本较敏感若遇到兼容性问题可指定版本安装pip install mediapipe0.8.111.2 初始化摄像头与识别模型创建game.py文件导入库并初始化基础组件import cv2 import mediapipe as mp import numpy as np # 初始化MediaPipe手部模型 mp_hands mp.solutions.hands hands mp_hands.Hands( static_image_modeFalse, max_num_hands1, # 只需识别单手 min_detection_confidence0.7 ) # 启动摄像头 cap cv2.VideoCapture(0)关键参数说明static_image_modeFalse优化视频流处理性能max_num_hands1石头剪刀布只需识别一只手min_detection_confidence0.7平衡识别精度和响应速度2. 手势识别核心实现2.1 实时处理视频流建立主循环框架持续读取摄像头画面while cap.isOpened(): success, frame cap.read() if not success: continue # 水平翻转画面获得镜像效果 frame cv2.flip(frame, 1) # 转换色彩空间供MediaPipe处理 rgb_frame cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) results hands.process(rgb_frame) # 显示原始画面 cv2.imshow(Gesture Game, frame) if cv2.waitKey(5) 0xFF 27: # ESC退出 break2.2 关键点分析与手势判断MediaPipe会返回21个手部关键点的三维坐标。我们需要根据特定关键点的位置关系判断手势def recognize_gesture(landmarks): # 获取指尖和手掌根部关键点 tip_ids [4, 8, 12, 16, 20] # 拇指到小指尖 root_joint landmarks[0] # 手腕根部 fingers [] # 拇指特殊处理x轴比较 thumb_tip landmarks[tip_ids[0]] if thumb_tip.x root_joint.x: fingers.append(1) else: fingers.append(0) # 其他四指判断y轴比较 for id in range(1, 5): if landmarks[tip_ids[id]].y landmarks[tip_ids[id]-2].y: fingers.append(1) # 手指伸直 else: fingers.append(0) # 手指弯曲 # 手势判断逻辑 total_fingers sum(fingers) if total_fingers 0: return rock elif total_fingers 2: if fingers[1] and fingers[2]: # 仅食指和中指伸直 return scissors elif total_fingers 5: return paper return None手势判定标准石头所有手指弯曲检测到0个伸直手指剪刀仅食指和中指伸直检测到2个特定伸直手指布所有手指伸直检测到5个伸直手指3. 游戏逻辑与交互设计3.1 胜负判定系统添加游戏状态管理类来跟踪比赛进程class GameState: def __init__(self): self.player_gesture None self.computer_choice None self.result None self.score 0 def decide_winner(self): choices [rock, paper, scissors] self.computer_choice np.random.choice(choices) if self.player_gesture self.computer_choice: self.result tie elif (self.player_gesture rock and self.computer_choice scissors) or \ (self.player_gesture scissors and self.computer_choice paper) or \ (self.player_gesture paper and self.computer_choice rock): self.result win self.score 1 else: self.result lose game GameState()3.2 可视化反馈增强在画面中添加游戏状态显示def draw_ui(frame, game_state): # 显示当前得分 cv2.putText(frame, fScore: {game_state.score}, (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2) if game_state.player_gesture: # 显示玩家和电脑的选择 cv2.putText(frame, fYou: {game_state.player_gesture}, (10, 70), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2) cv2.putText(frame, fComputer: {game_state.computer_choice}, (10, 110), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2) # 显示比赛结果 color (0, 255, 0) if game_state.result win else \ (0, 0, 255) if game_state.result lose else \ (255, 255, 0) cv2.putText(frame, game_state.result.upper(), (10, 150), cv2.FONT_HERSHEY_SIMPLEX, 1, color, 2) return frame4. 系统集成与性能优化4.1 主循环完整实现将所有组件整合到主循环中while cap.isOpened(): success, frame cap.read() if not success: continue frame cv2.flip(frame, 1) rgb_frame cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) results hands.process(rgb_frame) # 手势识别 if results.multi_hand_landmarks: for hand_landmarks in results.multi_hand_landmarks: # 绘制手部关键点 mp.solutions.drawing_utils.draw_landmarks( frame, hand_landmarks, mp_hands.HAND_CONNECTIONS) # 获取手势类型 game.player_gesture recognize_gesture(hand_landmarks.landmark) if game.player_gesture: game.decide_winner() # 绘制游戏界面 frame draw_ui(frame, game) # 添加操作提示 cv2.putText(frame, Press SPACE to play again, (10, 400), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 255, 255), 1) cv2.putText(frame, ESC to exit, (10, 430), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 255, 255), 1) cv2.imshow(Gesture Game, frame) key cv2.waitKey(5) if key 0xFF 27: # ESC退出 break elif key 0xFF 32: # 空格重置游戏 game GameState()4.2 常见问题解决方案遇到以下情况时可参考这些调试技巧问题现象可能原因解决方案无法识别手势光照条件差确保手部光照均匀背景不复杂识别延迟高硬件性能不足降低摄像头分辨率cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640)误识别率高手势标准度不够调整min_detection_confidence参数关键点抖动视频帧率不稳定添加简单滤波算法平滑关键点坐标完整项目可进一步扩展的方向添加手势训练模式支持自定义手势集成声音反馈增强游戏体验增加多人对战模式开发GUI界面替代控制台显示这个项目最令人兴奋的部分是看到抽象的技术概念转化为具体的交互体验。当第一次成功用剪刀击败电脑的布时那种术落地的成就感正是编程最有魅力的地方。建议尝试调整手势判定阈值来优化识别准确率每个开发者的最佳参数可能因摄像头和环境而异。