Удалить границы с изображения, но оставить текст написанным на границах (предварительная обработка перед распознаванием) - PullRequest
3 голосов
/ 24 сентября 2019

digit extraction

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

two

Что прекрасно работает в большинстве случаев, но если кто-то пишет через строку, это может быть предсказано как 7 вместоиз 2.

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

1 Ответ

5 голосов
/ 25 сентября 2019

Вот конвейер

  • Преобразование изображения в оттенки серого
  • Порог Оцу для получения двоичного изображения
  • Удаление горизонтальных линий
  • Удаление вертикальных линий
  • Построить исправление ядра и восстановить образ
  • Инвертировать изображение

После преобразования в оттенки серого мы используем порог Отсу

enter image description here

Отсюда мы удаляем горизонтальные и вертикальные линии

enter image description here

Это оставляет нам пробел в символах,чтобы исправить это, мы создаем исправительное ядро ​​для расширения изображения

enter image description here

Далее мы побитово - и с пороговым изображением для сохранения деталей нашего персонажа

enter image description here

Разрыв все еще есть, но немного лучше.Мы выполняем морфинг близко, чтобы закрыть разрыв

enter image description here

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

enter image description here

Чтобы получить желаемый результат, мы инвертируем изображение

enter image description here

import cv2

image = cv2.imread('1.png')
removed = image.copy()
gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]

# Remove horizontal lines
horizontal_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (40,1))
remove_horizontal = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, horizontal_kernel, iterations=2)
cnts = cv2.findContours(remove_horizontal, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
    cv2.drawContours(removed, [c], -1, (255,255,255), 5)

# Remove vertical lines
vertical_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (1,40))
remove_vertical = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, vertical_kernel, iterations=2)
cnts = cv2.findContours(remove_vertical, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
    cv2.drawContours(removed, [c], -1, (255,255,255), 15)

# Repair kernel
repair_kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3,3))
removed = 255 - removed
dilate = cv2.dilate(removed, repair_kernel, iterations=5)
dilate = cv2.cvtColor(dilate, cv2.COLOR_BGR2GRAY)
pre_result = cv2.bitwise_and(dilate, thresh)

result = cv2.morphologyEx(pre_result, cv2.MORPH_CLOSE, repair_kernel, iterations=5)
final = cv2.bitwise_and(result, thresh)

invert_final = 255 - final

cv2.imshow('thresh', thresh)
cv2.imshow('removed', removed)
cv2.imshow('dilate', dilate)
cv2.imshow('pre_result', pre_result)
cv2.imshow('result', result)
cv2.imshow('final', final)
cv2.imshow('invert_final', invert_final)
cv2.waitKey()
...