内容发布更新时间 : 2024/12/31 4:56:42星期一 下面是文章的全部内容请认真阅读。
车牌识别源代码部份流程(供参考一)
实际上车牌识别代码量并不是很大,如果不停的手工输入;用不到一天的时间,即可大功告成。但是程序需要反复调试,才可以走向成熟。所以工作量是很大的。另外车牌识别还有其本身的特点——理论并不成熟。这就给车牌识别带来了更多的工作量。一般来说,开发车牌识别程序,先按照最原始最朴素的思想编码,然后是不断地优化。这将贯彻到整个车牌识别的开发过程中去。
车牌识别最基本的流程是:将采集后的图像二值化,然后依次经过车牌定位、字符分割、去除干扰,最后是字符识别。有时还会加入本节前面部分所叙述的思想(比如回溯)。 下面将分五章具体介绍每一个模块。 一、二值化
二值化是车牌识别的第一步。二值化前后的对比如下图:
二值化的算法很简单,首先有一个亮度的阈值(threshold),对每一个像素的亮度和这个阈值做比较,根据比较结果得出车牌的前景和背景。用c/c++描述如下: void CLPR::Binary(int threshold) {
int y;
for(y=0;y int x; for(x=0;x unsigned char red,green,blue; GetPixel(red,green,blue,x,y); int bright; bright=red+green; if(m_search_blue_plate) { if(bright<=threshold) SetBinary(x,y,BACKGROUND); else SetBinary(x,y,FOREGOUND); } else //we are searching yellow plate { if(bright>=threshold) SetBinary(x,y,FOREGOUND); else SetBinary(x,y,BACKGROUND); } } } } 二值化算法虽然简单,但是阈值却不容易寻找。本章后面的部分,将重点介绍各种求解阈值的算法。 1、OTSU算法 OTSU算法的思想是:把输入图像首先转换成灰度图象,然后对图像进行直方图分析。如果直方图呈双峰分布。那么双峰之间的“谷”就是阈值。从统计学角度讲,阈值两边的距离最大。 由于车牌识别的特殊性,图象象素点的亮度为该象素点的红色分量和绿色分量的和,并且忽略蓝色分量。这一点对蓝色车牌和黄色车牌都是适用的。 OTSU算法仅对直方图呈双峰分布的图像有效。 全部代码如下: void LPR::OTSU() { //直方图统计 { int index; for(index=0;index int y; for(y=0;y<=m_height;y++) { int x; for(x=0;x<=m_width;x++) { int bright; bright=Bright(x,y); m_pixel_number[bright]++; } } } //真正求阈值 double sum; sum=0; int n; n=0; int k; for(k=0;k<=(m_bright_level_count-1);k++) { sum+=k*m_pixel_number[k]; n+=m_pixel_number[k]; } double c_sum; c_sum=0.0; double f_max; f_max=-1.0; int n1; n1=0; for(k=0;k<(m_bright_level_count-1);k++) { n1+=m_pixel_number[k]; if (n1==0) continue; int n2; n2=n-n1; if(n2==0) break; c_sum+=(double)k*m_pixel_number[k]; double m_1,m_2; m_1=c_sum/n1; m_2=(sum-c_sum)/n2; double sb; sb=(m_1-m_2)*(m_1-m_2)*(double)n1*(double)n2; if (f_max f_max=sb; m_prepare_threhold=(int)(k+0.5); } } } 2、Matlab算法 使用Matlab进行车牌识别,也是一个比较好的选择。在Matlab的环境中首先把输入的彩色图像使用命令rgb2gray转换成灰度图像。有了灰度图像就可以使用命令graythresh获得阈值了。最后使用命令im2bw对图像进行二值化。十分方便!代码如下: I=imread('blood1.tif'); imhist(I); % 人工观察灰度直方图,发现灰度120处有谷,确定阈值T=120 I1=im2bw(I,120/255); % im2bw函数需要将灰度值转换到[0,1]范围内 figure,imshow(I1); 改进为 I=imread('blood1.tif'); imhist(I); I1=graythresh(I); % im2bw函数需要将灰度值转换到[0,1]范围内 figure,imshow(I1); 二、车牌定位 图像二值化,占用车牌识别中的大部分时间,也是最难的。在二值化之后,车牌识别将变得比较难。车牌定位为二值化后的第一步。下面分小节分别介绍各种车牌定位算法。 车牌识别过程中,角点定位的基本思想是。在所有的边界点中,如果某些点的曲率半径比较小,那么这些点叫做“角点”:如下图所示(角点用红点表示): 图中字符上和车牌的四角都有角点。但是这并不影响车牌的定位。 根据距离最大的四个角点,得到了车牌的四个角,从而定了车牌。从角点定位的原理看出,如果经过旋转后车牌并不会影响角点定位的成功率和速度。 该算法的实现可以采取遍历匹配的算法,实现如下: void LPR::GetConere() { int y; for(y=0;y int x; for(x=0;x if(Line(x,y,x+4,y)>=3) { if(Line(x,y,x,y+4)>=3) { if(Line(x+1,y+1,x+4,y+4)<=1) Add(x,y,LEFT_TOP_CONNER); } if(Line(x,y,x,y-4)>=3) { if(Line(x+1,y-1,x+4,y-4)<=1) Add(x,y,LEFT_DOWN_CONNER); } } if(Line(x,y,x-4,y)>=3) { if(Line(x,y,x,y+4)>=3) { if(Line(x-1,y+1,x-4,y+4)<=1) Add(x,y,RIGHT_TOP_CONNER); } if(Line(x,y,x,y-4)>=3) { if(Line(x-1,y-1,x-4,y-4)<=1) Add(x,y,RIGHT_DOWN_CONNER); } } } } } 函数Line(x1,y1,x2,y2)返回过两点(x1,y1),(x2,y2)的直线,前景的象素个数。 注意这里的4,是检验角点的区域范围,如果区域过大,图像旋转时就会影响车牌定位的成功率。 1、上下定位方法