OpenCV - метод обработки изображений для лучшего чтения рельефных символов (например, в кредитных картах, номерной табличке) - PullRequest
0 голосов
/ 28 июня 2018

Итак, я уже искал много статей о том, как обрабатывать изображения с номерами на пластинах, поскольку это в основном то же самое, что и чтение рельефных символов. Но моя проблема в том, что если цвет рельефных символов совпадает с цветом карты, будет трудно распознать, если я использую Adaptive Threshold. Ребята, у вас есть идеи о том, как я достигну своей цели чтения рельефных персонажей? Или если есть статья об этом, было бы неплохо. Вот мой образец изображения

Я прочитал эту статью , но на самом деле не знаю, как перевести ее в реальный код.

Вот мой пример изображения enter image description here

1 Ответ

0 голосов
/ 25 июля 2018

Вы можете попробовать этот код. Это на python, но все методы opencv, по моему личному опыту, почти такие же, как Java.

EDIT: В вашем случае вы можете пропустить все методы улучшения OCR, используемые здесь. Позвольте мне описать процесс, который вы можете использовать:

В Python, используя ссылку выше:

Сначала примените преобразование цвета к оттенкам серого:

gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

Тогда: применить tophat (whitehat) морфологический оператор, чтобы найти свет регионы на темном фоне.

rectKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (9, 3))
tophat = cv2.morphologyEx(gray, cv2.MORPH_TOPHAT, rectKernel)

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

gradX = cv2.morphologyEx(gradX, cv2.MORPH_CLOSE, rectKernel)
thresh = cv2.threshold(gradX, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]

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

sqKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))    
thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, sqKernel)

Тогда найдите контуры номеров вашей карты регионов

cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL,
    cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if imutils.is_cv2() else cnts[1]
locs = []

Вы получите массив регионов, которые сможете извлечь, используя эту ветку

На Java:

Ранее я писал что-то похожее в java, у вас должно быть что-то похожее на это (ImgTransformation - один из моих классов, который упрощает некоторые параметры opencv, в основном он делает то же самое, что Imgproc, посмотрите документацию здесь ):

Преобразование изображения:

ImgTransformation.adjustConvertColor(tempMat,tempMat,Imgproc.COLOR_BGR2GRAY);

Imgproc.adaptiveThreshold(tempMat,tempMat,255,Imgproc.ADAPTIVE_THRESH_MEAN_C,Imgproc.THRESH_BINARY,31,40);

ImgTransformation.gaussianBlur(tempMat,tempMat,5,5,2);
Mat element = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new  Size(2*1 + 1, 2*1+1));
Imgproc.dilate(tempMat,tempMat,element);
Imgproc.erode(tempMat,tempMat,element);
ImgTransformation.adjustBinary(tempMat,tempMat,205,255,Imgproc.THRESH_BINARY_INV);

Сегментация:

Mat structuringElements = ImgSegmentation.getStructuringElement(Imgproc.MORPH_RECT, new Size(5, 3));
Imgproc.dilate(tempMat,tempMat,structuringElements,new Point(-1,-1),16);

Затем извлеките регионы:

List<MatOfPoint> contours = ImgSegmentation.findContours(tempMat, tempMat);

Вам просто нужно извлечь, используя submat(), и все хорошо! Поиграйте с некоторыми числовыми параметрами, чтобы настроить результат в своем собственном случае, так как мой проект больше касается отсканированных документов, чем номеров кредитных карт.

Удачи!

...