Python + OpenCV: сегментирование изображения OCR

Я пытаюсь сделать OCR из этого игрушечного примера квитанций. Использование Python 2.7 и OpenCV 3.1.

введите описание изображения здесь

Оттенки серого и размытие + Обнаружение внешнего края + Сегментация каждой области в квитанциях (например, «Категория», чтобы увидеть, какая из них отмечена – в этом случае – денежные средства).

Я считаю сложным, когда изображение «перекошено», чтобы иметь возможность правильно преобразовывать, а затем «автоматически» сегментировать каждый сегмент квитанций.

Пример:

введите описание изображения здесь

Любое предложение?

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

Любая помощь более чем оценена! 🙂

import os; os.chdir() # Put your own directory import cv2 import numpy as np image = cv2.imread("Rent-Receipt.jpg", cv2.IMREAD_GRAYSCALE) blurred = cv2.GaussianBlur(image, (5, 5), 0) #blurred = cv2.bilateralFilter(gray,9,75,75) # apply Canny Edge Detection edged = cv2.Canny(blurred, 0, 20) #Find external contour (_,contours, _) = cv2.findContours(edged, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) 

2 Solutions collect form web for “Python + OpenCV: сегментирование изображения OCR”

Большой учебник на первом этапе, который вы описали, доступен на pyimagesearch (и у них отличные учебники в целом)

Короче говоря, как описано Ella, вам нужно будет использовать cv2.CHAIN_APPROX_SIMPLE . Несколько более надежным методом было бы использовать cv2.RETR_LIST вместо cv2.RETR_EXTERNAL а затем отсортировать области, так как это должно прилично работать даже на белом фоне / если страница вписывает большую фигуру в фоновом режиме и т. Д.

Переходя к второй части вашего вопроса, хорошим способом сегментировать персонажей будет использование максимально стабильного экстракта экстремальной области, доступного в OpenCV. Полная реализация в CPP доступна здесь в проекте, который я недавно помогал. Реализация Python будет идти по строкам (код ниже работает для OpenCV 3.0+. Для синтаксиса OpenCV 2.x проверьте его в Интернете)

 import cv2 img = cv2.imread('test.jpg') mser = cv2.MSER_create() #Resize the image so that MSER can work better img = cv2.resize(img, (img.shape[1]*2, img.shape[0]*2)) gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) vis = img.copy() regions = mser.detectRegions(gray) hulls = [cv2.convexHull(p.reshape(-1, 1, 2)) for p in regions[0]] cv2.polylines(vis, hulls, 1, (0,255,0)) cv2.namedWindow('img', 0) cv2.imshow('img', vis) while(cv2.waitKey()!=ord('q')): continue cv2.destroyAllWindows() в import cv2 img = cv2.imread('test.jpg') mser = cv2.MSER_create() #Resize the image so that MSER can work better img = cv2.resize(img, (img.shape[1]*2, img.shape[0]*2)) gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) vis = img.copy() regions = mser.detectRegions(gray) hulls = [cv2.convexHull(p.reshape(-1, 1, 2)) for p in regions[0]] cv2.polylines(vis, hulls, 1, (0,255,0)) cv2.namedWindow('img', 0) cv2.imshow('img', vis) while(cv2.waitKey()!=ord('q')): continue cv2.destroyAllWindows() 

Это дает результат как

введите описание изображения здесь

Теперь, чтобы устранить ложные срабатывания, вы можете просто прокрутить точки в корпусах и вычислить периметр (сумму расстояния между всеми соседними точками в корпусах [i], где корпуса [i] – это список всех точек в одном выпуклом корпусе ). Если периметр слишком велик, классифицируйте его как символ.

Диагональные линии по изображению приближаются, потому что граница изображения черная. который можно просто удалить, добавив следующую строку, как только изображение будет прочитано (строка 7)

 img = img[5:-5,5:-5,:] 

который дает выход

введите описание изображения здесь

Опция на верхней части головы требует выделения из 4 углов перекошенного изображения. Это делается с помощью cv2.CHAIN_APPROX_SIMPLE вместо cv2.CHAIN_APPROX_NONE при поиске контуров. Впоследствии вы можете использовать cv2.approxPolyDP и, надеюсь, остаться с четырьмя углами квитанции (если все ваши изображения похожи на это, тогда нет причин, по которым он не должен работать).

Теперь используйте cv2.findHomography и cv2.wardPerspective чтобы исправить изображение в соответствии с исходными точками, которые являются 4 точками, извлеченными из перекошенного изображения и точек назначения, которые должны образовывать прямоугольник, например, размеры полного изображения.

Здесь вы можете найти образцы кода и дополнительную информацию: OpenCV-геометрические преобразования изображений

Также этот ответ может быть полезен – SO – обнаружение и исправление перекоса текста

EDIT: Исправлена ​​вторая цепочка около cv2.CHAIN_APPROX_NONE .

  • Обнаружение линий и фигур в OpenCV с использованием Python
  • OpenCV / Python: быстрый способ сопоставить изображение с базой данных
  • Добавить размеры в массив Numpy
  • Opencv3 и Python 2.7 на виртуальном окружении - объект AttributeError: 'module' не имеет атрибута 'createLBPHFaceRecognizer'
  • Создание функции с использованием yield вместо возврата для генерации кадров из HTTP-потока непрерывно
  • Совместимость с ORB python opencv
  • Доступ к API Ximea через OpenCV в Python
  • Сравнение производительности интерфейсов OpenCV-Python, cv и cv2
  •  
    Interesting Posts for Van-Lav
    Python - лучший язык программирования в мире.