手势追踪
📌 项目介绍
手势追踪是 CV Zone 最经典的入门项目:用摄像头实时检测手部,并定位 21 个手部关键点(指尖、指节、腕部等)。
底层用 Google 的 MediaPipe 手部模型 + OpenCV 采集画面,视频作者封装成 cvzone 库的 HandTrackingModule,几行代码就能跑通。后续的虚拟鼠标、虚拟画家、手指计数等项目都建立在这个模块之上,所以它被视作手势应用的基石。
🔬 原课深化 · 原理与模块
① 手部 21 个关键点怎么看
MediaPipe 把每只手输出 21 个关键点,编号固定:0 是手腕;1~4 是拇指(4 为拇指尖);5~8 是食指(8 为食指尖);9~12 是中指(12 为中指尖);13~16 是无名指(16 为无名指尖);17~20 是小指(20 为小指尖)。
记住「指尖索引 = 4 / 8 / 12 / 16 / 20」这条规律,后续虚拟鼠标、手指计数、音量控制所有项目都在取这些点做几何判断。
② HandDetector 封装了什么
cvzone 的 HandTrackingModule 把三件事封装成了几行 API:跑 MediaPipe Hands 模型推理 → 把归一化坐标还原成画面像素坐标 → 顺手整理成字典返回。
每只手返回的字典含 4 个键:lmList(21 个点的 [x, y, z] 列表)、bbox(手部边界框 x/y/w/h)、center(掌心坐标)、type(Left/Right)。
它就是本站其余十几个手势项目的公共底座——先学这一篇,等于一次性掌握了虚拟鼠标、虚拟画家、手指计数的检测部分。
③ 识别原理(通俗版)
MediaPipe Hands 分两步:先用一个轻量网络在整幅画面里定位手的位置(棕榈检测),再对裁剪出的手部区域做关键点回归;一旦检测到,后续帧走更快的跟踪通路,所以能轻松跑到实时帧率。
trackCon 与 detectionCon 两个置信度就是控制「跟踪」与「重新检测」切换的阈值:手跟丢(置信度跌破 trackCon)时会自动退回完整检测。
🧰 环境与物料
- 电脑 + 摄像头(笔记本自带即可)
- Python 3.7+ 环境
- pip 安装:opencv-python、mediapipe、cvzone
- (可选)USB 外接摄像头,画质更好
🔧 步骤拆解
安装环境
创建虚拟环境后执行 pip install opencv-python mediapipe cvzone
安装较慢时用国内镜像源加速
摄像头取流
用 OpenCV 的 VideoCapture(0) 打开摄像头
逐帧读取后用 flip 镜像画面,操作更自然
初始化手部检测器
从 cvzone 导入 HandTrackingModule 并实例化
关键参数:静态模式、最大手数(默认 1 只)、检测置信度
检测并画点连线
每帧调用 findHands() 返回关键点坐标
drawLandmarks 会在画面上画出 21 个点与骨架连线
获取单点坐标
用 lmList 拿到每个关键点的 (x, y) 像素坐标
通过索引取指尖等关键位置,供后续逻辑使用
封装与后续扩展
把检测逻辑封装成函数/类,方便复用
这个模块就是虚拟鼠标、画家、音量控制的底座
💻 完整代码示例
# 依赖:pip install opencv-python mediapipe==0.10.14 cvzone
# 注意:cvzone 当前使用 mediapipe 旧版 Hands API,
# 直接装最新版 mediapipe 会找不到解决方案,务必固定 0.10.14
import cv2
from cvzone.HandTrackingModule import HandDetector
cap = cv2.VideoCapture(0) # 打开摄像头(0 为默认摄像头)
detector = HandDetector(detectionCon=0.8, maxHands=1) # 检测置信度 0.8,最多 1 只手
while True:
ok, img = cap.read() # 逐帧读取
if not ok:
break
img = cv2.flip(img, 1) # 水平镜像,像照镜子一样自然
hands, img = detector.findHands(img) # 检测并绘制 21 点骨架,返回手部信息列表
if hands:
hand = hands[0]
lmList = hand["lmList"] # 21 个关键点 [[x, y, z], ...],z 为深度
bbox = hand["bbox"] # (x, y, w, h)
cx, cy = hand["center"] # 掌心中心
tip = lmList[8][:2] # 食指指尖坐标(索引 8)
cv2.circle(img, tip, 8, (0, 255, 255), cv2.FILLED) # 黄色高亮食指尖
cv2.imshow("Hand Tracking", img)
if cv2.waitKey(1) & 0xFF == ord("q"): # 按 q 退出
break
cap.release()
cv2.destroyAllWindows()import cv2
from cvzone.HandTrackingModule import HandDetector
cap = cv2.VideoCapture(0)
detector = HandDetector(detectionCon=0.8, maxHands=2) # 最多同时检测 2 只手
while True:
ok, img = cap.read()
if not ok:
break
img = cv2.flip(img, 1)
hands, img = detector.findHands(img) # findHands 默认已画出骨架与框
if hands:
for hand in hands:
# 五个指尖索引:拇指4 食指8 中指12 无名指16 小指20
for i in [4, 8, 12, 16, 20]:
x, y = hand["lmList"][i][:2]
cv2.circle(img, (x, y), 7, (0, 255, 0), cv2.FILLED)
x, y = hand["bbox"][:2]
cv2.putText(img, hand["type"], (x, y - 10),
cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 0, 255), 2)
cv2.imshow("Hand Tracking", img)
if cv2.waitKey(1) & 0xFF == ord("q"):
break
cap.release()
cv2.destroyAllWindows()⚙️ 关键参数说明
| 参数 | 默认 | 作用与建议 |
|---|---|---|
| staticMode | False | 是否每一帧都做完整检测。False 时检测到手后进入跟踪模式,帧率更高;True 适合手不动、需要最高稳定性的场景,但更耗 CPU。 |
| maxHands | 2 | 画面中最多检测的手的数量。只做单指控制类应用可设为 1,省算力。 |
| modelComplexity | 1 | 模型复杂度 0 或 1,越大关键点越准但越慢。普通笔记本用默认 1 即可。 |
| detectionCon | 0.5 | 初次检测的置信度阈值(0~1)。检测不到手时适当降到 0.5~0.6 更易检出,但过低会引入误检。 |
| trackCon | 0.5 | 帧间跟踪的置信度阈值。跟丢后会自动切回完整检测,一般无需修改。 |
💡 要点提示
- 手部进入画面时模型最稳,手指并拢或遮挡会降低检测置信度
- 摄像头画面越大,检测越耗 CPU;640×480 分辨率性价比最高
- 检测不到手时先检查光照是否均匀,避免强逆光
🧯 常见问题排查
安装 mediapipe 后导入失败 / 报找不到 Hands?
新版 mediapipe(0.10.20+)已移除旧版 solutions.hands 接口,而 cvzone 目前仍依赖旧接口。请固定安装:pip install mediapipe==0.10.14,且 Python 用 3.8~3.11(3.12+ 旧版 mediapipe 无预编译包)。
摄像头正常但一直检测不到手?
按顺序排查:① 光照是否均匀(强逆光几乎必失败,侧光最佳);② 手与镜头距离 30~80cm、完整入画;③ 把 detectionCon 从 0.8 降到 0.5~0.6 再试;④ 确认没有把 maxHands 设成 0。
画面很卡、CPU 占用高?
把摄像头分辨率调到 640×480;保持 staticMode=False;不需要画骨架时用 findHands(img, draw=False) 跳过绘图开销;减少同时检测的手数。
左右手 type 反了?
type 是按「画面中的成像位置」标注的(非你身体的实际左右)。开镜像后感觉相反是正常现象;逻辑里若按真实左右手判断(如手势操作),把两值互换或用食指根部 x 与掌心 x 的关系自行判定即可。
lmList 的点坐标是什么单位?
lmList 是像素坐标 [x, y, z]:x、y 为画面像素位置,z 为相对深度的归一化值(手腕为 0,可用来判断手指是否朝镜头弯曲)。做画布/屏幕映射时直接用 x、y。
📦 原站课程与全部资料
- 官网课程(免费 · 2 节课) ↗原站课程入口,含官方视频与图文步骤;视频观看需登录,正文版权归 CV Zone(Murtaza's Workshop)。
- cvzone 官方 GitHub ↗HandTrackingModule 完整源码与更多官方示例,可直接阅读/参考。
- MediaPipe Hands 官方文档 ↗Google 官方手部关键点方案文档,了解最新版 API 与 21 点定义。
- B站镜像检索 ↗打不开原站/YouTube 时,在 B 站搜索同名教程视频学习。