数字图像处理实习报告OCR车牌号码识别.docx
- 文档编号:15460747
- 上传时间:2023-07-04
- 格式:DOCX
- 页数:37
- 大小:902.23KB
数字图像处理实习报告OCR车牌号码识别.docx
《数字图像处理实习报告OCR车牌号码识别.docx》由会员分享,可在线阅读,更多相关《数字图像处理实习报告OCR车牌号码识别.docx(37页珍藏版)》请在冰点文库上搜索。
数字图像处理实习报告OCR车牌号码识别
数字图像处理实习报告
实习项目名称:
OCR-车牌号码识别
所属课程名称:
数字图像处理
班级:
学号:
姓名:
指导教师:
一、实习目的
(1)掌握数字图像处理的相关知识及算法。
(2)学习在VC6.0环境下编写车牌定位与识别程序。
(3)了解车牌定位方法,如边缘检测法,基于矢量量化的车牌定位法等。
(4)了解车牌字符分割方法,如,投影法,基于车牌字符先验知识的字符分割方法等。
(5)了解车牌字符识别方法,如字符归一化,投影法,基于数字和字母特征的模板匹配法。
(6)运用编写的车牌定位与识别程序实现在各种环境下车牌的识别。
二、实习原理
基于VC++图像处理的汽车牌照识别系统主要包括车牌定位,字符车牌分割和车牌字符识别三个关键环节其识别流程图如图1所示。
图1识别流程图
其中,
(1)原始图像:
原始的汽车图像;
(2)图像预处理:
对采集到的图像进行滤波等处理以克服图像干扰;
(3)车牌定位:
计算边缘图像的投影面积,寻找峰谷点,大致确定车牌位置,再计算此连通域内的宽高比,剔除不在域值范围内的连通域,最后得到的便为车牌区域;
(4)字符分割:
利用投影检测的字符定位分割方法得到车牌的字符;
(5)字符数据库:
为第6步的字符识别建立字符模板数据库;
(6)字符识别:
通过基于模板匹配的人工神经网络算法,通过特征对比或训练识别出相关的字符,得到最后的汽车牌照,包括英文字母和数字。
三、实习步骤
请打开一个BMP格式的位图文件:
标示图象的坐标标示算子的坐标标识区域的地点
3.1完成车牌定位的整个过程
程序流程:
1.产生副本
2.水平差分提取边缘,寻找横向的车牌带状区域
3.垂直差分提取边缘,寻找纵向的车牌带状区域
4.利用先验知识标识车牌区域,进行车牌带状区域的选择,(横纵向)
5.构造出车牌矩形域;
6.再次利用利用跳变数选择车牌矩形区域,进行车牌区域的最终选择;
7.精确定位车牌,即削弱车牌横向宽度;
8.更新图象;
3.2水平差分提取图象边缘
程序流程:
1.逐行扫描,sub=|f(x,y)-f(x,y+1)|;
2.若差值小于20,则g(x,y)=0;
若差值大于30,则增强原图象,令g(x,y)=g(x,y)+30;
3.另最后一列全部为0,即黑色;
3.3完成图象车牌区域的初步定位。
程序流程:
1.利用间行扫描的方式找出跳变数最大的前10行;
2.对Top10行进行区域细粒度增长选择;
其相似度的选取为:
0.7~1.3倍的该行跳变总数;
3.二值化,threshold=255;
4.任意选择一列,最好不要边缘列,可能有干扰(本程序选择为第十列),搜索出各个带状候选域,存入标志;
3.4利用先验知识标识车牌区域,进行车牌区域的选择
函数说明:
特定应用条件,拍摄所得车牌的区域高度、宽度均有一定的范围,其大小可以分析图象后可得
根据统计得到:
车牌的顶部极少出现在高度小于100个像素的区域;
车牌高度也一般大于20个像素。
程序的最终结果为满足条件的经过扩展了的带状区域
程序流程:
1.舍弃区域顶部小于100的待选域
2.选择区域高度大于20的待选域
3.区域扩展,上下各增大5个像素。
若顶部小于5,则顶部坐标不变,高度加5;
若底部大于图象的底部,则底部坐标不变,高度加5;
3.5水平查找后,纵向查找。
完成图象车牌区域的初步定位。
程序流程:
1.利用间行扫描的方式找出跳变数最大的前30行;
2.对Top30行进行区域增长;
其相似度的选取为:
0.8~1.2倍的该行跳变总数;
3.二值化,threshold=255;
4.任意选择一列,(本程序选择为第十行),搜索出各个带状候选域,存入标志;
3.6利用先验知识标识车牌区域,进行车牌区域的选择,(横纵向)
函数说明:
国家标准:
车牌的宽高比近似为3:
1;
程序流程:
1.初始化存储数组
2.选择区域高宽比大于3的待选域
函数功能:
再次利用利用跳变数选择车牌区域,进行车牌区域的最终选择,(横纵向)
程序流程:
1.初始化存储数组
2.计算每个伪车牌区域的跳变数
3.选择具有最大跳变数的区域为车牌区
3.7计算伪车牌区的跳变平均数
程序流程:
1.初始化;
2.水平差分,边缘提取;
3.选择车牌的中间1/3行来计算每个伪车牌区域的跳变平均数;
3.8找出所有伪车牌区域中具有最大跳变平均数的区域号,精确定位车牌
程序说明:
选择排序,由于水平分割出的伪车牌区域已经比较准确,故仅作垂直方向的进一步定位(缩小宽度)
3.91找出车牌的左右边缘
程序流程:
1.水平差分,二值化;
2.垂直方向投影,统计各列的投影值;
3.去除噪声点;
4.找出左右边缘
5.计算车牌宽度
6.车牌精确定位赋值
3.92二值化图象
程序说明:
threshold=average+delt;
程序流程:
1.计算图象均值;
2.计算图象方差;
3.二值化
3.93车牌字符分割
程序流程:
1.区域扩展;
2.投影分割;
3.字符区域的获取;
3.94水平方向投影,分割出字符
程序流程;1.统计各列白象素个数;
2.平滑投影曲线;
3.寻找波谷(trough)进行分割;
四、实验程序
3.1车牌识别
///
///函数功能:
水平方向投影,分割出字符
///程序流程:
1.统计各列白象素个数;
///2.平滑投影曲线;
///3.寻找波谷(trough)进行分割;
//二值化算法,二值化为0和1两种值
voidCDipView:
:
BinaryImg(BYTE*DisposeImg,intwidth,intheight)
{
BYTE*temp=newBYTE[height*width];
intx,y;
CopyImg(DisposeImg,temp,width,height);
longdoubletotal=0;
floataver=0;
for(x=0;x { for(y=0;y { total+=DisposeImg[x*width+y]; } } aver=(BYTE)(total/(float)(height*width)); floatdelt; floatsub=0; for(x=0;x { for(y=0;y { sub+=(DisposeImg[x*width+y]-aver)*(DisposeImg[x*width+y]-aver); } } delt=(float)(sqrt(sub/(float)(height*width))); BYTEjudge; judge=(BYTE)(delt+aver); for(x=0;x { for(y=0;y { if(DisposeImg[(x*width)+y]>=judge) { DisposeImg[(x*width)+y]=(BYTE)1; } else { DisposeImg[(x*width)+y]=(BYTE)0; } } } free(temp); } //Hilditch细化算法 voidCDipView: : ThinnerHilditch(void*image,unsignedlonglx,unsignedlongly) { char*f,*g; charn[10]; unsignedintcounter; shortk,shori,xx,nrn; unsignedlongi,j; longkk,kk11,kk12,kk13,kk21,kk22,kk23,kk31,kk32,kk33,size; size=(long)lx*(long)ly; g=(char*)malloc(size); if(g==NULL) { printf("errorinallocatingmemory! \n"); return; } f=(char*)image; for(i=0;i { for(j=0;j { kk=i*ly+j; if(f[kk]! =0) { f[kk]=1; g[kk]=f[kk]; } } } counter=1; do { printf("%4d*",counter); counter++; shori=0; for(i=0;i { for(j=0;j { kk=i*ly+j; if(f[kk]<0) f[kk]=0; g[kk]=f[kk]; } } for(i=1;i { for(j=1;j { kk=i*ly+j; if(f[kk]! =1) continue; kk11=(i-1)*ly+j-1; kk12=kk11+1; kk13=kk12+1; kk21=i*ly+j-1; kk22=kk21+1; kk23=kk22+1; kk31=(i+1)*ly+j-1; kk32=kk31+1; kk33=kk32+1; if((g[kk12]&&g[kk21]&&g[kk23]&&g[kk32])! =0) continue; nrn=g[kk11]+g[kk12]+g[kk13]+g[kk21]+g[kk23]+ g[kk31]+g[kk32]+g[kk33]; if(nrn<=1) { f[kk22]=2; continue; } n[4]=f[kk11]; n[3]=f[kk12]; n[2]=f[kk13]; n[5]=f[kk21]; n[1]=f[kk23]; n[6]=f[kk31]; n[7]=f[kk32]; n[8]=f[kk33]; n[9]=n[1]; xx=0; for(k=1;k<8;k=k+2) { if((! n[k])&&(n[k+1]||n[k+2])) xx++; } if(xx! =1) { f[kk22]=2; continue; } if(f[kk12]==-1) { f[kk12]=0; n[3]=0; xx=0; for(k=1;k<8;k=k+2) { if((! n[k])&&(n[k+1]||n[k+2])) xx++; } if(xx! =1) { f[kk12]=-1; continue; } f[kk12]=-1; n[3]=-1; } if(f[kk21]! =-1) { f[kk22]=-1; shori=1; continue; } f[kk21]=0; n[5]=0; xx=0; for(k=1;k<8;k=k+2) { if((! n[k])&&(n[k+1]||n[k+2])) { xx++; } } if(xx==1) { f[kk21]=-1; f[kk22]=-1; shori=1; } else f[kk21]=-1; } } }while(shori); free(g); } //细化算法 voidCDipView: : ThinImage(BYTE*image,intwidth,intheight) { LONGx,y,k; BYTEimage1[10000]; k=0; LONGdigitWidth=width; LONGdigitHeight=height; for(x=0;x { image[x*width+0]=(BYTE)0; image[x*width+digitHeight-1]=(BYTE)0; } for(y=0;y { image[0*width+y]=(BYTE)0; image[(digitWidth-1)*width+y]=(BYTE)0; } for(x=0;x { for(y=0;y { image1[k]=image[x*width+y]; if(image1[k]! =0) image1[k]=(BYTE)1; k++; } } ThinnerHilditch((void*)image1,digitWidth,digitHeight); k=0; for(x=0;x { for(y=0;y { image[x*width+y]=image1[k]; if(image[x*width+y]! =0) image[x*width+y]=(BYTE)1; k++; } } } //获取特征值的函数 voidCDipView: : GetFeature(BYTE*image,longwidth,longheight,double*feature,intsize) { inti,j; for(i=0;i<13;i++) feature[i]=0; //图象是20×36大小的,分成9块 //第一块 for(i=0;i<7;i++) { for(j=0;j<12;j++) { if(image[i*width+j]==1) feature[0]+=1.0; } } //第二块 for(i=0;i<7;i++) { for(j=12;j<24;j++) { if(image[i*width+j]==1) feature[1]+=1.0; } } //第三块 for(i=0;i<7;i++) { for(j=24;j<36;j++) { if(image[i*width+j]==1) feature[2]+=1.0; } } //第四块 for(i=7;i<13;i++) { for(j=0;j<12;j++) { if(image[i*width+j]==1) feature[3]+=1.0; } } //第五块 for(i=7;i<13;i++) { for(j=12;j<24;j++) { if(image[i*width+j]==1) feature[4]+=1.0; } } //第六块 for(i=7;i<13;i++) { for(j=24;j<36;j++) { if(image[i*width+j]==1) feature[5]+=1.0; } } //第七块 for(i=13;i<20;i++) { for(j=0;j<12;j++) { if(image[i*width+j]==1) feature[6]+=1.0; } } //第八块 for(i=13;i<20;i++) { for(j=12;j<24;j++) { if(image[i*width+j]==1) feature[7]+=1.0; } } //第九块 for(i=13;i<20;i++) { for(j=24;j<36;j++) { if(image[i*width+j]==1) feature[8]+=1.0; } } //下面统计方向交点特征 for(j=0;j<36;j++) { if(image[7*width+j]==1) feature[9]+=1.0; } for(j=0;j<36;j++) { if(image[13*width+j]==1) feature[10]+=1.0; } for(i=0;i<20;i++) { if(image[i*width+12]==1) feature[11]+=1.0; } for(i=0;i<20;i++) { if(image[i*width+24]==1) feature[12]+=1.0; } } //识别函数,第一个参数为LoadCharLib读出的数组, //第二个参数为LoadCharLib的返回值(即样本个数), //将上面获得的特征值传入第三个参数,返回为识别结果 CStringCDipView: : Recognize(sample*sa,intnum,double*feature) { intj; doublemin=100000.0; CStringResult; for(inti=0;i { doublediff=0.0; for(j=0;j<9;j++) { diff+=fabs(feature[j]-sa[num].feature[j]); } for(j=9;j<13;j++) { diff+=fabs(feature[j]-sa[num].feature[j])*9; } if(diff { min=diff; Result.Format("%s",sa[num].trueClass); } } returnResult; }*/ //字符识别 /*voidCDipView: : GetCharacter() { //CDipDoc*pDoc=GetDocument(); //intwidth,height; //width=pDoc->ImgWidth; //height=pDoc->ImgHeight; //samplemysa[500]; //doublemyfeature[13]; //intnum; //CStringresult[10]; //BYTE*Img; //introw=0; //intcol=0; //intx=-1; //inty=-1; //intw=0; //inth=0; //intarea=0; //for(area=0;area<10;area++); //{ //if(cRects[area].w>0) //{ //x=cRects[area].x; //y=cRects[area].y; //w=cRects[area].w; //h=cRects[area].h; //Img=newBYTE[w*h]; //for(row=0;row //{ //for(col=0;col //{ ////Img[row*w+col]=pDoc->ImgData[y*width+x]; //} //} //////num=LoadCharLib(mysa);//获取样本库保存到mysa[500]中 //////Zoom(Img,w,h);//对切割出的图象进行大小归一化 //////ThinImage(Img,w,h);//对大小归一化后的图象进行细化 //////GetFeature(Img,w,h,myfeature,13);//图象细化以后就可以提取特征了 //////result[area]=Recognize(mysa,num,myfeature); //} //} //delete[]mysa; //delete[]myfeature; //delete[]result; }*/ voidCDipView: : OnCharacterRecg() { CMainFrame*MainFrame=(CMainFrame*)this->GetParent()->GetParent(); CCharView*pchview=(CCharView*)MainFrame->m_wndSplitter.GetPane(0,1); CDigitClassdigitTest; CStringclassResult; CString
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数字图像 处理 实习 报告 OCR 车牌 号码 识别