Как получить лучшие / точные результаты с помощью OCR для изображений с низким разрешением

Я написал сценарий на python с использованием pytesseract для встраивания текста в изображение. Когда я запускаю свой скрипт, скребок выполняет свою работу странно, что означает, что текст, который я получаю в результате, сильно отличается от того, что находится на изображении.

Скрипт, с которым я пробовал:

import requests, io, pytesseract
from PIL import Image

response = requests.get('http://skoleadresser.no/4DCGI/WC_Pedlex_Adresse/864928.jpg')
img = Image.open(io.BytesIO(response.content))
imagetext = pytesseract.image_to_string(img)
print(imagetext)

Текст на картинке выглядит так:

Как получить лучшие / точные результаты с помощью OCR для изображений с низким разрешением

Результат у меня:

Adresse WM 0an Hanssensm 7 A
4u21 Slavanqer

warm 52 m so no

Te‘efaks 52 m 90 m

E'Dus‘x Van’s strandflanlmu

Как я могу получить точный результат?

это кодировка?

Crt 14.06.2018 18:32

Нет, я полагаю, что нет, потому что, когда я пытаюсь распечатать текст из этого изображения локально, результат все тот же.

SIM 14.06.2018 18:38

Я не голосовал против, но согласен, кто бы это ни сделал, должен указать причину.

Crt 14.06.2018 22:21
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
6
3
2 124
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

tl; dr:

import requests
import io
import pytesseract
from PIL import Image

response = requests.get('http://skoleadresser.no/4DCGI/WC_Pedlex_Adresse/864928.jpg')
img = Image.open(io.BytesIO(response.content))
width, height = img.size
new_size = width*6, height*6
img = img.resize(new_size, Image.LANCZOS)
img = img.convert('L')
img = img.point(lambda x: 0 if x < 155 else 255, '1')
imagetext = pytesseract.image_to_string(img)

print(imagetext)

Результаты в:

Adresse Prof. Olav Hanssens vei 7 A
4021 Stavanger

Telefon 52 70 90 00

Telefaks 52 70 90 01

E-post [email protected]

Инструкции / Как сделать

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

Это может звучать так, как будто у него мало шансов заставить его работать - простое масштабирование без какой-либо дополнительной обработки не поможет, как вы увидите позже, изображение все равно будет слишком далеко от похожего на что-либо подобное. печатный / печатный текст.

Я провел несколько проб и ошибок с коэффициентом масштабирования и обнаружил, что 6 лучше всего работают с этим изображением, поэтому:

width, height = img.size
new_size = width*6, height*6

Увеличение в 6 раз без повторной выборки:

img = img.resize(new_size)

Предоставляет нам это изображение, которое довольно бесполезно, потому что это в основном то же самое нечитаемое изображение, что и раньше, просто 1px * 1px теперь 6px * 6px (обратите внимание на серые области, которые почти пересекаются между буквами - особенно Pr, s и k будут приводят к большим проблемам):

Scaled up by factor 6 without resampling

К счастью, есть несколько формул передискретизации, которые дают очень хорошие результаты, для PIL есть PIL.Image.LANCZOS (среди других), который применяет Формула передискретизации Ланцоша:

img = img.resize(new_size, Image.LANCZOS)

Scaled up by factor 6 with LANCZOS resampling

Поначалу разница может показаться не такой уж большой - но теперь у нас есть лучшая заливка для букв вместо этих черных и серых блоков - и гораздо более естественное размытие, с которым мы можем работать на следующем шаге. Теперь, глядя на Pr, s и k, мы видим, что они больше не пересекаются так сильно.

Что нужно сделать дальше, чтобы изображение больше походило на фактически напечатанный документ, сделав его черно-белым, удалив размытие - первый шаг - заставить изображение работать с mode L (8-битные пиксели ч / б)

img = img.convert('L')

Converted to 8 bit b/w

Конечно, практически нет разницы, поскольку исходное изображение было черным текстом на белом фоне, но все же вам нужен этот шаг, чтобы иметь возможность работать с порогом яркости, чтобы преобразовать его в черно-белое изображение.

Это делается путем оценки каждого пикселя изображения по его 8-битному значению - хорошее значение для начала - 128, который на 50% черный:

img = img.point(lambda x: 0 if x < 128 else 255, '1')

Это дает нам слишком тонкий текст - инструмент OCR распознает большинство 5 как S и некоторые 0 как O:

b/w conversion at threshold 128

Теперь установив порог яркости на 200, мы получим следующее изображение:

b/w conversion at threshold 200

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

Давайте установим порог где-то между 128 и 200, чтобы мы получили естественно выглядящий печатный текст - немного проб и ошибок я обнаружил, что 155 работает отлично и выглядит так же, как и в исходном изображении:

b/w conversion at threshold 155

Поскольку это очень похоже на сканирование в высоком разрешении плохо напечатанного ч / б документа, инструмент OCR теперь может правильно выполнять свою работу.

Другие вопросы по теме