Вопрос или проблема
Я пытаюсь сделать изображения captcha
более читабельными для tesseract
с помощью обработки изображений. Изображения имеют белый фон, 4 черные цифры в центре, слегка повёрнутые, и случайную черную линию (тоньше, чем цифры), которая обычно пересекает цифры, чтобы сделать их труднее различимыми. Вот 2 примера:
Изображение captcha 6135
Изображение captcha 8892
Сейчас у меня есть некоторый код, и он срабатывает примерно в 50% случаев, и я не боюсь признаться, что использовал chatGPT для большинства, если не для всего этого..
Вот он:
import cv2
import numpy as np
import pytesseract
# Загрузка изображения
def clean_image(path: str):
image = cv2.imread(path)
# Конвертация в оттенки серого
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# Применение пороговой обработки для получения бинарного изображения
_, binary = cv2.threshold(gray, 100, 255, cv2.THRESH_BINARY_INV)
# Морфологические операции для обнаружения и удаления линии
# Используйте более крупный прямоугольный элемент для более эффективного обнаружения горизонтальной линии
kernel_line = cv2.getStructuringElement(cv2.MORPH_RECT, (40, 4)) # Увеличьте размер для более точного обнаружения линии
line_mask = cv2.morphologyEx(binary, cv2.MORPH_OPEN, kernel_line, iterations=2)
# Вычитание обнаруженной линии из оригинального бинарного изображения
line_removed = cv2.bitwise_and(binary, cv2.bitwise_not(line_mask))
# Применение медианного размытия для уменьшения оставшегося шума (точки на фоне)
blurred = cv2.medianBlur(line_removed, 5) # Увеличьте размер размытия, чтобы устранить шум
# Применение морфологического закрытия, чтобы заполнить пробелы и сделать цифры более четкими
kernel_digits = cv2.getStructuringElement(cv2.MORPH_RECT, (2, 2))
cleaned_image = cv2.morphologyEx(blurred, cv2.MORPH_CLOSE, kernel_digits, iterations=2)
return cleaned_image
custom_config = r'--oem 3 --psm 8 -c tessedit_char_whitelist=0123456789' # Ограничить только цифрами
pytesseract.pytesseract.tesseract_cmd = r"C:\Program Files\Tesseract-OCR\tesseract.exe"
# Выполнение OCR на очищенном изображении
for i in range(1, 6):
a = clean_image("image" + str(i) + ".png")
text = pytesseract.image_to_string(a, config=custom_config).strip()
print("Обнаруженный текст:", text, "Длина:", len(text))
cv2.imshow("i", a)
cv2.waitKey(0)
cv2.destroyAllWindows()
Получившиеся изображения:
Результирующее изображение для 6135
Результирующее изображение для 8892
Я пытался поиграть с пороговыми значениями, и 100 кажется “золотой серединой”.
Я ожидал, что код выдаст текст на изображениях, хотя он только половину времени дал точный ответ.
Я не знаю глубокое обучение, и я буду использовать его, если не будет другого способа дальше обработать изображения captcha
.
Ответ или решение
Для успешной обработки изображений CAPTCHA с четырьмя цифрами и улучшения распознавания с использованием Tesseract, необходимо внести некоторые изменения в ваш текущий код и применить дополнительные методы предварительной обработки изображений. Давайте рассмотрим улучшенный подход.
Улучшенный код обработки CAPTCHA
import cv2
import numpy as np
import pytesseract
# Функция для очистки изображения
def clean_image(path: str):
image = cv2.imread(path)
# Преобразование в оттенки серого
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# Применение адаптивного порога для бинаризованного изображения
binary = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
cv2.THRESH_BINARY_INV, 11, 2)
# Морфологические операции для удаления линий
kernel_line = cv2.getStructuringElement(cv2.MORPH_RECT, (40, 4)) # Размер можно изменять
line_mask = cv2.morphologyEx(binary, cv2.MORPH_OPEN, kernel_line, iterations=2)
# Удаление линий из бинарного изображения
line_removed = cv2.bitwise_and(binary, cv2.bitwise_not(line_mask))
# Применение медианного размытия для уменьшения шума
blurred = cv2.medianBlur(line_removed, 3)
# Морфологическое закрытие для улучшения цифр
kernel_digits = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
cleaned_image = cv2.morphologyEx(blurred, cv2.MORPH_CLOSE, kernel_digits, iterations=2)
# Опционально: сглаживание краев
cleaned_image = cv2.GaussianBlur(cleaned_image, (5, 5), 0)
return cleaned_image
# Настройки для Tesseract
custom_config = r'--oem 3 --psm 6 -c tessedit_char_whitelist=0123456789' # Ограничение до цифр
pytesseract.pytesseract.tesseract_cmd = r"C:\Program Files\Tesseract-OCR\tesseract.exe"
# Запуск OCR на очищенном изображении
for i in range(1, 6):
a = clean_image(f"image{i}.png")
text = pytesseract.image_to_string(a, config=custom_config).strip()
print("Обнаруженный текст:", text, "Длина:", len(text))
cv2.imshow("Cleaned Image", a)
cv2.waitKey(0)
cv2.destroyAllWindows()
Объяснение улучшений:
-
Адаптивное пороговое преобразование: Вместо фиксированного порога, я применил адаптивное пороговое преобразование. Это поможет более эффективно бинаризовать изображение с учетом различных освещенных участков.
-
Улучшение морфологических операций: С учетом природы вашего CAPTCHA, использование морфологических операций помогает удалить не только линии, но и другие шумы, которые могут затруднять распознавание цифр.
-
Сглаживание изображения: Дополнительное сглаживание краев перед обработкой может помочь уменьшить лишние артефакты, которые могут мешать алгоритму OCR.
-
Установка параметров Tesseract: Изменение параметра
--psm
на 6 (предполагается, что строка состоит из текста) может улучшить результаты распознавания.
Заключение
Предложенные улучшения должны повысить точность распознавания чисел на CAPTCHA. Тем не менее, стоит учитывать, что современные CAPTCHA системы могут использовать различные методы защиты, способные затруднить попытки распознавания. В таком случае, возможно, стоит рассмотреть использование более сложных методов, таких как глубокое обучение и нейронные сети для обработки изображений.