Вы можете попробовать этот код. Это на 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()
, и все хорошо!
Поиграйте с некоторыми числовыми параметрами, чтобы настроить результат в своем собственном случае, так как мой проект больше касается отсканированных документов, чем номеров кредитных карт.
Удачи!