【问题标题】:pyocr with tesseract runs out of memory带有tesseract的pyocr内存不足
【发布时间】:2017-03-28 14:17:53
【问题描述】:

我制作了一个脚本,在 tesseract 和 pyocr 的帮助下将 pdf 扫描成批处理。代码如下。问题是,在处理大量文件(例如 20+)时,有时脚本会耗尽内存并因 OSError 而失败。我目前做了它,以便它可以在手动重启后顺利赶上崩溃的地方,但是这些手动重启很乏味。

由于 pyocr 对我来说基本上是一个黑匣子,我尝试将脚本包装到其他 Python 脚本中,以便在崩溃时重新启动它,但它们似乎都出现了该错误,只有在每个相关脚本终止时才释放内存。

我能想到的唯一其他解决方案是制作一个完全外部的包装器,它会检查脚本是否正在运行,如果没有,则重新启动它并且仍然有未处理的文件。

但也许有更好的解决方案?或者,也许我编写了可以改进以避免这些内存崩溃的蹩脚代码? (除此之外,我知道它很蹩脚,但效果很好:))。

from io import BytesIO
from wand.image import Image
from PIL import Image as PI
import pyocr
import pyocr.builders
import io
import os
import os.path
import ast


def daemon_ocr(tool, img, lang):
    txt = tool.image_to_string(
        PI.open(BytesIO(img)),
        lang=lang,
        builder=pyocr.builders.TextBuilder()
    )
    return txt


def daemon_wrap(image_pdf, tool, lang, iteration):
    print(iteration)
    req_image = []
    final_text = ''
    image_pdf_bckp = image_pdf
    image_jpeg = image_pdf.convert('jpeg')

    for img in image_jpeg.sequence:
        img_page = Image(image=img)
        req_image.append(img_page.make_blob('jpeg'))

    for img in req_image:
        txt = daemon_ocr(tool, img, lang)
        final_text += txt + '\n '
    if 'работ' not in final_text and 'фактура' not in final_text and 'Аренда' not in final_text and 'Сумма' not in final_text\
            and 'аренде' not in final_text and 'товара' not in final_text:
        if iteration < 5:
            iteration += 1
            image_pdf = image_pdf.rotate(90)
            final_text = daemon_wrap(image_pdf_bckp, tool, lang, iteration)
    return final_text


def daemon_pyocr(food):
    tool = pyocr.get_available_tools()[0]
    lang = tool.get_available_languages()[0]
    iteration = 1
    image_pdf = Image(filename='{doc_name}'.format(doc_name=food), resolution=300)
    final_text = daemon_wrap(image_pdf, tool, lang, iteration)
    return final_text


files = [f for f in os.listdir('.') if os.path.isfile(f)]
output = {}
print(files)
path = os.path.dirname(os.path.abspath(__file__))
if os.path.exists('{p}/output'.format(p=path)):
    text_file = open("output", "a")
    first = False
else:
    text_file = open("output", "w")
    first = True

for f in files:
    if f != 'ocr.py' and f != 'output':
        try:
            output[f] = daemon_pyocr(f)
            print('{f} done'.format(f=f))
            if first:
                text_file.write(str(output)[1:-1])
                first = False
            else:
                text_file.write(', {d}'.format(d=str(output)[1:-1]))
            output = {}
            os.rename('{p}/{f}'.format(p=path, f=f), "{p}/done/{f}".format(p=path, f=f))
        except OSError:
            print('{f} failed: not enough memory.'.format(f=f))

【问题讨论】:

    标签: python memory-leaks python-tesseract


    【解决方案1】:

    我也遇到了同样的问题,终于解决了。 真正的问题不在于pyocr,而在于sequencewand.image.Image

    您可以使用Image 对象的destroy() 方法来释放内存。处理魔杖时始终使用with 语句。

    关于这个话题herehere已经有问题了

    这是我的代码,它可以将 pdf 转换为图像 blob,如果对您有帮助的话

    def convert_pdf_to_image_blob(pdf):
        req_image = []
        with WI(filename=pdf, resolution=150) as image_jpeg:
            image_jpeg.compression_quality = 99
            image_jpeg = image_jpeg.convert('jpeg')
    
            for img in image_jpeg.sequence:
                with WI(image=img) as img_page:
                    req_image.append(img_page.make_blob('jpeg'))
        image_jpeg.destroy()  # frees memory used by Image object. 
        return req_image
    

    谢谢

    【讨论】:

    • 感谢分享。我正在执行的任务现在已经消失了,但我肯定会尝试该解决方案以使其正常工作。
    • 错误:image_jpeg 你不能销毁它,因为它已经被with 关闭了。
    猜你喜欢
    • 2019-11-15
    • 2018-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-04
    • 1970-01-01
    • 1970-01-01
    • 2017-01-12
    相关资源
    最近更新 更多