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

Python结合Mediapipe开发手部检测类代码出现内存无法释放占满问题

Python+Mediapipe手部检测内存泄漏问题解决

问题原因

  1. 核心泄漏点:你将handDetector类的实例化逻辑放在了while循环内部,每轮循环都会创建一个新的mp.solutions.hands.Hands模型实例。Mediapipe的模型底层由C实现,你手动删除Python层的handDtc对象、调用gc.collect()仅能回收Python层分配的内存,无法释放C层申请的模型内存,每轮循环遗留的C++层内存持续累积,最终导致内存被占满。
  2. 附加问题:代码存在语法错误(draw_landmarks方法调用后多了冗余的cv.FILLED参数)、无用赋值语句,会额外引发运行异常。

修复方案

  • 将handDetector的实例化移到while循环外部,整个程序运行周期仅初始化一次Mediapipe手部检测模型,避免重复创建实例占用内存。
  • 移除所有gc相关操作,gc无法管理Mediapipe底层C++内存,手动调用完全无效。
  • 程序退出时新增摄像头资源、OpenCV窗口资源的释放逻辑。
  • 修正现有代码的语法错误和无用语句。

修复后完整代码

import cv2 as cv
import mediapipe as mp
import time

class handDetector():
    def __init__(self, mode=False, maxHands=2, detectionCon=0.5, trackCon=0.5):
        self.mode = mode
        self.maxHands = maxHands
        self.detectionCon = detectionCon
        self.trackCon = trackCon
        self.mpHands = mp.solutions.hands
        self.hands = self.mpHands.Hands(self.mode, self.maxHands, 1, self.detectionCon, self.trackCon)
        self.mpDraw = mp.solutions.drawing_utils
    def findHands(self, image, draw=True):
        imgRGB = cv.cvtColor(image, cv.COLOR_BGR2RGB)
        self.result = self.hands.process(imgRGB)

        if self.result.multi_hand_landmarks:
            for hand in self.result.multi_hand_landmarks:
                if draw:
                    self.mpDraw.draw_landmarks(image, hand, self.mpHands.HAND_CONNECTIONS)
        return image
    def findPosition(self, image, handNo=0, draw=True):
        lmList = []
        h, w, c = image.shape
        if self.result.multi_hand_landmarks:
            myHand = self.result.multi_hand_landmarks[handNo]
            for id, land in enumerate(myHand.landmark):
                cx, cy = int(land.x * w), int(land.y * h)
                lmList.append([id, cx, cy])
                if draw:
                    cv.circle(image, (cx,cy), 15, (0,0,255), cv.FILLED)
        return lmList


def main():
    cap = cv.VideoCapture(0)
    ret = True   
    pre_time = time.time()
    # 模型实例化移到循环外,仅初始化一次
    handDtc = handDetector()
    while ret:
        ret, frame = cap.read()
        if not ret:
            break
        crt_time = time.time()
        fps = int(1/(crt_time-pre_time))
        image = handDtc.findHands(frame)
        lmList = handDtc.findPosition(image) 
        cv.putText(image, str(fps), (50,50), cv.FONT_HERSHEY_COMPLEX, 1, (255,255,0))        
        cv.imshow('image', image)
        pre_time = time.time()     
        if cv.waitKey(1) == ord('q'):
            break
    # 释放资源
    cap.release()
    cv.destroyAllWindows()

if __name__ == "__main__":
    main()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 20:48:00