三江学院2014届本科生毕业设计(论文)
计像素个数,然后进一步确定。在此过程中统计列非零像素并找出最大连续统计,这值是车牌左边界,区域右边界同理可得。然后使用OpenCV的功能函数在此区域设置感兴趣的块,最后截取出车牌区域。该方法可以通俗易懂的描述成拿一个大小设置好图框去框像素,图框中的像素在不断的变化,变化到最大值时保存在数组中,则此区域就是车牌的区域,如图4-3所示。
图4-3 车牌定位图
图4-3中字母L字符,圆点表示像素,黑色像素值是0,白色像素值是255。A、B、C 是矩形框,A 是刚开始的矩形框,B 和 C 用虚线表示,代表依次往下移动。图像中一行的投影值存放在数组 num_h[]里。
整个过程使用函数:int CMyDialog::PlateAreaSearch(IplPic *pImg_Image); 部分代码如下: k=temp_i;
While (((num_h[k +1]>POINT_X )||
(num_h[k+2]>POINT_X )||(num_h[k]>POINT_X )) && k )
k--;
plate_n=k+1;//下边界行 k=temp_i+10;
while(((num_h[k-1]>POINT_X )||
(num_h[k-2]>POINT_X )||(num_h[k]>POINT_X ))&& (k
k++; plate_s=k;
if ((ROI_rect.width+ROI_rect.x)> pImg_Image->width) {
ROI_rect.width=pImg_Image->width-ROI_rect.x;
//cout<<\垂直方向分割失败!\
12
三江学院2014届本科生毕业设计(论文)
MessageBox(\垂直方向分割失败!\Return 0 ; }
cvSetImageROI(src,ROI_rect);//将 ROI_rect 设置为感兴趣区域 cvCopy(src,pImg8uROI,NULL);//把感兴趣区域
pImg8uROI cvResetImageROI(src);//重新设置感兴趣区域 pImgResize=cvCreateImage(cvSize(40*HIGH_WITH_CAR,40),
IPL_DEPTH_8U,1);
cvResize(pImg8uROI,pImg8u11,CV_INTER_LINEAR); //车牌归一化 cvCvtColor(pImg8u11,pImgResize,CV_RGB2GRAY);//转为灰度图 Threshold(pImgResize,pImgResize);//二值化
车牌定位相比原车牌图像进一步精确了车牌区域,并从这个区域把车牌分割出来,为后面的识别做准备。
图4-4 车牌定位效果图
如图4-4所示为车牌定位效果图,实现车牌定位算法。
4.2 车牌图像分割及识别技术 4.2.1字符分割
字符分割的关键是在车牌字符的分割起始定位点,如果每个字符的起始定位点准确了,那么分割也就变得相当简单了。要识别已经定位到的车牌字符,首先要进行字符分割,得到单个字符,再进行字符识别。其基本方法是利用字符之间间隔的特点,进行垂直投影[25]。
首先对第二个字符末端进行初定位,然后再从定位的地方往前确定第一个和第二个字符位置,最后从第3个往后定位出后5个字符位置,
根据这样找到的位置来设置字符感兴趣的区域,利用OpenCV中的cvSetImageROI()函数,正如图4-5所示。
图4-5 字符垂直投影
13
三江学院2014届本科生毕业设计(论文)
整个过程使用函数:int CMyDialog::SegmentPlate(); 部分代码如下:
for (i=0;i<40*HIGH_WITH_CAR;i++) {
num_h[i]=0; //初始化指针 for (j=0;j<17;j++)//0-16/40 {
num_h[i]+=CV_PIC_SUBS(pImgResize,func,j,i)/45; }
for (j=24;j<40;j++)//24-39/40
{ num_h[i]+=CV_PIC_SUBS(pImgResize,func,j,i)/45;
}// 精定位
for(i=0;i<40*HIGH_WITH_CAR;i++)//每一列的 {
for(j=17;j<=24;j++)//17-24/40每一列的17到24行相加 {
num_h[i]+=CV_PIC_SUBS(pImgResize,func,j,i)/45;
}
}
for(j=letter[3];j>0;j--)//从第二个字符的末端开始 {
if ((num_h[j] letter [2]=j; letter[1]=(j>=23)?j-3:letter[1]; letter[0]=(j>=23)?j-23:letter[0]; //第一个字符的起始位置 break; } } 字符分割效果如图4-6所示: 图4-6 字符分割效果 最后确定好车牌字符的分割点,然后利用OpeCV函数中的cvSetImageROI()函数,分别把各个字符区域设置为感兴趣区域,然后把感兴趣区域保存下来,就 14 三江学院2014届本科生毕业设计(论文) 得到分割好的字符图片。 4.2.2字符识别 经过字符图像的分割之后,会得到七个已经保存好的单个字符的图像,使用模板匹配法[26],进行数字图像匹配。下面通过读取这些保存好的字符图像,通过匹配,判断输出字符结果,从而达到字符识别的目的。 车牌特征就是车牌一般大小即长宽比例固定并且每个字符之间的间隔一定,而第二个和第三个字符之间间隔稍大些,同时车牌里还包含汉字、数字和字母,第一个是汉字,第二个是字母,后面是字母和数字。 整个过程用到函数:int CMyDialog::CodeRecognize(IplPic*imgTest, int num, int char_num); (1)提取模板的特征值,然后放到数组中,通过以下算法提取前九个特征。 for(k=0; k<8; k++) { for(j=int(k/2)*10; j { for(i=(k%2)*10;i<(k%2+1)*10;i++) { num_t[k]+=CV_Pic_Subs(imgTest,func,j,i)/255; } } } num_t [ 8 ] + = num_t [K ];//第9个是前8个的和 之后的特征值提取也是固定的算法。 (2)对待处理的图片使用同样的提取算法,然后与数组中的值进行比较,如果差值在一定范围内则符合,同时把匹配次数相符最多的作为识别结果并保存。 输入原始车牌图片如图4-5所示: 图4-5 原始车牌图片 在定位、分割、识别以后的结果如图4-6所示: 图4-6 字符识别效果图 15 三江学院2014届本科生毕业设计(论文) 部分代码如下: for(k=char_start;k<=char_end;k++) { matchnum=0; for(i=0;i<8;i++)//区域的匹配 { if (abs(num_t[i]-Num_Templete[k][i])<=2)//与模板进行匹配 配 matchnum+=2; for(i=9;i { if (Num_Templete[k][i]>=5) { if(abs(num_t[i]-Num_Templete[k][i])<=1)matchnum+=2; } else if( num_t[i]==Num_Templete[k][i]) { matchnum+=2; } } if(matchnum>matchnum_max) { matchnum_max=matchnum;//保留最大的匹配 matchcode= k; } } } 通过调用void CMyDialog::OnShibiecar()函数7次来识别7个字符中的每一个字符,具体实现代码如下: void CMyDialog::OnShibiecar() { CodeRecognize(pImgCharOne,3,0); CodeRecognize(pImgCharTwo,1,1); CodeRecognize(pImgCharThree,2,2); 16 matchnum++; } if(Num_Templete[k][i]-abs(num_t[i])<=8)//对第9个特征进行匹 G_PlateChar[char_num]=PlateCode[matchcode]; //保存字符 百度搜索“77cn”或“免费范文网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,免费范文网,提供经典小说综合文库基于Opencv的车牌识别工具研究与实现(4)在线全文阅读。
相关推荐: