14

我正在尝试开发用于车牌识别的简单 PC 应用程序(Java + OpenCV + Tess4j)。图像不是很好(进一步它们会很好)。我想为 tesseract 预处理图像,但我一直在检测车牌(矩形检测)。

我的步骤:

1) 源图像

真实影像

Mat img = new Mat();
img = Imgcodecs.imread("sample_photo.jpg"); 
Imgcodecs.imwrite("preprocess/True_Image.png", img);

2) 灰度

Mat imgGray = new Mat();
Imgproc.cvtColor(img, imgGray, Imgproc.COLOR_BGR2GRAY);
Imgcodecs.imwrite("preprocess/Gray.png", imgGray);

3) 高斯模糊

Mat imgGaussianBlur = new Mat(); 
Imgproc.GaussianBlur(imgGray,imgGaussianBlur,new Size(3, 3),0);
Imgcodecs.imwrite("preprocess/gaussian_blur.png", imgGaussianBlur);  

4) 自适应阈值

Mat imgAdaptiveThreshold = new Mat();
Imgproc.adaptiveThreshold(imgGaussianBlur, imgAdaptiveThreshold, 255, CV_ADAPTIVE_THRESH_MEAN_C ,CV_THRESH_BINARY, 99, 4);
Imgcodecs.imwrite("preprocess/adaptive_threshold.png", imgAdaptiveThreshold);

这里应该是第 5 步,即检测板块区域(现在可能甚至没有去偏斜)。

我用Paint从图像中裁剪了需要的区域(在第4步之后),并得到:

板块区域

然后我做了 OCR(通过 tesseract,tess4j):

File imageFile = new File("preprocess/adaptive_threshold_AFTER_PAINT.png");
ITesseract instance = new Tesseract();
instance.setLanguage("eng");
instance.setTessVariable("tessedit_char_whitelist", "acekopxyABCEHKMOPTXY0123456789");
String result = instance.doOCR(imageFile); 
System.out.println(result);

并得到(足够好?)结果 - “Y841ox EH”(几乎是真的)

第 4 步后如何检测和裁剪板块区域?我是否需要分 1-4 个步骤进行一些更改(改进)?希望看到一些通过 Java + OpenCV(不是 JavaCV)实现的示例。
提前致谢。

编辑(感谢@Abdul Fatir 的回答)好吧,我为那些对这个问题感兴趣的人提供了工作(至少对我来说)代码示例(Netbeans+Java+OpenCV+Tess4j)。代码不是最好的,但我只是为了学习而写的。
http://pastebin.com/H46wuXWn(不要忘记将tessdata文件夹放入您的项目文件夹中)

4

3 回答 3

13

以下是我建议您执行此任务的方法。

  1. 转换为灰度。
  2. 使用 3x3 或 5x5 滤镜的高斯模糊。
  3. 应用 Sobel 滤波器来查找垂直边缘。

    Sobel(gray, dst, -1, 1, 0)

  4. 对结果图像设置阈值以获得二值图像。
  5. 使用合适的结构元素应用形态关闭操作。
  6. 找到结果图像的轮廓。
  7. 查找minAreaRect每个轮廓。根据纵横比和最小和最大面积选择矩形。
  8. 对于每个选定的轮廓,找到边缘密度。设置边缘密度的阈值,并选择超出该阈值的矩形作为可能的板块区域。
  9. 在此之后将保留几个矩形。您可以根据方向或您认为合适的任何标准过滤它们。
  10. 之后从图像中剪切这些检测到的矩形部分adaptiveThreshold并应用 OCR。

a)步骤 5 后的结果

步骤 5 后的结果

b)步骤 7 之后的结果。绿色是所有的minAreaRects,红色是满足以下条件的那些:纵横比范围 (2,12) & 面积范围 (300,10000)

c)步骤 9 后的结果。选定的矩形。标准:边缘密度 > 0.5

在此处输入图像描述

编辑

对于边缘密度,我在上述示例中所做的如下。

  1. 将 Canny 边缘检测器直接应用于输入图像。让 cannyED 图像为Ic
  2. 将 Sobel 滤波器和Ic的结果相乘。基本上,对 Sobel 和 Canny 图像进行 AND 运算。
  3. 高斯模糊使用大滤镜生成的图像。我使用 21x21。
  4. 使用 OTSU 的方法对生成的图像进行阈值处理。你会得到一个二进制图像
  5. 对于每个红色矩形,旋转该矩形内的部分(在二进制图像中)以使其直立。循环遍历矩形的像素并计算白色像素。(如何旋转?

边缘密度 = 矩形中的白色像素数/总数。矩形中的像素数

  1. 选择边缘密度的阈值。

注意:您也可以使用步骤 5 中的二进制图像来计算边缘密度,而不是执行步骤 1 到 3。

于 2016-05-19T08:58:43.720 回答
2

实际上 OpenCV 有专门针对俄罗斯车牌的预训练模型:haarcascade_russian_plate_number

还有俄罗斯车牌的开源 ANPR 项目: plate_recognition。它没有使用 tesseract,但它具有相当好的预训练神经网络。

于 2016-09-05T02:45:12.290 回答
1
  • 您找到所有连接的组件(白色区域)并确定它们的轮廓。
  • 如果您根据大小(作为图像的一部分)、比率(宽度-高度)和白/黑比率对它们进行过滤以检索候选板。
  • 撤消矩形的变换
  • 拆下螺栓
  • 将图像传递给 OCR 引擎。
于 2016-05-19T08:34:18.523 回答