Я пытаюсь применить OCR с помощью OpenCV и Python-tesseract для преобразования следующего изображения в текст: Исходное изображение.
Но tesseract пока не удалось правильно прочитать изображение. Вместо этого он гласит: uleswylly Bie7 Srp a7.
Я предпринял следующие шаги для предварительной обработки изображения, прежде чем передать его в tesseract:
# Image scaling
def set_image_dpi(img):
# Get current dimensions of the image
height, width = img.shape[:2]
# Define scale factor
scale_factor = 6
# Calculate new dimensions
new_height = int(height * scale_factor)
new_width = int(width * scale_factor)
# Resize image
return cv2.resize(img, (new_width, new_height))
Результат изображения: result1.png
# Normalization
norm_img = np.zeros((img.shape[0], img.shape[1]))
img = cv2.normalize(img, norm_img, 0, 255, cv2.NORM_MINMAX)
Результат изображения: result2.png
# Remove noise
def remove_noise(img):
return cv2.fastNlMeansDenoisingColored(img, None, 10, 10, 7, 15)
Результат изображения: result3.png
# Get grayscale
def get_grayscale(img):
return cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
Результат изображения: result4.png
# Thresholding
def thresholding(img):
return cv2.threshold(img, 150, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU) [1]
Результат изображения: result5.png
# Invert the image
def invert(img):
return cv2.bitwise_not(img)
Результат изображения: result6.png
# Pass preprocessed image to pytesseract
text = pytesseract.image_to_string(img)
print("Text found: " + text)
вывод питессеракта: "uleswylly Bie7 Srp a7"
Я хотел бы улучшить предварительную обработку, чтобы pytesseract действительно мог читать изображение? Любая помощь будет принята с благодарностью!
Заранее спасибо,
Стинерт
Проблема немного сложная, без переоснащения решения проблемы...
Предположим, что текст яркий, бесцветный и окружен цветными пикселями. Можно также предположить, что фон относительно однороден.
Мы можем начать с result3.png
и использовать следующие этапы:
floodFill
(требуется, потому что некоторые цветные пиксели касаются полей изображения).cv2.THRESH_OTSU
для автоматического порогового значения).pytesseract.image_to_string
к пороговому изображению.Пример кода:
import cv2
import numpy as np
import pytesseract
pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract.exe' # May be required when using Windows
img = cv2.imread('result3.png') # Read result3.png
# Add padding with the color of the top left pixel
pad_color = img[0, 0, :]
padded_img = np.full((img.shape[0]+10, img.shape[1]+10, 3), pad_color, np.uint8)
padded_img[5:-5, 5:-5, :] = img
cv2.floodFill(padded_img, None, (0, 0), (255, 100, 100), loDiff=(10, 10, 10), upDiff=(10, 10, 10)) # Fill the background with blue color.
cv2.imwrite('result7.png', padded_img)
# Convert from BGR to HSV color space, and extract the saturation channel.
hsv = cv2.cvtColor(padded_img, cv2.COLOR_BGR2HSV)
s = hsv[:, :, 1]
cv2.imwrite('result8.png', s)
# Apply thresholding (use `cv2.THRESH_OTSU` for automatic thresholding)
thresh = cv2.threshold(s, 0, 255, cv2.THRESH_OTSU)[1]
cv2.imwrite('result9.png', thresh)
# Pass preprocessed image to PyTesseract
text = pytesseract.image_to_string(thresh, config = "--psm 6")
print("Text found: " + text)
Выход:Text found: Jules -Lv: 175 -P.17
result7.png
(после флуда):
result8.png
(после извлечения канала насыщения):
result9.png
(после порога):
Это сработало отлично! Я не подумал о добавлении отступов и настройке насыщенности изображения перед порогом. Спасибо
Измените размер, как вы это сделали, затем установите порог для белых букв, используя cv2.inRange(). Это должно дать только буквы на черном фоне. Затем инвертируйте это и сделайте pytesseract на этом.