在进行字符识别之前使用OpenCV进行图像预处理(tesseract)

时间:2016-05-18 14:08:24

标签: java opencv tesseract tess4j anpr

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

我的步骤:

1)源图像

True Image

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步之后)粘贴起来,然后得到:

plate region

然后我做了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 文件夹放入项目文件夹中)

3 个答案:

答案 0 :(得分:11)

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

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

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

  4. 对结果图像进行阈值处理以获得二进制图像。
  5. 使用合适的结构元素进行形态学闭合操作。
  6. 查找生成图像的轮廓。
  7. 查找每个轮廓的minAreaRect。根据纵横比,最小和最大面积选择矩形。
  8. 对于每个选定的轮廓,找到边缘密度。设置边缘密度的阈值,并选择超出该阈值的矩形作为可能的板区域。
  9. 此后几乎没有矩形。您可以根据方向或您认为合适的任何标准对其进行过滤。
  10. adaptiveThreshold之后剪切这些检测到的矩形部分并应用OCR。
  11. a)步骤5后的结果

    Result after Step 5

    b)步骤7之后的结果。绿色的是minAreaRect s,红色的是满足以下标准的那些:宽高比范围(2,12)&面积范围(300,10000)

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

    enter image description here

    编辑

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

    1. 将Canny Edge探测器直接应用于输入图像。让cannyED图像为 Ic
    2. 将Sobel滤波器和 Ic 的结果相乘。基本上,拍摄Sobel和Canny图像的AND。
    3. 高斯使用大滤镜模糊合成图像。我使用了21x21。
    4. 使用OTSU方法对生成的图像进行阈值处理。您将获得二进制图像
    5. 对于每个红色矩形,旋转此矩形内的部分(在二进制图像中)使其竖直。循环遍历矩形的像素并计算白色像素。 (How to rotate?
    6. 边缘密度=矩形中的白色像素数/总数。矩形中的像素数

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

答案 1 :(得分:2)

实际上,OpenCV专门针对俄罗斯车牌进行了预训练模型:haarcascade_russian_plate_number

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

答案 2 :(得分:1)

  • 找到所有连接的组件(白色区域)并确定其轮廓。
  • 如果您根据尺寸(作为图像的一部分),比率(宽度 - 高度)和白/黑比率过滤它们以检索候选印版。
  • 撤消矩形的转换
  • 取下螺栓
  • 将图像传递给OCR引擎。