Распознавание текста с изображений в Python: библиотеки Tesseract и pytesseract
Основные подходы к извлечению текста из изображений
Как наиболее эффективно распознать текст с изображения на Python?
Самым распространённым и проверенным решением является связка библиотеки pytesseract и установленного движка Tesseract OCR. Этот подход подходит для большинства задач: документы, скриншоты, вывески, книги. Процесс включает установку Tesseract, затем Python-обёртки.
# Установка Tesseract (пример для Ubuntu)
# sudo apt install tesseract-ocr
# Для Windows скачать с GitHub, добавить в PATH
# Установка Python пакета:
# pip install pytesseract Pillow
import pytesseract
from PIL import Image
# Открыть изображение
img = Image.open('example.png')
# Распознать текст
text = pytesseract.image_to_string(img, lang='rus')
print(text)
изображение в текст python (извлечение текста из изображения в python)
Типичные ошибки:
- TesseractNotFoundError - Tesseract не установлен или не добавлен в PATH. Решение: указать путь через `pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract.exe'`.
- UnicodeDecodeError - проблемы с кодировкой текста на изображении. Решение: использовать аргумент `lang='rus+eng'` или настроить локаль.
Цель - быстрое получение текста из чёткого печатного изображения. Случаи использования: автоматизация ввода данных, архивация документов, обработка скриншотов.
Как улучшить качество распознавания на зашумлённых или низкоконтрастных изображениях?
Для повышения точности применяют предобработку с помощью OpenCV. Основные шаги: преобразование в оттенки серого, бинаризация (пороговая обработка), удаление шума.
import cv2
import pytesseract
img = cv2.imread('noisy.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Бинаризация методом Оцу
_, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
# Удаление шума (медианный фильтр)
denoised = cv2.medianBlur(thresh, 3)
# Сохранить промежуточное изображение для pytesseract (или передать массив)
import tempfile
with tempfile.NamedTemporaryFile(suffix='.png', delete=False) as f:
cv2.imwrite(f.name, denoised)
text = pytesseract.image_to_string(f.name, lang='rus')
print(text)
Типичные проблемы:
- Излишняя бинаризация стирает тонкие линии текста. Решение: подбор порога вручную (cv2.threshold с конкретным значением).
- Шумы после бинаризации. Решение: морфологические операции (cv2.morphologyEx).
Цель - распознавание текста с фотографий, старых сканов, изображений с плохим освещением. Случаи: обработка чеков, визиток, документов с печатями.
Как распознать текст на нескольких языках одновременно?
В Tesseract можно указать комбинацию языков через знак '+', например 'rus+eng'. При этом движок использует общий набор символов.
text = pytesseract.image_to_string(img, lang='rus+eng')
print(text)
Ошибка:
- Языковой пакет не установлен. Решение: для русского языка - `sudo apt install tesseract-ocr-rus`.
Цель - документация, содержащая смешанный текст (например, инструкция на двух языках).
Как получить текст с сохранением структуры (абзацы, переносы строк)?
Параметр --psm (Page Segmentation Mode) управляет способом разбиения изображения. PSM 6 предполагает единый блок текста, PSM 4 - многострочный текст.
text = pytesseract.image_to_string(img, config='--psm 6', lang='rus')
print(text)
Проблемы:
- Некорректный выбор PSM приводит к потере строк. Решение: экспериментировать с режимами 3, 4, 6.
Цель - распознавание многострочных текстов (статьи, таблицы).
Как извлечь только цифры или определённые символы?
Используется whitelist через параметр `-c tessedit_char_whitelist`. Например, только цифры.
# Распознать только цифры
config = '--psm 13 -c tessedit_char_whitelist=0123456789'
text = pytesseract.image_to_string(img, config=config, lang='eng')
print(text)
Проблема:
- Whitelist работает только при однозначном соответствии символов. Если на изображении есть буквы, они будут проигнорированы, но это может снизить точность.
Цель - распознавание номеров, кодов, цен.
Как исправить искажения перспективы или наклон текста?
Текст под углом распознаётся плохо. Необходимо выпрямить изображение с помощью OpenCV (аффинные преобразования).
import cv2
import numpy as np
def deskew(image):
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(gray, 50, 150)
lines = cv2.HoughLines(edges, 1, np.pi/180, 200)
if lines is None:
return image
# Найти средний угол
angles = [line[0][1] for line in lines]
median_angle = np.median(angles)
angle = median_angle * 180 / np.pi - 90
if abs(angle) < 1:
return image
h, w = image.shape[:2]
center = (w // 2, h // 2)
M = cv2.getRotationMatrix2D(center, angle, 1.0)
rotated = cv2.warpAffine(image, M, (w, h), flags=cv2.INTER_CUBIC, borderMode=cv2.BORDER_REPLICATE)
return rotated
img = cv2.imread('skewed.png')
deskewed = deskew(img)
cv2.imwrite('fixed.png', deskewed)
text = pytesseract.image_to_string('fixed.png', lang='rus')
print(text)
Сложности:
- Метод HoughLines может не сработать на изображениях с маленьким текстом. Альтернатива: поиск контуров и выравнивание по минимальному ограничивающему прямоугольнику.
Цель - распознавание текста с перекошенных фотографий, сканов.
Расширенные примеры извлечения текста
Пример 1: Комплексная обработка изображения с распознаванием bounding box и данных о каждом символе.
import pytesseract
from PIL import Image, ImageDraw
img = Image.open('complex.png')
data = pytesseract.image_to_data(img, lang='rus', output_type=pytesseract.Output.DICT)
# Рисование рамок для каждого найденного слова
img_draw = img.copy()
draw = ImageDraw.Draw(img_draw)
for level, text, left, top, width, height, conf in zip(
data['level'], data['text'], data['left'], data['top'],
data['width'], data['height'], data['conf']):
if level == 5 and conf > 30: # слово
draw.rectangle([left, top, left+width, top+height], outline='red')
img_draw.save('annotated.png')
print('Аннотированное изображение сохранено')
(В консоли выводится сообщение о сохранении, а файл annotated.png содержит изображение с рамками.)
Пример 2: Пакетная обработка нескольких изображений из папки с выводом результатов в CSV.
import os
import csv
import pytesseract
from PIL import Image
input_folder = 'images'
output_file = 'results.csv'
results = []
for filename in os.listdir(input_folder):
if filename.lower().endswith(('.png', '.jpg', '.jpeg', '.tiff')):
path = os.path.join(input_folder, filename)
try:
img = Image.open(path)
text = pytesseract.image_to_string(img, lang='rus+eng')
results.append([filename, text.strip()])
except Exception as e:
results.append([filename, f'Ошибка: {e}'])
with open(output_file, 'w', newline='', encoding='utf-8') as f:
writer = csv.writer(f)
writer.writerow(['Имя файла', 'Распознанный текст'])
writer.writerows(results)
print(f'Обработано {len(results)} файлов. Результат в {output_file}')
Обработано 5 файлов. Результат в results.csv
Пример 3: Конвертация PDF в текст с помощью извлечения изображений из страниц.
from pdf2image import convert_from_path
import pytesseract
images = convert_from_path('document.pdf', dpi=300)
full_text = ''
for i, img in enumerate(images):
text = pytesseract.image_to_string(img, lang='rus')
full_text += f'--- Страница {i+1} ---\n{text}\n'
with open('document.txt', 'w', encoding='utf-8') as f:
f.write(full_text)
print('Текст из PDF извлечён')
Текст из PDF извлечён (файл document.txt создан)
Пример 4: Использование tesseract с пользовательским конфигурационным файлом для улучшения распознавания шрифтов.
# Предварительно создайте файл myconfig.conf с содержимым:
# load_system_dawg false
# load_freq_dawg false
custom_config = r'--user-words ./mywords.txt --psm 6'
# или путь к конфигу:
# custom_config = r'--config ./myconfig.conf --psm 6'
text = pytesseract.image_to_string(img, lang='eng', config=custom_config)
print(text)
(Выводится распознанный текст с повышенной точностью для специфического шрифта)