Извлечение текста из отсканированного PDF без сохранения отсканированного изображения в виде нового файла - PullRequest
1 голос
/ 16 января 2020

Я хотел бы извлечь текст из отсканированных PDF-файлов.
Мой «тестовый» код выглядит следующим образом:

from pdf2image import convert_from_path
from pytesseract import image_to_string
from PIL import Image

converted_scan = convert_from_path('test.pdf', 500)

for i in converted_scan:
    i.save('scan_image.png', 'png')

text = image_to_string(Image.open('scan_image.png'))
with open('scan_text_output.txt', 'w') as outfile:
    outfile.write(text.replace('\n\n', '\n'))

Я хотел бы знать, есть ли способ извлечь содержимое изображение непосредственно с объекта converted_scan, без сохранения сканирования в виде нового «физического» файла изображения на диске?

По сути, я хотел бы пропустить эту часть:

for i in converted_scan:
    i.save('scan_image.png', 'png')

У меня есть несколько тысяч сканов для извлечения текста. Хотя все сгенерированные новые файлы изображений не являются особенно тяжелыми, это не является незначительным, и я нахожу это немного излишним.

РЕДАКТИРОВАТЬ

Вот немного другой подход, основанный на этот пост .

from wand.image import Image as w_img
from PIL import Image as p_img
import pyocr.builders
import pyocr
import io

infile = 'my_file.pdf'

tool = pyocr.get_available_tools()[0]
lang = tool.get_available_languages()[0]
print("Language used: '%s'" % (lang))

# image to text
req_image = []
text = []

image_pdf = w_img(filename = infile, resolution = 300)
image_png = image_pdf.convert('png')

for img in image_png.sequence:
    img_page = w_img(image = img)
    req_image.append(img_page.make_blob('png'))

for i in req_image:
    content = tool.image_to_string(
        p_img.open(io.BytesIO(i)),
        lang = lang,
        builder = pyocr.builders.TextBuilder()
    )
    text.append(content)

# save output
with open(infile[:-4] + '.txt', 'w') as outfile:
    full_txt = '\n'.join(text)
    full_txt = full_txt.replace(r'\n\n', '\n')
    outfile.write(full_txt)

1 Ответ

2 голосов
/ 16 января 2020

РЕДАКТИРОВАТЬ : вы также можете попробовать и использовать pdftotext library

pdf2image - это простая оболочка для pdftoppm и pdftocairo. Внутренне он ничего не делает, но вызывает подпроцесс. Этот скрипт должен делать то, что вы хотите, но вам нужна библиотека wand, а также pyocr (я думаю, что это вопрос предпочтений, поэтому не стесняйтесь использовать любые библиотека для извлечения текста вы хотите).

from PIL import Image as Pimage, ImageDraw
from wand.image import Image as Wimage
import sys
import numpy as np
from io import BytesIO

import pyocr
import pyocr.builders

def _convert_pdf2jpg(in_file_path: str, resolution: int=300) -> Pimage:
    """
    Convert PDF file to JPG

    :param in_file_path: path of pdf file to convert
    :param resolution: resolution with which to read the PDF file
    :return: PIL Image
    """
    with Wimage(filename=in_file_path, resolution=resolution).convert("jpg") as all_pages:
        for page in all_pages.sequence:
            with Wimage(page) as single_page_image:
                # transform wand image to bytes in order to transform it into PIL image
                yield Pimage.open(BytesIO(bytearray(single_page_image.make_blob(format="jpeg"))))

tools = pyocr.get_available_tools()
if len(tools) == 0:
    print("No OCR tool found")
    sys.exit(1)
# The tools are returned in the recommended order of usage
tool = tools[0]
print("Will use tool '%s'" % (tool.get_name()))
# Ex: Will use tool 'libtesseract'

langs = tool.get_available_languages()
print("Available languages: %s" % ", ".join(langs))
lang = langs[0]
print("Will use lang '%s'" % (lang))
# Ex: Will use lang 'fra'
# Note that languages are NOT sorted in any way. Please refer
# to the system locale settings for the default language
# to use.
for img in _convert_pdf2jpg("some_pdf.pdf"):
    txt = tool.image_to_string(img,
                               lang=lang,
                               builder=pyocr.builders.TextBuilder())
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...