基于手部追踪的手指计数出现IndexError:元组索引越界问题排查
错误原因分析
1. 核心问题:返回值结构不匹配
你使用的cvzone.HandTrackingModule.HandDetector的findPosition方法,返回的手部关键点列表仅包含[x, y]坐标,每个元素只有2个值(索引0对应x,1对应y),但你的代码试图访问索引2,直接触发IndexError。
而视频中Murtaza使用的是自定义HandTrackingModule,其findPosition方法返回的是包含[id, x, y](或带z轴深度)的结构,因此可以通过索引2访问对应坐标,这是两者的核心差异。
2. 次要问题:手部检测不稳定
当摄像头未检测到手、检测置信度不足时,lmList会为空列表;或偶尔检测到的关键点数量不完整,也会导致索引越界。
解决方法
提供两种方案,根据需求选择:
方案一:换回视频中的自定义HandTrackingModule
取消代码中自定义模块的注释,替换cvzone的Detector:
import cv2 import time import HandTrackingModule as htm # 取消注释 wcam, hcam = 640 ,480 cap = cv2.VideoCapture(0) cap.set(3, wcam) cap.set(4, hcam) pTime = 0 detector = htm.HandDetector(detectionCon=0.7, maxHands=5) # 使用自定义模块 tipIds = [4,8,12,16,20] while True: success, img = cap.read() img = detector.findHands(img) lmList = detector.findPosition(img, draw=False) fingers = [0,0,0,0,0] if len(lmList) != 0: # 大拇指单独判断(x坐标对比) if lmList[tipIds[0]][1] < lmList[tipIds[0]-2][1]: fingers[0] = 1 # 其他手指判断(y坐标对比) for id in range(1,5): if lmList[tipIds[id]][2] < lmList[tipIds[id]-2][2]: fingers[id] = 1 cTime = time.time() fps = 1 / (cTime - pTime) pTime = cTime cv2.putText(img,f'fps: {int(fps)}',(70,40), cv2.FONT_HERSHEY_PLAIN,3,(255,255,0),3) cv2.imshow("image",img) cv2.waitKey(1)
方案二:适配cvzone的返回结构
修改代码,使用cvzone返回的[x,y]坐标(索引0对应x,1对应y),同时修正大拇指的判断逻辑:
import cv2 import time from cvzone.HandTrackingModule import HandDetector wcam, hcam = 640 ,480 cap = cv2.VideoCapture(0) cap.set(3, wcam) cap.set(4, hcam) pTime = 0 detector = HandDetector(detectionCon=0.7, maxHands=5) tipIds = [4,8,12,16,20] while True: success, img = cap.read() img = detector.findHands(img) lmList = detector.findPosition(img, draw=False) fingers = [0,0,0,0,0] # 确保关键点数量足够(至少21个,对应完整手部) if len(lmList) >= 21: # 大拇指判断:对比x坐标(默认适配右手,如需左手可调整判断方向) if lmList[tipIds[0]][0] < lmList[tipIds[0]-2][0]: fingers[0] = 1 # 其他手指判断:对比y坐标(y值越小越靠上,指尖在上则表示伸直) for id in range(1,5): if lmList[tipIds[id]][1] < lmList[tipIds[id]-2][1]: fingers[id] = 1 cTime = time.time() fps = 1 / (cTime - pTime) pTime = cTime cv2.putText(img,f'fps: {int(fps)}',(70,40), cv2.FONT_HERSHEY_PLAIN,3,(255,255,0),3) cv2.imshow("image",img) cv2.waitKey(1)
额外注意事项
- 确保手部完整出现在摄像头画面中,避免部分关键点无法检测
- 可调整
detectionCon参数(如设置为0.8)提升检测稳定性,减少误判 - 如果需要支持左右手,可通过cvzone的
findHands返回的手部信息添加方向判断逻辑
内容的提问来源于stack exchange,提问作者Yash Rakesh
相关产品推荐
相关产品推荐

