如何清除PySimpleGUI中Graph组件绘制的内容以解决draw_image内存泄漏问题
PySimpleGUI Graph组件清空方法及内存泄漏问题修复
核心原因
你遇到的内存泄漏是因为draw_image()每次调用都会在Graph中新增一个独立的图像元素,旧图像不会自动销毁,持续叠加后内存占用就会不断上涨。
解决方法
方案1:全量清空(适合帧已经叠加了标注的场景,也就是你当前的代码逻辑)
直接在每次绘制新图像前调用Graph的erase()方法清空所有历史绘制内容即可,修改后的循环逻辑如下:
camera = my_opencv_library(device=0) while True: event, values = window.read(timeout=20) if event == "-GRAPH-": camera.update_coordinate(values["-GRAPH-"]) # 获取叠加了鼠标点击实时绘制内容的直播画面 frame = camera.get_frame() imgbytes = cv2.imencode(".png", frame)[1].tobytes() # 先清空历史内容 window["-GRAPH-"].erase() # 再绘制新帧 window["-GRAPH-"].draw_image(data=imgbytes, location=(0,0))
方案2:仅删除旧背景帧(适合分层绘制、需要保留上层标注的场景)
如果后续你需要把摄像头帧作为底层背景,上层的标注框单独绘制不需要每次随帧重绘,可以记录每次背景帧的元素ID,只删除上一帧的背景,避免清空标注,性能更高:
camera = my_opencv_library(device=0) last_bg_id = None # 记录上一帧背景图的元素ID while True: event, values = window.read(timeout=20) if event == "-GRAPH-": camera.update_coordinate(values["-GRAPH-"]) # 示例:绘制标注框并记录ID,不需要随背景清空 # rect_id = window["-GRAPH-"].draw_rectangle(...) frame = camera.get_frame() imgbytes = cv2.imencode(".png", frame)[1].tobytes() # 仅删除上一帧的背景图,保留标注等上层元素 if last_bg_id is not None: window["-GRAPH-"].delete_figure(last_bg_id) # 绘制新背景,保存元素ID last_bg_id = window["-GRAPH-"].draw_image(data=imgbytes, location=(0,0))
额外优化建议
实时摄像头场景下,用cv2.imencode(".jpg", frame)代替png编码,速度更快、生成的字节流体积更小,能进一步降低内存占用和CPU消耗。
内容的提问来源于stack exchange,提问作者lejun
相关产品推荐
相关产品推荐

