车牌号识别系统原理图都能识别什么车牌?

还没有帐号? 赶紧
用户版块帖子
现在这智能车牌识别系统不得了
UID:20059
在线时间3170小时
M币32623专家4
来商场看电影,吃饭。在地下停车场,可以找到你的车,可以微信支付自动抬杆,太厉害=740) window.open('http://img.mydigit.net/Mon_59_45e70.jpg?235');" style="max-width:100%;" onload="if(is_ie6&&this.offsetWidth>740)this.width=740;" title="现在这智能车牌识别系统不得了" alt="现在这智能车牌识别系统不得了"> =740) window.open('http://img.mydigit.net/Mon_59_c1799cc4bbb2f3b.jpg?196');" style="max-width:100%;" onload="if(is_ie6&&this.offsetWidth>740)this.width=740;" title="现在这智能车牌识别系统不得了" alt="现在这智能车牌识别系统不得了">=740) window.open('http://img.mydigit.net/Mon_59_ac80.png?168');" style="max-width:100%;" onload="if(is_ie6&&this.offsetWidth>740)this.width=740;" title="现在这智能车牌识别系统不得了" alt="现在这智能车牌识别系统不得了">
[ 此帖被gungum在 21:40重新编辑 ]
科技的力量
6元能停多久?2个小时吗?
謝謝分享,人真的很聪明啊,享受高科技带来的便利&&老规矩有M必回,为了22合一
我们这新车场都这样了
简单的停车场用plc编我都还不会
车牌就不要爆了,涉及隐私
科技越来越发达
UID:794486
在线时间3023小时
M币62专家12
陕A@#¥%! 这么大的车牌号 你当我们跟你一样视而不见吗 [ 此帖被damu在 21:47重新编辑 ]
你这马赛克打的,呵呵。陕A725MG。
UID:1757964
在线时间281小时
M币2834专家2
头像搞笑啊,啊啊
UID:109030
在线时间1142小时
M币6583专家1
还有雪铁龙
UID:1025786
在线时间1035小时
M币1625专家0
你这马赛克打的,呵呵。&&&& [ 此帖被mingzhu00在 09:11重新编辑 ]
请删车牌号,谢谢!
UID:20059
在线时间3170小时
M币32623专家4
隐私暴露啦,客户端怎么不能编辑!?
呵呵,用电脑才行?
在线时间15474小时
M币27532专家322
登陆网页版编辑吧
也删不了!算了😁
UID:1770032
在线时间196小时
M币4409专家0
主要是摄像头多
UID:1978033
在线时间482小时
M币7054专家1
这玩意早有了&& 单位都是自动识别车牌后抬杆放行的&&只不过门口多了一个感应区录入过系统的车牌&&不用再麻烦到车辆上面装感应器了
UID:228506
在线时间5604小时
M币1113专家77
这算什么,技术难度不大的,你看这个新闻“90后司机开套牌车自驾游 遇交警把牌照掰碎 ”,里面提到“”国庆首日,高速车流出现井喷态势,一辆车牌号为鄂J1092*本田思域牌小车在经过二广高速东岳庙卡口时,查缉布控系统报警提示有假牌嫌疑,湖北省高警公安大队执勤民警立即在前方收费站进行拦截检查。“”人家这么大的车流都能实时监控并且及时联网核查,那个计算量和处理速度才算快
交警的当然先进啦
访问内容超出本站范围,不能确定是否安全
“新手上路”发帖需审核后才能显示(请认真发帖),达到数码9级后取消此限制
您目前还是游客,请
&回复后跳转到最后一页
Code by , Time now is:09-06 19:06, Total 0.124608(s) query 7,
Gzip enabled&  我正在做一个开源的,Git地址为:/liuruoze/EasyPR。
  我给它取的名字为EasyPR,也就是Easy to do Plate Recognition的意思。我开发这套系统的主要原因是因为我希望能够锻炼我在这方面的能力,包括C++技术、计算机图形学、机器学习等。我把这个项目开源的主要目的是:1.它基于开源的代码诞生,理应回归开源;2.我希望有人能够一起协助强化这套系统,包括代码、训练数据等,能够让这套系统的准确性更高,鲁棒性更强等等。
  相比于其他的车牌识别系统,EasyPR有如下特点:
它基于openCV这个开源库,这意味着所有它的代码都可以轻易的获取。
它能够识别中文,例如车牌为苏EUK722的图片,它可以准确地输出std:string类型的"苏EUK722"的结果。
它的识别率较高。目前情况下,字符识别已经可以达到90%以上的精度。
  系统还提供全套的训练数据提供(包括车牌检测的近500个车牌和字符识别的4000多个字符)。所有全部都可以在Github的项目地址上直接下载到。
  那么,EasyPR是如何产生的呢?我简单介绍一下它的诞生过程:
  首先,在5月份左右时我考虑要做一个车牌识别系统。这个车牌系统中所有的代码都应该是开源的,不能基于任何黑盒技术。这主要起源于我想锻炼自己的C++和计算机视觉的水平。
  我在网上开始搜索了资料。由于计算机视觉中很多的算法我都是使用openCV,而且openCV发展非常良好,因此我查找的项目必须得是基于OpenCV技术的。于是我在CSDN的博客上找了一篇。
  文章的作者taotao1233在这两篇博客中以半学习笔记半开发讲解的方式说明了一个车牌识别系统的全部开发过程。非常感谢他的这些博客,借助于这些资料,我着手开始了开发。当时的想法非常朴素,就是想看看按照这些资料,能否真的实现一个车牌识别的系统。关于车牌照片数据的问题,幸运的很,我正在开发的一个项目中有大量的照片,因此数据不是问题。
  令人高兴的是,系统确实能够工作,但是让人沮丧的,似乎也就&仅仅&能够工作而已。在车牌检测这个环节中正确性已经惨不忍睹。
  这个事情给了我一拨不小的冷水,本来我以为很快的开发进度看来是乐观过头了。于是我决定沉下心来,仔细研究他的系统实现的每一个过程,结合OpenCV的官网教程与API资料,我发现他的实现系统中有很多并不适合我目前在做的场景。
  我手里的数据大部分是高速上的图像抓拍数据,其中每个车牌都偏小,而且模糊度较差。直接使用他们的方法,正确率低到了可怕的地步。于是我开始尝试利用openCv中的一些函数与功能,替代,增加,调优等等方法,不断的优化。这个过程很漫长,但是也有很多的积累。我逐渐发现,并且了解他系统中每一个步骤的目的,原理以及如果修改可以进行优化的方法。
  在最终实现的代码中,我的代码已经跟他的原始代码有很多的不一样了,但是成功率大幅度上升,而且车牌的正确检测率不断被优化。在系列文章的后面,我会逐一分享这些优化的过程与心得。
  最终我实现的系统与他的系统有以下几点不同:
他的系统代码基本上完全参照了《Mastering OpenCV with Practical Computer Vision Projects》这本书的代码,而这本书的代码是专门为西班牙车牌所开发的,因此不适合中文的环境。
他的系统的代码大部分是原始代码的搬迁,并没有做到优化与改进的地步。而我的系统中对原来的识别过程,做了很多优化步骤。
车牌识别中核心的机器学习算法的模型,他直接使用了原书提供的,而我这两个过程的模型是自己生成,而且模型也做了测试,作为开源系统的一部分也提供了出来。
  尽管我和他的系统有这么多的不同,但是我们在根本的系统结构上是一致的。应该说,我们都是参照了&Mastering OpenCV&这本数的处理结构。在这点上,我并没有所&创新&,事实上,结果也证明了&Mastering OpenCV&上的车牌识别的处理逻辑,是一个实际有效的最佳处理流程。
  &Mastering OpenCV&,包括我们的系统,都是把车牌识别划分为了两个过程:即车牌检测(Plate Detection)和字符识别(Chars Recognition)两个过程。可能有些书籍或论文上不是这样叫的,但是我觉得,这样的叫法更容易理解,也不容易搞混。
车牌检测(Plate Detection):对一个包含车牌的图像进行分析,最终截取出只包含车牌的一个图块。这个步骤的主要目的是降低了在车牌识别过程中的计算量。如果直接对原始的图像进行车牌识别,会非常的慢,因此需要检测的过程。在本系统中,我们使用SVM(支持向量机)这个机器学习算法去判别截取的图块是否是真的&车牌&。
字符识别(Chars Recognition):有的书上也叫Plate Recognition,我为了与整个系统的名称做区分,所以改为此名字。这个步骤的主要目的就是从上一个车牌检测步骤中获取到的车牌图像,进行光学字符识别(OCR)这个过程。其中用到的机器学习算法是著名的人工神经网络(ANN)中的多层感知机(MLP)模型。最近一段时间非常火的&深度学习&其实就是多隐层的人工神经网络,与其有非常紧密的联系。通过了解光学字符识别(OCR)这个过程,也可以知晓深度学习所基于的人工神经网路技术的一些内容。
  下图是一个完整的EasyPR的处理流程:
  本开源项目的目标客户群有三类:
需要开发一个车牌识别系统的(开发者)。
需要车牌系统去识别车牌的(用户)。
需要做毕业设计的(学生)。
  第一类客户是本项目的主要使用者,因此项目特地被精心划分为了6个模块,以供开发者按需选择。  第二类客户可能会有部分,EasyPR有一个同级项目EasyPR_Dll,可以DLL方式嵌入到其他的程序中,另外还有个一个同级项目EasyPR_Win,基于WTL开发的界面程序,可以简化与帮助车牌识别的结果比对过程。  对于第三类客户,最好在EasyPR的基础上加上自己的创新与调整,这样形成的设计才有价值,有见地,并且能够有底气通过设计会审。
  推荐你使用EasyPR有以下几点理由:
这里面的代码都是作者亲自优化过的,你可以在上面做修改,做优化,甚至一起协作开发,一些处理车牌的细节方法你应该是感兴趣的。
如果你对代码不感兴趣,那么经过作者精心训练的模型,包括SVM和ANN的模型,可以帮助你提升或验证你程序的正确率。
如果你对模型也不感兴趣,那么成百上千经过作者亲自挑选的训练数据生成的文件,你应该感兴趣。作者花了大量的时间处理这些训练数据与调整,现在直接提供给你,可以大幅度减轻很多人缺少数据的难题。
  有兴趣的同志可以留言或发Email: 或者直接在Git上发起pull requet,都可以,未来我会在cnblogs上发布更多的关于系统的介绍,包括编码过程,训练心得。
  最后,祝大家国庆快乐,节日顺利!
阅读(...) 评论()36279人阅读
OpenCV学习之旅(6)
1.车牌预处理
车牌预处理过程的好坏直接影响到车牌图像进行后期处理过程,比如车牌字符分割等。车牌预处理也是尽可能的消除噪声,减少后期处理带来的不必要的麻烦。
输入的车牌是24Bit的BMP真彩色图像,车牌照有黄底黑字,蓝底白字等颜色,为了将这些车牌图像一并处理,就要先将车牌进行灰度化处理,然后进行二值化(黑白)处理。
图4-1 原始图像
将采集的车牌图像进行预处理,为了方便起见,这里采用的是BMP格式的图片,我将采集的车牌图像进行了裁剪处理,裁剪后的图片如下:
由于中国大部分的车牌是第一个是汉字,第二个到第七个是字母或数字,这就可以将车牌图像识别过程分成两部分处理,第一部分是识别汉字的过程,第二部分是识别字母和数字的过程,由于汉字笔画较多,同字母或数字的处理过程有所不同。所以我这里就先处理字母或数字的过程。
除汉字外,在第一个字母和第二个数字的中间有个一点,所以在字符分割的时候要考虑去掉中间的点。车牌图像总体来说比较清晰,大型民用车,牌照为黄底黑字,小型民用车,牌照为蓝底白字&,由于字符与背景颜色对比比较明显,所以将车牌分割开来比较容易。由于有些车牌的上面和下面也有螺丝之类的东西将车牌固定,所以在将车牌分割的时候,通过水平扫描跳跃点的方法,可以去除掉,以便最后将车牌进行分割,去除这些干扰。
在RGB模型中,如果R=G=B时,则彩色表示一种灰度颜色,其中R=G=B的值叫灰度值,因此,灰度图像每个像素只需一个字节存放灰度值(又称强度值、亮度值),灰度范围为0-255。一般有四种方法对彩色图像进行灰度化。
1. 分量法。就是将每个分量上的颜色值即RGB3种颜色提取出来。即:将彩色图像中的三分量的亮度作为三个灰度图像的灰度值,可根据应用需要选取一种灰度图像。f1(i,j)=R(i,j) f2(i,j)=G(i,j) f3(i,j)=B(i,j)其中fk(i,j)(k=1,2,3)为转换后的灰度图像在(i,j)处的灰度值。
2.最大值法。选取彩色图像中的三分量中(RGB)的颜色的最大值作为灰度图的灰度值。即:f(i,j)=max(R(i,j),G(i,j),B(i,j))。
3.平均值法。 将彩色图像中的三分量亮度求平均得到一个灰度图f(i,j)=(R(i,j)+G(i,j)+B(i,j))/3。
4.加权平均法。根据重要性及其它指标,将三个分量以不同的权值进行加权平均。由于人眼对绿色的敏感最高,对蓝色敏感最低,因此,按下式对RGB三分量进行加权平均能得到较合理的灰度图像。f(i,j)=0.30R(i,j)+0.59G(i,j)+0.11B(i,j))。
以上四种处理过程,在车牌预处理的过程中,我选择加权平均值法。效果如下:
& & & & & & & & & & & &&
& & & & & & & & & & & &&图4-2 原始图像 & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & 图4-3灰度图像
如上图,是将图中的原始图像进行加权平均值处理后的灰度图像。
关键代码如下:
for(i = 0;i & H i++)
&&&&&&&&&&&&& for(j= 0;j & Width*3; j+=3)
&&&&&&&&&&&&& {
&&&&&&&&&&&&&&&&&&&& ired&& =&(unsigned& char*)lpDibBits + LineBytes* i + j + 2;
&&&&&&&&&&&&&&&&&&&& igreen=& (unsigned& char*)lpDibBits + LineBytes * i + j + 1;
&&&&&&&&&&&&&&&&&&&& iblue& =&(unsigned& char*)lpDibBits + LineBytes* i +&&&&&
&&&&&&&&&&&&&&&&&&&&&&& lpdest[i*Width+ j/3]= (unsigned char)((*ired)*0.299 + (*igreen)*0.588 + (*iblue)*0.114);//加权平均值计算处理
&&&&&&&&&&&&& }
二值化处理。二值化处理即将BMP图像进行黑白处理,使背景与字符区分开。由于灰度化后的图像是0-255之间的颜色值。而进行二值化处理的过程就是将此图像的颜色分成黑色值0和白色&#两种颜色。为了将背景与车牌字符分开,要设定一个阈值。设定阈值是关键。如果选取的二值化的阈值不当则就有可能不能将车牌图像中的背景与文字进行明显分开,所以这时二值化的阈值选取就显得非常重要。根据试验,我设定的阈值为
125。二值化后的效果如下:
图4-7& 二值化后图像
如上图是测试蓝底白字和黄底黑字的车牌图像的二值化后的效果。通过将图像进行二值化后,可以明显将背景与车牌字符进行分开。
二值化处理的关键代码如下:
&&&&&& for(i = 0; i & H i++)// 每行
&&&&&&&&&&&&& for(j = 0; j & W j++)// 每列
&&&&&&&&&&&&& {
&&&&&&&&&&&&&&&&&&&& // 指向DIB第i行,第j个象素的指针
&&&&&&&&&&&&&&&&&&&& lpSrc = (unsigned char*)lpDibBits+LineBytes *(lHeight - 1 - i) +
&&&&&&&&&&&&&&&&&&&& // 判断是否小于阈值
&&&&&&&&&&&&&&&&&&&& if ((*lpSrc) & bThre)
&&&&&&&&&&&&&&&&&&&& {
&&&&&&&&&&&&&&&&&&&&&&&&&&& *lpSrc = 0; // 直接赋值为0,即黑色
&&&&&&&&&&&&&&&&&&&& }
&&&&&&&&&&&&&&&&&&&& else
&&&&&&&&&&&&&&&&&&&& {&&&&&&&&&&&&&&&&&&&&&&&&&
*lpSrc = 255; // 直接赋值为255,即白色
&&&&&&&&&&&&&&&&&&&& }
&&&&&&&&&&&&& }
2.字符分割
由于车牌图像做了细化处理后,可以进行水平扫描和垂直扫描将字符分开,水平扫描确定图片的上下限,垂直扫描可以确定图片中字符的左右坐标。根据车牌的特征,先将车牌图像进行水平扫描跳跃点,即水平相邻的两个像素,如果不相同则认为有一个跳跃点,记录次数加1,由于车牌上面有时候会有两个白点,所以通过判断跳跃点的个数,可以将上面的两个白点去掉[9]。如图,扫描处理的跳跃点统计如下:
图4-10 原始图像,上面有两个白点
图4-11水平扫描跳跃点的个数统计
统计结果:4 4 4 0 0 14 14 16 20 24 24 24 24 22 20 24 26 28 28 30
20 22 22 22 26 20 20 22 24 20 20 20 20 2 0 4 4 6 4像素。扫描结果数量个数为的车牌高度的个数。
从上往下查找,根据实验结果,设置当水平跳跃点超过10个的时候,作为车牌字符截取的上限。当从下往上查找,当跳跃点超过8个的时候可以作为车牌字符截取的下限。通过上面的过程,基本可以确定车牌的上部和下部。同样,分割车牌字符左右边界时,通过垂直扫描过程,由于数字和字母具有连通性,所以分割数字和字母比较容易。通过垂直扫描过程,统计黑色像素点的个数,由于两个字符之间没有黑像素,所以可以作为字符分割的界限。垂直扫描过程如下图:
&&&&&& 陕&&&&&&&&& &A&&&&& .&&& 5&&&&&&&P&&&&&&&& 0&&&&&& 7&&&&&&&2
图4-12& 垂直扫描车牌字符黑像素个数统计
通过上面的统计可以很容易的把字符作用边界进行分割开来。通过水平扫描跳跃点和垂直扫描像素点,可以分开字符。但是其中还有些问题。比如有些汉字不是联通性,如“陕”字,左耳旁和右边的“夹”字,有时候扫描的时候会有空隙,所以我这里在扫描第一个汉字的时候,要多加一些处理,当“陕”的左耳旁的宽度不为总宽度的1/12时候,我继续向下扫描,直到找到为零的像素。还有就是A与5之间会有一个“.”号,这个可以通过扫描的宽度不为宽度的3/8时,我可以认为是中间的“.”号。所以通过以上的处理,基本能把大部分的车牌图像字符进行分割。字符分割后的效果如下图所示:
& & & & & & & 图4-13字符分割图像
字符分割关键代码如下:
&&&&&& //如果距离少于宽度的1/12,则计为无效
&&&&&& intwid = lWidth/13;
&&&&&& intxx=0,pos=0;
&&&&&& intflag = 0;
&&&&&& intsuccess = 0;
&&&&&& for(i=0;i&lW)
&&&&&&&&&&&&& while(VCount[i]==0)i++;
&&&&&&&&&&&&& if((i-1)&0)
&&&&&&&&&&&&&&&&&&&& posi[k++]=i;
&&&&&&&&&&&&& else
&&&&&&&&&&&&&&&&&&&& posi[k++]=i-1;
&&&&&&&&&&&&& xx=0;
&&&&&&&&&&&&& while(VCount[i]!=0&& i&lWidth) i++;
&&&&&&&&&&&&& if(flag==0)
&&&&&&&&&&&&& {
&&&&&&&&&&&&&&&&&&&& pos=
&&&&&&&&&&&&&&&&&&&& while(VCount[i]==0){i++;xx++;}
&&&&&&&&&&&&&&&&&&&& if(xx & (wid/4))
&&&&&&&&&&&&&&&&&&&& {
str.Format(&xx=%d wid/4=%d i=%dposi[k-1]=%d&,xx,wid/4,i,posi[k-1]);
&&&&&&&&&&&&&&&&&&&&&&&&&&& MessageBox(&汉字有分割&+str);
&&&&&&&&&&&&&&&&&&&&&&&&&&& xx=0;
&&&&&&&&&&&&&&&&&&&&&&&&&&& while(VCount[i]!=0){i++;xx++;}
&&&&&&&&&&&&&&&&&&&&&&&&&&& if(xx&=8)
&&&&&&&&&&&&&&&&&&&&&&&&&&& {
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& xx= 0;
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& while(VCount[i]==0){i++;xx++;}
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& if(xx&(lWidth/16))
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& while(VCount[i]!=0 && i&(lWidth/8)) i++;
&&&&&&&&&&&&&&&&&&&&&&&&&&& }
&&&&&&&&&&&&&&&&&&&& }
&&&&&&&&&&&&&&&&&&&& else
&&&&&&&&&&&&&&&&&&&& {
&&&&&&&&&&&&&&&&&&&&&&&&&&& i=
&&&&&&&&&&&&&&&&&&&& }
&&&&&&&&&&&&& }
&&&&&&&&&&&&& flag=1;
&&&&&&&&&&&&& if(i&= lWidth)
&&&&&&&&&&&&& {
&&&&&&&&&&&&&&&&&&&& posi[k++]=i-1;
&&&&&&&&&&&&& }
&&&&&&&&&&&&& else
&&&&&&&&&&&&& {
&&&&&&&&&&&&&&&&&&&& posi[k++]=i+1;
&&&&&&&&&&&&& }
&&&&&&&&&&&&& //如果是字符第二个和第三个字符中间的点,去除。如果是1,宽度增加
&&&&&&&&&&&&& if(posi[k-1]-posi[k-2]&=wid)
&&&&&&&&&&&&& {
&&&&&&&&&&&&&&&&&&&& if(i&=(lWidth/8*3))
&&&&&&&&&&&&&&&&&&&& {
&&&&&&&&&&&&&&&&&&&&&&&&&&& intx = posi[k-1]-posi[k-2]; k=k-2;&
&&&&&&&&&&&&&&&&&&&&&&&&&&& str.Format(&%d%d %d %d&,x,wid,i,BottomLine-TopLine);
&&&&&&&&&&&&&&&&&&&& }
&&&&&&&&&&&&&&&&&&&& else
&&&&&&&&&&&&&&&&&&&& {
&&&&&&&&&&&&&&&&&&&&&&&&&&& posi[k-1]= posi[k-1]+wid/3;
&&&&&&&&&&&&&&&&&&&&&&&&&&& posi[k-2]= posi[k-2]-wid/3;
&&&&&&&&&&&&&&&&&&&& }
&&&&&&&&&&&&& }
&&&&&&&&&&&&& if(k&=14)
&&&&&&&&&&&&& {
&&&&&&&&&&&&&&&&&&&& success= 1;
&&&&&&&&&&&&& &&&&&&
&&&&&&&&&&&&& }
&&&&&& if(success== 0)
&&&&&&&&&&&&& MessageBox(&字符分隔出错,程序结束识别过程!&);
3.归一化处理
字符分割的好坏关系到后面归一化处理关键。如果字符分割不成立,归一化处理过程也就不能成功。刚开始实验的时候,我先进行的细化处理,然后再进行归一化处理,但是归一化处理后有,字符基本失去了原来的骨架结构,所以我这里先进行归一化处理。
所谓归一化处理,就是为了在分割字符时,字符大小不相同,所以要将字符归一化为25×50像素大小的图像。图像x轴缩放比率为 ,y轴缩放比率为 ,原图像宽度和高度为lWidth,lHeight[12]。缩放比率由公式:
在放大或缩小图像过程中,产生的像素可能在原图中不能找到相应的像素点。这样就必须采用插值处理的方法。一般插值处理的方法有两种,一种是直接赋值为与它最相邻的像素值,另一种则通过插值算法来计算相应像素值。第一种方法计算过程较简单效率高,但是效果不是很好,比如有时候会出现马赛克现象;所以,这里采用第二种方法,虽然预算量有点复杂,但是最后归一化后的字符不会失真。对后面做细化处理过程做好了铺垫。通过实验得出,采用双线性插值法比最近邻插值法效果好,所以本文中归一化采用双线性插值法。
&图4-14 上面为原图像二值化后的结果,下面图像为归一化后的结果
归一化关键代码如下:
&&&&&& //针对图像每行进行操作
&&&&&&&&&&&&& for(i= 0; i & NewH i++)
&&&&&&&&&&&&& {
&&&&&&&&&&&&&&&&&&&& //针对图像每列进行操作
&&&&&&&&&&&&&&&&&&&& for(j= 0; j & NewW j++)
&&&&&&&&&&&&&&&&&&&& {
&&&&&&&&&&&&&&&&&&&&&&&&&&& //指向新DIB第i行,第j个象素的指针
&&&&&&&&&&&&&&&&&&&&&&&&&&& //注意此处宽度和高度是新DIB的宽度和高度
lpDst = (char*)lpNewDIBBits + NewLineBytes * (NewHeight - 1 - i) +
&&&&&&&&&&&&&&&&&&&&&&&&&&& x= j / fXZoomR
&&&&&&&&&&&&&&&&&&&&&&&&&&& y= i / fYZoomR
&&&&&&&&&&&&&&&&&&&&&&&&&&& if(tag)
&&&&&&&&&&&&&&&&&&&&&&&&&&& {&&&& //tag=1,则执行以下的最近邻插值代码
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& i0= (LONG) (y + 0.5);
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& j0= (LONG) (x + 0.5);
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //判断是否在源图范围内
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& if((j0 &= 0) && (j0 & Width) && (i0 &= 0) && (i0& Height))
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& {
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //指向源DIB第i0行,第j0个象素的指针
lpSrc = (char*)lpTempDIBBits + LineBytes * (Height - 1 - i0) + j0;
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *lpDst= *lpS
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& }
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& else
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& {
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //对于源图中没有的象素,直接赋值为255
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *((unsigned char*)lpDst) = 255;
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& }
&&&&&&&&&&&&&&&&&&&&&&&&&&& }
&&&&&&&&&&&&&&&&&&&&&&&&&&& else
&&&&&&&&&&&&&&&&&&&&&&&&&&& {//否则,执行下面的双线性插值代码
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& doublem = x - LONG(x);//X方向的小数部分
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& doublen = y - LONG(y);//Y方向的小数部分
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& unsignedchar rd, ld, lu,//r:右;l:左;d:下;u:上
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
ld= *((char *)lpTempDIBBits + LineBytes * (Height - 1 - LONG(y)) + LONG(x));//左下角点的像素值
rd= *((char *)lpTempDIBBits + LineBytes * (Height - 1 - LONG(y)) + LONG(x) +1);// 右下角点的像素值
lu= *((char *)lpTempDIBBits + LineBytes * (Height - 1 - LONG(y) - 1) +LONG(x));// 左上角点的像素值
ru= *((char *)lpTempDIBBits + LineBytes * (Height - 1 - LONG(y) - 1) + LONG(x) +1);// 右上角点的像素值
pix= (1 - m) * (1 - n) * ld + (1 - m) * n * lu + m * n * ru + m * (1 - n) *//双线性插值,得到变换后的像素
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *((unsigned char*)lpDst) =//将像素值赋给目的图片
&&&&&&&&&&&&&&&&&&&&&&&&&&& }
&&&&&& &&&&&&&&&&&&& }
&&&&&&&&&&&&& }
4.细化处理
对图像的喜欢过程实际是求图像骨架的过程。骨架是二维二值目标的重要描述,它指图像中央的骨骼部分,是描述图像几何及拓扑性质的重要特征之一。细化算法有很多。按照迭代方法,分为两类,一类是非迭代过程,一类是迭代过程。非迭代算法有基于距离变换的方法等。迭代方法是通过重复删除像素边缘,直到得到单独像素宽度的图像为止。现在用的比较多的细化算法有Hilditch、Pavlidis、Rosenfeld细化算法和索引表细化算法等[13]。下面主要介绍这四种算法。
Hilditch、Pavlidis、Rosenfeld细化算法:这类算法则是在程序中直接运算,根据运算结果来判定是否可以删除点的算法,差别在于不同算法的判定条件不同。
其中Hilditch算法比较适用于二值图像,是用的比较普遍的细化算法,在本文中我用了该算法后发现会有马赛克效果,所以本文中没有引用该算法; Pavlidis算法用位运算进行特定模式的匹配,所得的骨架是8连接的,使用于0-1二值图像 ;Rosenfeld算法是一种并行细化方法,所得的骨架形态是8-连接的,使用于0-1二值图像 。 后两种算法的效果要更好一些,但是处理某些图像时效果一般,第一种算法适用性强一些[13]。
索引表细化算法:经过预处理后得到待细化的图像是0、1二值图像。像素值为1的是需要细化的部分,像素值为0的是背景区域。基于索引表的算法就是依据一定的判断依据,产生一个表,然后根据要细化的点的八个邻域的情况进行匹配,若表中元素是1,若表中元素是1,则删除该点(改为背景),若是0则保留。因为一个像素的8个邻域共有256种可能情况,因此,索引表的大小一般为256种。
车牌图像进行预处理后,细化处理是关系到后面能否正确提取字符特征值的关键,所以本文中在比较了几种细化方法后,使用Rosenfeld骨架细化的方法,细化处理后可以得到图像中字符的基本骨架,不会破坏原来的连通性。
Rosenfeld细化过程主要是保持原来图像的连通性
&&& 通过归一化 后,再将图像进行细化,基本保存了字符特征的骨架特征。所以后面就是要进行的字符特征提取操作。Rosenfeld效果如下所示:
& & & & & & & & & & &
&&& 4-19大小归一化后再细化的图像
5.字符特征提取
&&&&字符特征提取的好坏,直接影响字符识别的结果。字符特征提取是一个字符识别过程必不可少的过程。目前,字符特征提取的方法很多,比如:基于网格像素统计方法[5],基于笔画,轮廓,骨架特征等。我之前做了基于网格像素统计的方法,通过实验,发现识别能力比较差,不能达到预想的结果。
&&&&&& 针对上面的结果,我参考何兆成等人的方法,在字符细化后的基础上,通过统计字符笔画斜率特征,字符侧面深度等特征作为字符提取的特征,得到22个特征值。具体统计方法如下:
(1)基于笔画斜率的累计特征提取
&&&& 字符最具代表性的特征是笔画,不同的字符有不同的笔画数量,形态,长度等,所以可将笔画的斜率累计值作为特征进行特征值提取。笔画斜率有正斜率,负斜率,零斜率三部分,分别统计字符零斜率,正斜率,负斜率的累加和。斜率的统计过程,例如从字符左边扫描,当前的扫描点为 ,下一个扫描点为为 。斜率K值计算如下:
通过上面的过程,从字符左侧开始计算斜率特征,可以得到3个特征。我这里从字符左右上下四个方向统计斜率特征可以得到12个特征值。
(2)拐点幅度累计特征提取
在字符中字符的拐点含有丰富的特征。所以统计拐点幅度特征累计和,可以得到4个特征值。拐点幅度特征 计算如下:
(3)字符轮廓深度特征提取
&不同的字符在轮廓上有着明显差异。比如“S”和“C”。如下图中的“S”字符,从右侧扫描深度的时候有着有很多的凹凸信息。而字符“C”从右侧扫描的过程中,字符的中间凹陷比较明显。所以通过扫描字符四个方向的轮廓深度,也能得到4个轮廓特征值。
&&&&&& (4)字符跳跃点统计
由于字符“1”和“B”从左侧扫描过程中基本上没有区别。所以,为了更准确些。我这里通过统计字符水平扫描跳跃点和垂直扫描字符跳跃点来区分。很明显,字符“1”和字符“B”水平和垂直方向的跳跃点有明显的差别。以上过程可以得到2个字符特征。
&&&&&& 通过以上分析总共可以得到22个字符特征值。将这些特征进行训练,即可得到所需的结果。关键代码如下(计算左边的特征值为例):
&&&&&& if(left[i]==-1)
&&&&&&&&&&&&& while(left[i] == -1) i++;
&&&&&& begin=i;i=Height-1;
&&&&&& if(left[i] == -1)
&&&&&&&&&&&&& while(left[i] == -1) i--;
&&&&&& end =
&&&&&& for(i=i&=i++)
&&&&&&&&&&&&& if(left[i] == -1)
&&&&&&&&&&&&&&&&&&&& left[i] = left[i+1];
&&&&&& //扫描深度
&&&&&& for(i=i&=i++)
&&&&&&&&&&&&& feature[4] += left[i];
&&&&&& feature[4]=feature[4]/10;
&&&&&& double *leftradio = new double[end-begin];
&&&&&& for(i=0;i&end-i++)
&&&&&&&&&&&&& leftradio[i]=0;
&&&&&& int n=0;
&&&&&& for(i=i&=(end-4);i++)
//如果斜率为零
&&&&&&&&&&&&& if(left[i] == left[i+4])
&&&&&&&&&&&&& {
&&&&&&&&&&&&&&&&&&&& feature[0]++;
&&&&&&&&&&&&&&&&&&&& leftradio[n]=0;
&&&&&&&&&&&&& }
&&&&&&&&&&&&& else
&&&&&&&&&&&&& {
&&&&&&&&&&&&&&&&&&&& leftradio[n] =(left[i]-left[i+4])/4.0;
&&&&&&&&&&&&&&&&&&&& if(leftradio[n] &0) //如果斜率小于0
&&&&&&&&&&&&&&&&&&&&&&&&&&& feature[1]++;
&&&&&&&&&&&&&&&&&&&& else&&&&&&& //斜率大于0
&&&&&&&&&&&&&&&&&&&&&&&&&&& feature[2]++;
&&&&&&&&&&&&& }
&&&&&&&&&&&&& n++;
&&&&&& for(i=1;i&n;i++)
&&&&&&&&&&&&& feature[3] +=fabs(leftradio[i]-leftradio[i-1]);
5.神经网络训练
通过提取的特征值,识别的算法有很多,包括分类器算法,模板匹配算法,基于概率统计的Bayes分类器算法,聚类分析算法等。我这里采用的是BP神经网络分类器算法。
将提取的特征值,输入层为22个特征,隐含层为80个特征,输出层为34个特征。这里去除字母“I”和“O”。字符0-9,24个字母一共34个输出。说明:由于有34个输出,所以这里理想情况下输出结果为33个0和一个1.只是1在第i个输出。i对应的数字编号如0则对应0,1对应1,9对应9,字符“A”对应10,字符“B”对应11,依次类推,字符“Z”对应33。
Matlab创建网络及训练的代码实现如下:
%创建BP网络
net_1=newff(minmax(p),[80,34],{'tansig','purelin'},'traingdm')
%&当前输入层权值和阈值
inputWeights=net_1.IW{1,1};
inputbias=net_1.b{1};
%&当前网络层权值和阈值
layerWeights=net_1.LW{2,1};
layerbias=net_1.b{2};
%&设置训练参数
net_1.trainParam.show = 50;
net_1.trainParam.lr = 0.01; %学习率
net_1.trainParam.mc = 0.9;
net_1.trainParam.epochs = 10000;%训练次数
net_1.trainParam.goal = 1e0; %目标误差
%&调用 TRAINGDM 算法训练 BP 网络
[net_1,tr]=train(net_1,p,q);
6.车牌图像识别结果测试
因为车牌中的汉字与字母数字的结构以及骨架不同,所以汉字的识别过程需要另外再做处理,所以本文处理的是车牌除汉字外的车牌图像识别过程。通过最终的测试实验结果,数字的识别结果正确率比较高,字符的识别正确率比较低一点(由于训练用的英文字符比较少)。
& & & & & & & & & & & & & & & &识别结果
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:160112次
积分:1602
积分:1602
排名:千里之外
原创:35篇
评论:87条
阅读:3370
(1)(7)(3)(1)(1)(1)(1)(1)(3)(1)(3)(1)(4)(2)(1)(9)(1)

我要回帖

更多关于 车牌号识别能破解吗 的文章

 

随机推荐