File size: 4,521 Bytes
d83150d |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
import os
from PIL import Image
import pytesseract
from tqdm import tqdm
from pytesseract import Output
from transformers import VisionEncoderDecoderModel, TrOCRProcessor
def recognize_row(row_file):
hf_model = VisionEncoderDecoderModel.from_pretrained("Serovvans/trocr-prereform-orthography")
image = Image.open(row_file)
processor = TrOCRProcessor.from_pretrained("microsoft/trocr-base-printed")
pixel_values = processor(images=image, return_tensors="pt").pixel_values
generated_ids = hf_model.generate(pixel_values)
generated_text = processor.batch_decode(generated_ids, skip_special_tokens=True)[0]
return generated_text
def recognize_page(image_path, output_dir="./", page_name=None):
"""
Разбивает изображение страницы на строки, сортирует строки, распознаёт их и соединяет текст.
Параметры:
image_path (str): Путь к изображению страницы.
output_dir (str): Путь к папке для сохранения строк.
page_name (str): Имя страницы для сохранения строк (по умолчанию None).
Возвращает:
str: Итоговый распознанный текст страницы.
"""
os.makedirs(output_dir, exist_ok=True)
image = Image.open(image_path)
data = pytesseract.image_to_data(image, config='--psm 3', output_type=Output.DICT)
lines = []
current_line = []
previous_y = None
y_threshold = 15 # Порог для объединения слов в одну строку
# Обход всех блоков текста
n_boxes = len(data['level'])
for i in range(n_boxes):
if data['level'][i] == 5 or data['level'][i] == 4: # Уровень строки или слова
x, y, w, h = data['left'][i], data['top'][i], data['width'][i], data['height'][i]
text = data['text'][i].strip()
if not text:
continue
# Проверяем, начинается ли новая строка
if previous_y is None or abs(y - previous_y) > y_threshold:
if current_line:
# Объединяем слова в строку и добавляем в список строк
min_x = min([word['x'] for word in current_line])
max_x = max([word['x'] + word['w'] for word in current_line])
avg_y = sum([word['y'] for word in current_line]) / len(current_line)
max_y = max([word['y'] + word['h'] for word in current_line])
lines.append((min_x, avg_y, max_x - min_x, max_y - avg_y, current_line))
current_line = []
# Добавляем текущее слово в текущую строку
current_line.append({'x': x, 'y': y, 'w': w, 'h': h, 'text': text})
previous_y = y
# Добавляем последнюю строку
if current_line:
min_x = min([word['x'] for word in current_line])
max_x = max([word['x'] + word['w'] for word in current_line])
avg_y = sum([word['y'] for word in current_line]) / len(current_line)
max_y = max([word['y'] + word['h'] for word in current_line])
lines.append((min_x, avg_y, max_x - min_x, max_y - avg_y, current_line))
# Сортировка строк по координате Y
lines.sort(key=lambda line: line[1])
# Сохранение строк как изображений и распознавание текста
recognized_text = []
i = 0
for line in tqdm(lines, desc="Processing page"):
x, y, w, h, words = line
min_x = x
max_x = x + w
min_y = max(0, y - 10)
max_y = y + h
# Обрезаем изображение по координатам строки
row_image = image.crop((min_x, min_y, max_x, max_y))
row_image_path = os.path.join(output_dir, f'{page_name}_row_{i}.png')
row_image.save(row_image_path)
# Распознаём текст строки
row_text = recognize_row(row_image_path)
os.remove(row_image_path)
recognized_text.append(row_text)
i += 1
# Соединяем распознанный текст строк
full_text = ' '.join(recognized_text)
return full_text
|