尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

MediaPipe 实现实时手势数字识别(0-10 手势计数)完整代码 + 原理讲解

MediaPipe 实现实时手势数字识别(0-10 手势计数)完整代码 + 原理讲解
📅 发布时间:2026/7/18 22:53:12

一、项目简介

本文基于 Google 开源的 MediaPipe 手部识别方案,结合 OpenCV 调用本地摄像头,通过手掌 21 个手部关键点坐标计算距离,判断伸直手指数量,实现实时 0-10 数字手势识别。 无需深度学习模型训练,开箱即用,运行速度快,适合手势交互、简易数字识别、课堂手势计数等轻量化场景。

二、环境依赖安装

只需要安装两个库,命令行执行:

bash

运行

pip install opencv-python mediapipe
  • opencv-python:摄像头读取、画面渲染、图像色彩转换
  • mediapipe:Google 手部关键点检测框架,内置轻量化手部识别模型,支持单 / 双手检测

三、核心原理讲解

1. MediaPipe 手部关键点分布

手掌一共输出 21 个归一化坐标点(x/y 范围 0~1),本代码用到关键点位:

  • 0 号点:手掌根部(腕关节)
  • 4 号点:大拇指指尖
  • 5 号点:食指根部关节
  • 8 号点:食指指尖
  • 12 号点:中指指尖
  • 16 号点:无名指指尖
  • 20 号点:小指指尖
2. 手指伸直判断逻辑
  1. 基准长度校准用腕关节 0 点与食指根部 5 点的距离作为手掌基准长度,消除远近、手掌大小带来的坐标偏差:base = distance_0_5 / 0.6
  2. 四根常规手指(食 / 中 / 无名 / 小指)计算腕部 0 点到各指尖的欧式距离平方,若距离大于基准值,判定手指伸直,flag 计数 + 1;
  3. 大拇指特殊判定大拇指活动方式与其余四指不同,改用食指根部 5 点到大拇指 4 点距离做阈值判断,阈值缩小为base*0.3;
  4. 手势映射flag 代表伸直手指总数,对应列表gesture = ["none", "one", "two"...,"ten"],实时打印对应数字手势。
3. 图像预处理说明

MediaPipe 模型要求输入 RGB 图像,但 OpenCV 读取摄像头默认为 BGR 格式,因此需要两次色彩转换:

  1. 摄像头画面 BGR → RGB 送入手部模型推理
  2. 推理完成 RGB → BGR 用于 OpenCV 绘图、显示 额外增加cv2.flip(frame,1)水平镜像,符合人眼正常视觉习惯。

四、完整可运行代码

python

运行

import cv2 import mediapipe as mp # 手势标签,flag对应伸直手指数量 gesture = ["none", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"] flag = 0 # 初始化mediapipe绘图工具与手部检测模块 mp_drawing = mp.solutions.drawing_utils mp_hands = mp.solutions.hands # 手部检测参数配置 hands = mp_hands.Hands( static_image_mode=False, # False视频流模式,True静态图片模式 max_num_hands=2, # 最多检测2只手 min_detection_confidence=0.75,# 手部检测最低置信度 min_tracking_confidence=0.75 # 手部跟踪最低置信度 ) # 打开本地摄像头 cap = cv2.VideoCapture(0) while True: flag = 0 # 每帧重置手指计数 ret, frame = cap.read() if not ret: print("无法读取摄像头画面") break # BGR转RGB供mediapipe处理 frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) # 水平翻转,消除镜像 frame = cv2.flip(frame, 1) # 手部关键点推理 results = hands.process(frame) # 转回BGR用于opencv绘图显示 frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR) # 如果检测到手部关键点 if results.multi_hand_landmarks: for hand_landmarks in results.multi_hand_landmarks: # 0:腕部坐标,5:食指根部坐标,计算手掌基准长度 p0_x = hand_landmarks.landmark[0].x p0_y = hand_landmarks.landmark[0].y p5_x = hand_landmarks.landmark[5].x p5_y = hand_landmarks.landmark[5].y distance_0_5 = pow(p0_x - p5_x, 2) + pow(p0_y - p5_y, 2) base = distance_0_5 / 0.6 # 大拇指4号指尖距离计算 p4_x = hand_landmarks.landmark[4].x p4_y = hand_landmarks.landmark[4].y distance_5_4 = pow(p5_x - p4_x, 2) + pow(p5_y - p4_y, 2) # 食指8、中指12、无名指16、小指20指尖距离 p8_x, p8_y = hand_landmarks.landmark[8].x, hand_landmarks.landmark[8].y distance_0_8 = pow(p0_x - p8_x, 2) + pow(p0_y - p8_y, 2) p12_x, p12_y = hand_landmarks.landmark[12].x, hand_landmarks.landmark[12].y distance_0_12 = pow(p0_x - p12_x, 2) + pow(p0_y - p12_y, 2) p16_x, p16_y = hand_landmarks.landmark[16].x, hand_landmarks.landmark[16].y distance_0_16 = pow(p0_x - p16_x, 2) + pow(p0_y - p16_y, 2) p20_x, p20_y = hand_landmarks.landmark[20].x, hand_landmarks.landmark[20].y distance_0_20 = pow(p0_x - p20_x, 2) + pow(p0_y - p20_y, 2) # 判断四根手指是否伸直 if distance_0_8 > base: flag += 1 if distance_0_12 > base: flag += 1 if distance_0_16 > base: flag += 1 if distance_0_20 > base: flag += 1 # 判断大拇指是否伸出 if distance_5_4 > base * 0.3: flag += 1 # 最大限制10根手指(双手) if flag >= 10: flag = 10 # 绘制手部21个关键点与连接线 mp_drawing.draw_landmarks(frame, hand_landmarks, mp_hands.HAND_CONNECTIONS) # 在画面左上角显示识别结果 cv2.putText(frame, gesture[flag], (50, 50), 0, 1.3, (0, 0, 255), 3) # 窗口展示画面 cv2.imshow('MediaPipe Hands', frame) # 按下ESC键退出循环 if cv2.waitKey(1) & 0xFF == 27: break # 释放资源 cap.release() cv2.destroyAllWindows()

五、代码分段详细解析

1. MediaPipe 手部检测初始化参数

python

运行

hands = mp_hands.Hands( static_image_mode=False, max_num_hands=2, min_detection_confidence=0.75, min_tracking_confidence=0.75 )
  • static_image_mode=False:视频流模式,启用手部跟踪加速推理,帧率更高;图片识别改为 True;
  • max_num_hands=2:支持左右手同时识别,最高可检测双手 10 根手指;
  • 两个 confidence 阈值:过滤低置信度误识别,阈值越高识别越严格。
2. 距离平方代替欧式距离

代码全部使用pow(x差,2)+pow(y差,2)计算距离平方,不开根号,减少浮点运算,提升实时推理速度,不影响大小比较逻辑。

3. 自适应基准 base 解决远近干扰

直接使用固定距离阈值会出现:手靠近镜头判定全伸直、远离镜头判定全弯曲。 代码利用手掌自身尺寸做自适应基准,无论手掌远近,判定标准统一,鲁棒性更强。

4. 双手兼容逻辑

单只手最多 5 根手指,双手最多 10 根,flag >=10限制最大计数为 10,对应 gesture 列表 ten。

5. 可视化与退出逻辑
  • mp_drawing.draw_landmarks:自动绘制手掌 21 个关键点 + 骨骼连线,直观观察手部识别效果;
  • cv2.putText:红色粗字体实时展示当前识别数字;
  • waitKey(1)监听键盘,按下 ESC(27)关闭摄像头窗口。

六、运行效果说明

  1. 运行代码自动弹出摄像头窗口,画面左右镜像;
  2. 伸出对应数量手指,左上角实时显示 one/two/three...ten;
  3. 无手进入画面显示 none;
  4. 双手同时伸出最多显示 ten;
  5. 画面上会绘制彩色手掌骨骼关键点,方便调试识别异常。

七、常见问题优化方案

  1. 识别不准、手指计数乱跳
    • 调高min_detection_confidence至 0.85;
    • 调整base = distance_0_5 / 0.6中的 0.6 阈值,根据自己摄像头微调;
  2. 大拇指识别错误修改大拇指阈值base * 0.3,增大 / 缩小系数适配手势;
  3. 画面卡顿
    • 降低摄像头分辨率;
    • 将max_num_hands改为 1,只检测单手;
  4. 不需要镜像画面删除frame = cv2.flip(frame, 1)这一行即可。

八、拓展改进方向

  1. 增加手势分类:剪刀、石头、布等自定义手势;
  2. 保存手势截图,制作手势数据集;
  3. 结合串口 / 单片机,手势控制硬件设备;
  4. 替换距离判断逻辑,使用关键点角度判断手指弯曲程度,识别精度更高;
  5. 增加左右手区分,分别计数。

九、总结

MediaPipe 手部检测上手成本极低,无需训练模型,依靠内置预训练模型即可快速完成手部关键点提取。本文通过简单几何距离计算实现 0~10 数字手势识别,代码轻量化、实时性强,适合入门学习手部视觉交互开发,可拓展到人机交互、体感控制、课堂答题计数等场景。

相关新闻

  • 天梭官方售后服务中心电话和完整维修地址实地考察报告+多信源验证(2026年7月更新) - 天梭服务中心
  • 如何快速掌握Loop窗口管理:新手入门完整指南
  • 南昌游客必吃火锅怎么选?3个核心维度避坑,附主流品牌对比 - 品牌2026推荐

最新新闻

  • 河南地区球墨铸铁井盖厂哪家好 2026年采购选型全攻略 - 热点品牌推荐
  • 2026年古建长廊源头厂家如何选 实用选型靠谱全攻略 - 热点品牌推荐
  • HTTP/1.1、HTTP/2、HTTP/3 对爬虫到底有什么影响?
  • Claude 连不上数据库?MCP 服务器 30 分钟从零搭一个
  • 【JVM原理详解】01-从一次编写到处运行到JVM
  • 2026年福州选少儿艺术机构 舞蹈口碑几家实用参考 - 热点品牌推荐

日新闻

  • SaaS软件行业GEO实践:AI搜索时代的品牌可见性与获客新路径
  • 什么是PCTFE?医药高端包装的“防潮王牌“材料
  • 【JVM调优实战】16-可视化利器-JConsole-VisualVM-JMC

周新闻

  • SaaS软件行业GEO实践:AI搜索时代的品牌可见性与获客新路径
  • 什么是PCTFE?医药高端包装的“防潮王牌“材料
  • 【JVM调优实战】16-可视化利器-JConsole-VisualVM-JMC

月新闻

  • 2026年6月公司网站搭建最新热门渠道测评:四大低成本/零代码平台对比+避坑
  • 【Linux】Linux arm 编译QT程序,出现expected “}“报错
  • 【MATLAB例程】四基站二维AOA定位与距离辅助增强对比仿真。基于角度观测和测距修正的固定目标平面定位精度分析

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号