转载

iOS OpenCV 车牌静态识别浅谈

成果展示:

iOS OpenCV 车牌静态识别浅谈
车牌静态识别

视频记录了每一次操作的图像变化,便于我们进行跟踪调试。车牌定位的速度还是挺快的。

那么,研究到现在,大概了解到了车牌识别主要分为三大部分:
1、车牌定位:如果连车牌都定位不到,那还谈什么车牌识别。
2、车牌字符切割:这一步其实是很重要的,有些人认为不切割字符,将整体使用OCR进行识别,这样的识别不仅效率不高还容易出错。
3、车牌文字识别:将切割好的字符使用OCR进行识别。

所采用的环境:Xcode 9.2
图片处理库:OpenCV 3.2.0
文字识别库:TesseractOCRiOS 4.0.0

这篇文章只介绍第一部分,即车牌定位。之前写过一篇iOS OpenCV 身份证静态识别浅谈,有兴趣可以看看。

但是不得不说身份证识别和车牌识别差距比较大。原因在于,一般来说身份证占据着整个相机图片,而车牌不是,车牌往往只是相机图片中一个小小的元素,远小于身份证,这就给识别带来了不小的难度。我们无法再使用取最大轮廓的方式。

基于车牌的特征,我们可以想到是根据车牌的形状或者车牌的颜色,这里我是根据车牌的形态特征进行识别。

我采用的步骤是:
1、高斯模糊
2、灰度
3、垂直边缘检测
4、二值化
5、形态学闭操作
6、寻找轮廓

下面就简单讲解一下各个步骤的大概情况:
1、高斯模糊:模糊的作用在图像识别中一般都是降噪,但是需要注意参数的配值。

采用的函数是:

CV_EXPORTS_W void GaussianBlur( InputArray src, OutputArray dst, Size ksize,
                            double sigmaX, double sigmaY = 0,
                            int borderType = BORDER_DEFAULT );

2、灰度:这里取出蓝色通道,因为识别的是蓝色车牌,取出蓝色通道能够加强识别。

采用的函数是:

CV_EXPORTS void mixChannels(const Mat* src, size_t nsrcs, Mat* dst, size_t ndsts,
                        const int* fromTo, size_t npairs);

3、垂直边缘检测:即著名的Sobel算子,这是一个基于形态的算子,我们通过设置水平求导,使车牌字符紧密串连起来。

采用的函数是:

CV_EXPORTS_W void Sobel( InputArray src, OutputArray dst, int ddepth,
                     int dx, int dy, int ksize = 3,
                     double scale = 1, double delta = 0,
                     int borderType = BORDER_DEFAULT );

4、二值化:这一步通过0或者255两种值,将车牌与非车牌的轮廓描绘出来。

采用的函数是:

CV_EXPORTS_W double threshold( InputArray src, OutputArray dst,
                           double thresh, double maxval, int type );

5、形态学闭操作:形态学闭操作的作用是将刚才字符轮廓进行融合,变成一个整体,然后呈现符合车牌大小的矩形轮廓。闭操作也就是先膨胀后腐蚀,参数大小的配置也是极其重要的。

采用的函数是:

CV_EXPORTS_W void morphologyEx( InputArray src, OutputArray dst,
                            int op, InputArray kernel,
                            Point anchor = Point(-1,-1), int iterations = 1,
                            int borderType = BORDER_CONSTANT,
                            const Scalar& borderValue = morphologyDefaultBorderValue() );

6、寻找轮廓:经过上述的5个步骤之后,所获得的轮廓也算清晰了,然后经过一系列的筛选条件就能基本定位出车牌了。

采用的函数是:

CV_EXPORTS void findContours( InputOutputArray image, OutputArrayOfArrays contours,
                          int mode, int method, Point offset = Point());

车牌定位的操作到这里也算是结束了。但是其实这种定位方式有个很大的问题在于你无法知道你的相机和车牌之间的距离,无法知道这个距离时,对第5步骤的影响还是很大的。所以,其实这种方式的形态识别并不是一种很好的识别方式,试用场景有限,难以覆盖全部车牌。

之前尝试过不少方向,但效果都不理想:
1、尝试过将图片切成1块1块地来识别,不过这种方式可能会破坏车牌。
2、尝试过基于颜色的识别,不过按照网上的教程配置HSV的参数屡屡受阻,发现并不适用。
3、尝试过增强车牌的对比度和亮度,以加强步骤4中二值化的结果,效果也不理想。

尾记:目前来说并没有一种优秀的算法方式能够准确地覆盖所有的车牌,只能经过大数据取材,然后去掉一些不符合条件的因素,才能最终形成比较完善的识别。

作者:随行的羊
链接:https://www.jianshu.com/p/fd444615dfed

正文到此结束
Loading...