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

使用MediaPipe与OpenCV构建手部检测模块时遇异常错误求助

问题描述

我尝试用MediaPipe和OpenCV编写手部检测模块,代码如下:

import cv2
import mediapipe as mp
import time


class handDetector():
    def __init__(self, mode=False, model_complexity=1, maxHands=2, detectionCon=0.5, trackingCon=0.5):
        self.mode = mode
        self.maxHands = maxHands
        self.model_complexity = model_complexity
        self.detectionCon = detectionCon
        self.trackingCon = trackingCon

        self.mpHands = mp.solutions.hands
        self.hands = self.mpHands.Hands(self.mode, self.model_complexity, self.maxHands, self.detectionCon,
                                        self.trackingCon)
        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(results.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 == 8:
                    cv2.circle(img, (cx, cy), 10, (255, 0, 255), cv2.FILLED)
                if id == 12:
                    cv2.circle(img, (cx, cy), 10, (255, 0, 255), cv2.FILLED)
                if id == 16:
                    cv2.circle(img, (cx, cy), 10, (255, 0, 255), cv2.FILLED)
                if id == 20:
                    cv2.circle(img, (cx, cy), 10, (255, 0, 255), cv2.FILLED)
                if id == 4:
                    cv2.circle(img, (cx, cy), 10, (255, 0, 255), cv2.FILLED)

        return lmList


def main():

    ctime = 0
    ptime = 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()

运行时出现以下错误:

WARNING: Logging before InitGoogleLogging() is written to STDERR
F20230316 09:19:51.302183 3056 collection.h:55] Failed to get tag "C2__PACKET" index 0
*** Check failure stack trace: ***
F20230316 09:19:51.302183 7892 collection.h:55] Failed to get tag "C2__PACKET" index 0
*** Check failure stack trace: ***

我已经尝试搜索解决方案并将MediaPipe降级到3.8.0,但问题仍未解决,请求帮助。


解决方案

第一步:修复代码中的语法错误

你的代码存在两处明显逻辑/语法错误,先修正它们再排查其他问题:

  • 方法名大小写错误:Python是大小写敏感语言,detector.findposition(img) 应改为 detector.findPosition(img)
  • 判断逻辑错误:if len(lmList != 0): 应改为 if len(lmList) != 0:(原写法会先判断lmList !=0得到布尔值,再取长度,逻辑完全错误)

同时补充摄像头异常处理和退出逻辑,修正后的main函数:

def main():
    ctime = 0
    ptime = 0
    cap = cv2.VideoCapture(0)
    detector = handDetector()
    while True:
        success, img = cap.read()
        if not success:
            break  # 处理摄像头读取失败的情况
        img = detector.findHands(img)
        lmList = detector.findPosition(img)
        if len(lmList) != 0:
            print(lmList[4])

        ctime = time.time()
        fps = 1 / (ctime - ptime) if (ctime - ptime) !=0 else 0  # 避免除以0的异常
        ptime = ctime

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

        cv2.imshow("Image", img)
        if cv2.waitKey(1) & 0xFF == ord('q'):  # 按q键退出程序
            break
    cap.release()
    cv2.destroyAllWindows()

第二步:解决MediaPipe的C2__PACKET错误

这个错误通常和底层依赖兼容性、系统环境或模型加载问题有关,尝试以下方案:

方案1:匹配MediaPipe和OpenCV的兼容版本

MediaPipe不同版本对OpenCV有明确版本要求,建议使用经过验证的组合:

  • MediaPipe 0.8.10 + OpenCV 4.5.5.62
  • 或MediaPipe 0.9.0 + OpenCV 4.6.0.66

执行命令重新安装指定版本:

pip uninstall -y mediapipe opencv-python
pip install mediapipe==0.8.10 opencv-python==4.5.5.62

方案2:降低模型复杂度(针对Windows环境)

Windows环境下,model_complexity=1可能触发底层兼容性问题,尝试将初始化参数中的模型复杂度改为0:

detector = handDetector(model_complexity=0)

或者直接修改类的默认参数:

def __init__(self, mode=False, model_complexity=0, maxHands=2, detectionCon=0.5, trackingCon=0.5):

方案3:检查摄像头状态

  • 确保摄像头没有被其他程序占用
  • 尝试更换摄像头设备,或修改cv2.VideoCapture的设备索引,比如cap = cv2.VideoCapture(1)
  • Windows用户请确保已安装摄像头的最新驱动

方案4:清理MediaPipe模型缓存

删除MediaPipe的本地模型缓存,让程序重新下载适配的模型文件:

  • Windows路径:C:\Users\<你的用户名>\AppData\Roaming\Python\Python<版本号>\site-packages\mediapipe\modules
  • 删除该目录下的手部检测相关模型文件,重新运行程序

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 11:55:00