OpenCV - 用于更好地读取浮雕字符(例如信用卡、车牌号)的图像处理技术

OpenCV - Image Processing Technique for better reading of embossed characters (e.g in credit cards,plate number)

因此,我已经搜索了很多有关车牌图像处理的文章,因为它基本上与读取浮雕字符相同。但我的问题是,如果浮雕字符的颜色与卡片的颜色相同,那么如果我使用自适应阈值,将很难识别。你们知道我将如何实现阅读浮雕字符的目标吗?或者如果有任何关于它的文章,那就太好了。这是我的示例图片

我读过这个 article 但真的不知道如何将它转化为实际代码。

这是我的示例图片

您可以试用 this 代码。它在 python 中,但根据我个人的经验,所有 opencv 方法都与 Java 完全相同。

编辑: 在您的情况下,您可以跳过此处使用的所有 OCR 增强方法。让我描述一下您可以使用的过程:

在python中使用上面的link:

首先,对灰度应用颜色转换:

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

然后: 应用顶帽(白帽)形态学算子来寻找光 深色背景区域。

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 = []

您将获得一组区域,您可以使用 this thread

提取这些区域

在Java中:

我之前在java写过类似的东西,你应该有类似的东西(ImgTransformation是我的class之一,它简化了一些opencv参数,它基本上和Imgproc一样,去检查文档 here):

图像变换:

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() 进行提取就可以了! 使用一些数字参数来根据您自己的情况调整结果,因为我的项目更多的是关于扫描文档而不是信用卡号码。

祝你好运!