使用OpenCV、PyAutoGUI和Tesseract OCR的Python脚本内存占用持续增长问题求助
使用OpenCV、PyAutoGUI和Tesseract OCR的Python脚本内存占用持续增长问题求助
看起来你遇到的内存泄漏问题在涉及OpenCV、Tesseract这类C扩展库的Python脚本里挺常见的——毕竟Python的垃圾回收机制对底层C/C++分配的内存不一定能自动处理好。我帮你分析下可能的问题点和对应的修复方案:
1. PyAutoGUI截图的内存开销问题
PyAutoGUI的screenshot()返回的是PIL图像对象,之后转成numpy数组给OpenCV用的过程可能会产生额外内存副本,而且PIL对象的回收有时候没那么及时。建议换成更高效的截图库mss,它直接返回numpy数组,不需要中间的PIL对象,能减少内存占用和碎片:
首先安装mss:
pip install mss
然后修改你的capture_screen函数:
import mss def capture_screen(region): """Captures a screenshot of a given region""" x, y, w, h = region # 使用mss上下文管理器,自动释放资源 with mss.mss() as sct: monitor = {"top": y, "left": x, "width": w, "height": h} # 直接获取numpy数组格式的截图 img = np.array(sct.grab(monitor)) # 转换为OpenCV需要的BGR格式(mss返回的是BGRA) img = cv2.cvtColor(img, cv2.COLOR_BGRA2BGR) return img
2. OpenCV图像的底层内存未释放
你虽然用了del img,但OpenCV的图像对象底层是C++的Mat结构,Python的垃圾回收没法直接回收这部分内存。需要手动调用img.release()来释放底层资源:
修改extract_text函数:
def extract_text(img): """Extracts text using Tesseract""" config = "--psm 8 -c tessedit_char_whitelist=0123456789-AS" text = pytesseract.image_to_string(img, config=config) # 手动释放OpenCV图像的底层内存 img.release() del img gc.collect() return text.strip()
3. Tesseract的资源残留
pytesseract默认可能会复用全局的Tesseract实例,这有时候会导致内存累积。你可以手动创建Tesseract实例,用完后显式关闭它,确保资源释放:
def extract_text(img): """Extracts text using Tesseract""" config = "--psm 8 -c tessedit_char_whitelist=0123456789-AS" # 手动初始化Tesseract实例 tess = pytesseract.pytesseract.Tesseract() try: text = tess.image_to_string(img, config=config) finally: # 显式关闭实例,释放资源 tess.end() img.release() del img, tess gc.collect() return text.strip()
4. 调整垃圾回收的时机
你现在在每个函数里都调用gc.collect(),其实频繁触发垃圾回收反而可能影响效率,而且有时候函数内的回收不如循环末尾彻底。可以把gc.collect()移到循环的最后,同时手动删除循环内的变量:
while True: print(f"Memory usage: {process.memory_info().rss / 1024 / 1024:.2f} MB") img = capture_screen(ROI) text = extract_text(img) print(f"Detected text: {text}") # 手动删除循环内的临时变量 del img, text # 统一回收垃圾 gc.collect() time.sleep(1)
额外建议
- 升级你的OpenCV、pytesseract和numpy到最新稳定版本,旧版本可能存在已知的内存泄漏问题
- 如果你不需要实时性特别高,可以适当延长
time.sleep()的时间,减少循环频率,也能缓解内存增长
你可以先从替换mss截图和添加img.release()这两步开始试,这两个是最常见的问题点,应该能解决大部分内存增长的问题。
备注:内容来源于stack exchange,提问作者André
相关产品推荐
相关产品推荐

