虚拟鼠标开发遇ValueError解包错误,寻求调试帮助
问题:虚拟鼠标开发中findPosition函数报错ValueError
报错信息
INFO: Created TensorFlow Lite XNNPACK delegate for CPU. Traceback (most recent call last): File "C:\AIproject\virMouse.py", line 18, in <module> lmList, bbox = detector.findPosition(img) ValueError: not enough values to unpack (expected 2, got 0) Process finished with exit code 1
主程序代码(virMouse.py)
import cv2 import numpy as np import time import HTmodule as htm import autopy wCam, hCam = 640, 480 cap = cv2.VideoCapture(0) cap.set(3, wCam) cap.set(4, hCam) pTime = 0 detector = htm.handDetector(maxHands=1) while True: success, img = cap.read() img = detector.findHands(img) lmList, bbox = detector.findPosition(img) cTime = time.time() fps = 1 / (cTime - pTime) pTime = cTime cv2.putText(img, f'FPS:{(int(fps))}', (5, 30), cv2.FONT_HERSHEY_DUPLEX, 1, (204, 0, 0), 2) cv2.imshow("Image", img) cv2.waitKey(1)
手部追踪模块代码(HTmodule.py)
import cv2 import mediapipe as mp import time class handDetector(): def __init__(self, mode=False, maxHands=2,modelC=1, detectionCon=0.5, trackCon=0.5): self.mode = mode self.maxHands = maxHands self.modelC = modelC self.detectionCon = detectionCon self.trackCon = trackCon self.mpHands = mp.solutions.hands self.hands = self.mpHands.Hands(self.mode, self.maxHands, self.modelC, self.detectionCon, self.trackCon) self.mpDraw = mp.solutions.drawing_utils def findHands(self, img, draw=True): imgRGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) self.results = self.hands.process(imgRGB) # print(result.multi_hand_landmarks) if self.results.multi_hand_landmarks: for handLms in self.results.multi_hand_landmarks: if draw: self.mpDraw.draw_landmarks(img, handLms, self.mpHands.HAND_CONNECTIONS) return img def findPosition(self, img, handNo=0, draw=True): lmList=[] if self.results.multi_hand_landmarks: myHand = self.results.multi_hand_landmarks[handNo] for id, lm in enumerate(myHand.landmark): # print(id,lm) h, w, c = img.shape cx, cy = int(lm.x * w), int(lm.y * h) # print(id, cx, cy) lmList.append([id, cx, cy]) # if id == 0: if draw: cv2.circle(img, (cx, cy), 3, (229, 25, 66), cv2.FILLED) return lmList def main(): pTime = 0 cTime = 0 cap = cv2.VideoCapture(0) detector = handDetector() while True: success, img = cap.read() img = detector.findHands(img) lmList = detector.findPosition(img, draw=False) # print(lmList) # PRINTS THE LIST OF LANDMARKS if len(lmList) != 0: print(lmList[4]) cTime = time.time() fps = 1 / (cTime - pTime) pTime = cTime cv2.putText(img, f'FPS:{(int(fps))}', (5, 30), cv2.FONT_HERSHEY_DUPLEX, 1, (9, 9, 255), 1) cv2.imshow("Image", img) cv2.waitKey(1) if __name__ == "__main__": main()
问题分析与解决方法
核心问题
报错的直接原因是主程序错误地期望findPosition返回两个值(lmList和bbox),但该函数实际只返回lmList一个值。当没有检测到手时,lmList是空列表,尝试将空列表解包为两个变量就会触发ValueError: not enough values to unpack (expected 2, got 0)。
解决步骤
修正主程序的赋值语句
如果不需要bounding box,直接将主程序中的:lmList, bbox = detector.findPosition(img)修改为:
lmList = detector.findPosition(img)若确实需要手部的bounding box,可以修改
HTmodule中的findPosition函数,让它同时返回lmList和bbox,示例修改如下:def findPosition(self, img, handNo=0, draw=True): lmList=[] bbox = [] if self.results.multi_hand_landmarks: myHand = self.results.multi_hand_landmarks[handNo] # 计算bounding box x_list = [] y_list = [] for id, lm in enumerate(myHand.landmark): h, w, c = img.shape cx, cy = int(lm.x * w), int(lm.y * h) x_list.append(cx) y_list.append(cy) lmList.append([id, cx, cy]) if draw: cv2.circle(img, (cx, cy), 3, (229, 25, 66), cv2.FILLED) bbox = [min(x_list), min(y_list), max(x_list)-min(x_list), max(y_list)-min(y_list)] # 可选:绘制bbox if draw: cv2.rectangle(img, (bbox[0]-20, bbox[1]-20), (bbox[0]+bbox[2]+20, bbox[1]+bbox[3]+20), (0,255,0), 2) return lmList, bbox此时主程序的
lmList, bbox = detector.findPosition(img)就能正常运行。增加手部检测判断
在使用lmList之前,先判断是否有检测到手,避免后续操作出错,比如在主程序中添加:lmList = detector.findPosition(img) if len(lmList) > 0: # 这里写后续的鼠标控制逻辑,比如获取指尖坐标等 print("检测到手部关键点")
内容的提问来源于stack exchange,提问作者UserS1912
相关产品推荐
相关产品推荐

