使用opencv进行车牌提取及识别

您所在的位置:网站首页 怎么用图片搜车牌号码 使用opencv进行车牌提取及识别

使用opencv进行车牌提取及识别

#使用opencv进行车牌提取及识别| 来源: 网络整理| 查看: 265

商业合作可联系:[email protected]

目录

1车牌提取过程 1.1车辆图像获取1.2车牌定位1.3车牌字符分割2车牌提取 2.1灰度化2.2Candy边缘检测2.3形态学(膨胀腐蚀)处理2.4轮廓处理2.5自适应二值化处理3字符提取分割 3.1像素值判断3.2确认字符位置

 

车牌提取过程

一个典型的车辆牌照识别系统一般包括以下4个部分:车辆图像获取、车牌定位、车牌字符分割和车牌字符识别 。

本篇文章只介绍车牌的提取分割过程,关于如何对分割后的字符进行识别 ,请看我的另一篇WIKI ,opencv基于人工神经网络的字母识别。

车辆图像获取

车辆图像获取是车牌识别的第一步,也是很重要的一步,车辆图像的好坏对后面的工作有很大的影响。如果车辆图像的质量太差,连人眼都没法分辨,那么肯定不会被机器所识别出来。车辆图像都是在实际现场拍摄出来的,实际环境情况比较复杂,图像受天气和光线等环境影响较大,在恶劣的工作条件下系统性能将显著下降。 现有的车辆图像获取方式主要有两种:一种是由彩色摄像机和图像采集卡组成,其工作过程是:当车辆检测器(如地感线圈、红外线等)检测到车辆进入拍摄范围时,向主机发送启动信号,主机通过采集卡采集一幅车辆图像,为了提高系统对天气、环境、光线等的适应性,摄像机一般采用自动对焦和自动光圈的一体化机,同时光照不足时还可以自动补光照明,保证拍摄图片的质量;另一种是由数码照相机构成,其工作过程是:当车辆检测器检测到车辆进入拍摄范围时,直接给数码照相机发送一个信号,数码相机自动拍摄一幅车辆图像,再传到主机上,数码相机的一些技术参数可以通过与数码相机相连的主机进行设置,光照不足时也需要自动开启补光照明,保证拍摄图片的质量。

图(有车牌的图像)

车牌定位

车牌定位的主要工作是从摄入的汽车图像中找到汽车牌照所在位置,并把车牌从该区域中准确地分割出来,供字符分割使用。因此,牌照区域的确定是影响系统性能的重要因素之一,牌照的定位与否直接影响到字符分割和字符识别的准确率。目前车牌定位的方法很多,但总的来说可以分为以下4类:(1)基于颜色的分割方法,这种方法主要利用颜色空间的信息,实现车牌分割,包括彩色边缘算法、颜色距离和相似度算法等;(2)基于纹理的分割方法,这种方法主要利用车牌区域水平方向的纹理特征进行分割,包括小波纹理、水平梯度差分纹理等;(3)基于边缘检测的分割方法;(4)基于数学形态法的分割方法。 本文为了代码实现上的方便,我采用的是基于边缘检测的分割方法。主要是利用水平投影方法和垂直投影方法进行车牌定位。

车牌字符分割

要识别车牌字符,前提是先进行车牌字符的正确分割与提取。字符分割的任务是把多列或多行字符图像中的每个字符从整个图像中切割出来成为单个字符。车牌字符的正确分割对字符的识别是很关键的。传统的字符分割算法可以归纳为以下三类:直接分割法、基于识别基础上的分割法、自适应分割线类聚法。直接分割法简单,但它的局限是分割点的确定需要较高的准确性;基于识别基础上的分割法是把识别和分割结合起来,但是需要识别的高准确性,它根据分类和识别的耦合程度又有不同的划分;自适应分割线聚类法是要建立一个分类器,用它来判断图像的每一列是否是分割线,它是根据训练样本来进行自适应学习的神经网络分类器,但对于粘连字符训练困难。也有直接把字符组成的单词当作一个整体来识别的,诸如运用马尔科夫数学模型等方法进行处理,这些算法主要应用于印刷体文本识别。

车牌提取 灰度化

灰度化的概念就是将一张三通道RGB颜色的图像变成单通道灰度图,为接下来的图像处理做准备。

//灰度化 Mat gray_image; cvtColor(image, gray_image, CV_RGB2GRAY); imshow("test", gray_image);

图(灰度图)

Candy边缘检测

Canny边缘检测算子的方向性质保证了很好的边缘强度估计,而且能同时产生边缘梯度方向和强度两个信息,即能在一定程度上抗噪声又能保持弱边缘,因此采用以canny算子做边缘检测。

Canny算法步骤:

(1)去噪

任何边缘检测算法都不可能在未经处理的原始数据上很好地處理,所以第一步是对原始数据与高斯 mask 作卷积,得到的图像与原始图像相比有些轻微的模糊(blurred)。这样,单独的一个像素雜訊在经过高斯平滑的图像上变得几乎没有影响。

(2)用一阶偏导的有限差分来计算梯度的幅值和方向。

(3)对梯度幅值进行非极大值抑制。

车牌细定位的目的是为下一步字符的分割做,就是要进一步去掉车牌冗余的部分。在一幅经过适当二值化处理 含有车牌的图像中,车牌区域具有以下三个基本特征:

1.在一个不大的区域内密集包含有多个字符;

2.车牌字符与车牌底色形成强烈对比;

3.车牌区域大小相对固定,区域长度和宽度成固定比例。

//Candy/sobel 边缘检测: Mat candy_image; Canny(blur_image, candy_image, 500, 200, 3); //imshow("test", candy_image);

图(边缘检测)

形态学(膨胀腐蚀)处理

膨胀与腐蚀的处理效果就如其名字一样,我们通过膨胀连接相近的图像区域,通过腐蚀去除孤立细小的色块。通过这一步,我们希望将所有的车牌号字符连通起来,这样为我们接下来通过轮廓识别来选取车牌区域做准备。由于字符都是横向排列的,因此要连通这些字符我们只需进行横向的膨胀即可。

进行膨胀腐蚀操作需要注意的是要一次到位,如果一次膨胀没有连通到位,那么再次腐蚀将会将图像回复原装,因此我首先做了2次迭代的膨胀,保证数字区域能连通起来,再进行4次迭代腐蚀,尽可能多的去除小块碎片,随后2次迭代膨胀,保证膨胀次数与腐蚀次数相同,以回复连通区域形态大小。

矩形轮廓查找与筛选:经过上一步操作,理论上来说车牌上的字符连通成一个矩形区域,通过轮廓查找我们可以定位该区域。当然,更为准确的说,经过上面的操作,我们将原始图片中在X方向排列紧密的纵向边缘区域连通成了一个矩形区域,出了车牌符合这个特点外,其他一些部分如路间栏杆,车头的纹理等同样符合。因此我们会找到很多这样的区域,这就需要我们进一步根据一些关于车牌特点的先验知识对这些矩形进行进一步筛选。最终,定位车牌所在的矩形区。

//形态学处理 //图片膨胀处理 Mat dilate_image, erode_image; //自定义 核进行 x 方向的膨胀腐蚀 Mat elementX = getStructuringElement(MORPH_RECT, Size(25, 1)); Mat elementY = getStructuringElement(MORPH_RECT, Size(1, 19)); Point point(-1, -1); dilate(candy_image, dilate_image, elementX, point, 2); erode(dilate_image, erode_image, elementX, point, 4); dilate(erode_image, dilate_image, elementX, point, 2); //自定义 核进行 Y 方向的膨胀腐蚀 erode(dilate_image, erode_image, elementY, point, 1); dilate(erode_image, dilate_image, elementY, point, 2); //imshow("test", dilate_image); //waitKey(1000); imwrite("dilate_image.jpg", dilate_image); //噪声处理 //平滑处理 中值滤波 Mat blurr_image; medianBlur(dilate_image, blurr_image, 15); medianBlur(blurr_image, blurr_image, 15); imshow("test", blurr_image);

图(形态学处理)

轮廓处理

提取轮廓

//矩形轮廓查找与筛选: Mat contour_image; //深拷贝 查找轮廓会改变源图像信息,需要重新 拷贝 图像 contour_image = blurr_image.clone(); vector contours; findContours(contour_image, contours, CV_RETR_EXTERNAL, CHAIN_APPROX_SIMPLE); //画出轮廓 drawContours(contour_image, contours, -1, Scalar(255), 1); //轮廓表示为一个矩形 车牌提取 Mat roi_image; vector rectPoint; for (int i = 0; i < contours.size(); i++) { Rect r = boundingRect(Mat(contours[i])); //RotatedRect r = minAreaRect(Mat(contours[i])); cout


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3