You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

运行OpenCV手部检测Python代码遇ValueError解包错误求助

问题:OpenCV手部检测报错ValueError: not enough values to unpack (expected 2, got 0)

运行代码时触发以下错误:

Exception has occurred: ValueError
not enough values to unpack (expected 2, got 0)

代码目标是通过Python调用摄像头,借助OpenCV和MediaPipe实现手部关键点标记。参考过类似问题但均非OpenCV场景,无法理解解决逻辑。

主代码

import cv2
import numpy as np
import controlledhandmouse as htm
import time
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, str(int(fps)), (20,50), cv2.FONT_HERSHEY_PLAIN,3,(255,0,0), 3)
                
    cv2.imshow("Image", img)
    cv2.waitKey(1)

controlledhandmouse模块代码

import cv2
import mediapipe as mp
import time


class handDetector():
    def __init__(self, mode=False, maxHands=1, modelComplexity=1, 
                 detectionCon=0.5, trackCon=0.5):
        self.mode = mode
        self.maxHands = maxHands
        self.modelComplex = modelComplexity
        self.detectionCon = detectionCon
        self.trackCon = trackCon

        self.mpHands = mp.solutions.hands
        self.hands = self.mpHands.Hands(self.mode, self.maxHands, 
                                        self.modelComplex, 
                                        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)

        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):
                h, w, c = img.shape
                cx, cy = int(lm.x * w), int(lm.y * h)
                lmList.append([id, cx, cy])
                if draw:
                    cv2.circle(img, (cx, cy), 6, (255, 0, 255), 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)
        if len(lmList) != 0:
            print(lmList[4])

        cTime = time.time()
        fps = 1 / (cTime - pTime)
        pTime = cTime

        cv2.putText(img, str(int(fps)), (10, 70), cv2.FONT_HERSHEY_PLAIN, 3,
                    (255, 0, 255), 3)

        cv2.imshow("Image", img)
        cv2.waitKey(1)


if __name__ == "__main__":
    main()

问题原因与解决办法

核心原因

主代码中尝试用lmList, bbox = detector.findPosition(img)解包两个变量,但handDetector类的findPosition方法仅返回lmList一个值,导致解包时因值数量不匹配触发ValueError。

解决步骤

  1. 修改findPosition方法,返回lmList和bbox两个值
    在方法中添加手部 bounding box 的计算逻辑,确保返回两个值:

    def findPosition(self, img, handNo=0, draw=True):
        lmList = []
        bbox = []
        if self.results.multi_hand_landmarks:
            myHand = self.results.multi_hand_landmarks[handNo]
            xList = []
            yList = []
            for id, lm in enumerate(myHand.landmark):
                h, w, c = img.shape
                cx, cy = int(lm.x * w), int(lm.y * h)
                xList.append(cx)
                yList.append(cy)
                lmList.append([id, cx, cy])
                if draw:
                    cv2.circle(img, (cx, cy), 6, (255, 0, 255), cv2.FILLED)
            # 计算手部 bounding box
            xmin, xmax = min(xList), max(xList)
            ymin, ymax = min(yList), max(yList)
            bbox = [xmin, ymin, xmax, ymax]
            # 可选:绘制 bounding box
            if draw:
                cv2.rectangle(img, (xmin-20, ymin-20), (xmax+20, ymax+20), (0, 255, 0), 2)
        return lmList, bbox
    
  2. 修正主代码中的拼写错误(可选但推荐)
    将主代码中的succes改为success,并添加摄像头帧读取失败的判断:

    success, img = cap.read()
    if not success:
        print("无法读取摄像头帧")
        break
    

内容的提问来源于stack exchange,提问作者kikoneImparat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 10:57:21