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

Python摄像头循环采集脚本内存持续增长问题求助

Python摄像头循环采集脚本内存持续增长问题求助

我用树莓派4B搭配13MP USB摄像头写了个Python脚本,功能是采集图片后上传到服务器,下面是简化后的版本(能复现内存增长的问题)。每次循环采集图片后,内存占用都会上涨,最后直接把脚本搞挂了。我已经试过用del删除变量、把变量设为None,还手动调用了垃圾回收,但都没效果。附上内存占用的截图:

内存占用截图

我的代码如下:

import cv2, psutil, os, gc, time

def takepic():

    frame = None
    cw, ch = 4000, 3000
    cap = cv2.VideoCapture(0)
    print('click!')
    cap.set(cv2.CAP_PROP_FRAME_WIDTH, cw)
    cap.set(cv2.CAP_PROP_FRAME_HEIGHT, ch)
    time.sleep(0.6)
    suc, frame = cap.read()
    cap.release()

    process = psutil.Process(os.getpid())
    print(f'Memory Used {round(process.memory_percent(), 2)}%')
    resizeit(frame)

def resizeit(img):
    small = cv2.resize(img, (0,0), fx=0.5, fy=0.5)
    del small
    del img
    print(gc.get_count())
    gc.collect()
    print(gc.get_count())
    time.sleep(1)
    takepic()
    
takepic()

兄弟我看了你的代码,一眼就发现了核心问题——递归调用导致的调用栈无限累积!你在resizeit函数最后又调用了takepic(),这相当于开启了无限递归模式:每一次递归都会在Python的调用栈里新增一个栈帧,哪怕你手动del变量、触发GC,这些栈帧本身占用的内存也不会被释放,因为函数从来没有真正返回过,栈帧会一直堆积,内存自然越涨越高。

另外OpenCV的底层操作偶尔会有小的内存泄漏,但你的主要问题肯定是递归结构。下面给你几个针对性的解决思路:

1. 把递归改成循环(最关键的一步)

放弃递归调用,改用while True循环实现重复采集,这样每次函数执行完后栈帧会被正常释放,内存就能被GC回收了。修改后的代码示例:

import cv2, psutil, os, gc, time

def takepic():
    frame = None
    cw, ch = 4000, 3000
    cap = cv2.VideoCapture(0)
    try:
        print('click!')
        cap.set(cv2.CAP_PROP_FRAME_WIDTH, cw)
        cap.set(cv2.CAP_PROP_FRAME_HEIGHT, ch)
        time.sleep(0.6)
        suc, frame = cap.read()
    finally:
        cap.release()  # 用try-finally确保摄像头资源必被释放

    process = psutil.Process(os.getpid())
    print(f'Memory Used {round(process.memory_info().rss / 1024 / 1024, 2)} MB')
    return frame

def resizeit(img):
    small = cv2.resize(img, (0,0), fx=0.5, fy=0.5)
    print(gc.get_count())
    gc.collect()
    print(gc.get_count())
    time.sleep(1)

# 用循环代替递归,避免栈帧堆积
if __name__ == "__main__":
    while True:
        frame = takepic()
        resizeit(frame)
        del frame  # 手动释放帧引用,帮助GC更快回收

2. 优化OpenCV资源处理

  • 用try-finally包裹摄像头操作,避免异常情况下资源没被释放;
  • 如果还是有内存缓慢增长,可以尝试更新OpenCV到最新稳定版(树莓派上执行pip install --upgrade opencv-python),某些旧版本在处理大分辨率USB摄像头帧时存在已知的内存泄漏问题。

3. 更精准地监控内存

memory_percent()是相对总内存的百分比,有时候不够直观,改成查看常驻内存(RSS)能更清楚看到实际占用的内存大小:

print(f'Memory Used {round(process.memory_info().rss / 1024 / 1024, 2)} MB')

备注:内容来源于stack exchange,提问作者Vanlon

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 17:08:07