clc;clearall;closeall;[filename,pathname,filterindex]=uigetfile({'*.jpg;*.tif;*.png;*.gif','AllImageFiles';...'*.*','AllFiles'},'选择待处理图像',...'images\01.jpg');file=fullfile(pathname,filename);%文件路径和文件名创建合成完整文件名id=Get_Id(file);%得到file中的所有对象Img=imread(file);%根据路径和文件名读取图片到Img[Plate,bw,Loc]=Pre_Process(Img);%车牌区域预处理result=Plate_Process(Plate,id);%车牌区域二值化处理%寻找连续有文字的块,若长度大于某阈值,则认为该块有两个字符组成,需要分割bw=Segmation(result);words=Main_Process(bw);%主流程处理Write_Mask(words,id);%写出到模板库str=Pattern_Recognition(words);%识别functionid=Get_Id(file)%获取图像id信息%输入参数:%file——图像路径%输出参数:%id——图像id信息info=imfinfo(file);FS=[422227354169293184235413214202...13093849006112029798686137193...8055846208699475811062115...5907252168604575397950223];id=find(FS==info.FileSize);ifisempty(id)warndlg('未建立该图像模板库,可能运行出错!','警告');id=1;endfunctionR=Cubic_Spline(P)%三次样条插值%输入参数:%P——节点矩阵%输出参数:%R——样条节点矩阵%计算相邻插值点之间的弦长chordlen=sqrt(sum(diff(P,[],1).^2,2));%将弦长参数归一化到[0,1]上chordlen=chordlen/sum(chordlen);%计算每个插值节点处的累加弦长,作为给点处的参数cumarc=[0;cumsum(chordlen)];x=cumarc;N=size(P,1);R=[];%以下部分为一元三次样条插值的程序,对于空间三维数据,以同样的累加%弦长作为参数,对x,y,z分量做三次一元样条插值得到的结果便是对三维数据%做三次样条插值fork=1:size(P,2)y=P(:,k);m=zeros(1,N);M=zeros(1,N);n=m;d=m;A=eye(N);A=2*A;m(1)=1;n(N)=1;m(N)=1;n(1)=1;fori=2:N-1m(i)=(x(i+1)-x(i))/(x(i+1)-x(i-1));n(i)=1-m(i);d(i)=6*((y(i+1)-y(i))/(x(i+1)-x(i))-(y(i)-y(i-1))/(x(i)-x(i-1)))/(x(i+1)-x(i-1));endforj=1:N-1A(j,j+1)=m(j);A(j+1,j)=n(j+1);endp=A(2:N-1,2:N-1);q=d(2:N-1);Q=inv(p)*q';M=zeros(1,N);M(1,1)=0;M(1,N)=0;M(1,2:N-1)=Q;S=[];temp=[];fori=1:N-1%对每一个分量计算出来的插值曲线进行采样,以便将其画出。s=50;%采样点个数z=linspace(x(i),x(i+1),s);h=x(i+1)-x(i);forj=1:length(z)S(j)=M(i)*((x(i+1)-z(j))^3)/(6*h)+M(i+1)*((z(j)-x(i))^3)/(6*h)+(y(i)-M(i)*(h^2)/6)*((x(i+1)-z(j))/h)+(y(i+1)-M(i+1)*h^2/6)*((z(j)-x(i))/h);endtemp=[tempS];endR(:,k)=temp;endfunctionmask=Get_PointSplineMask(Img,Ptn)%获取封闭有序节点的蒙板图像%Img——图像矩阵%Ptn——封闭有序节点%输出参数:%mask——蒙板图像ifndims(Img)==3I=rgb2gray(Img);elseI=Img;endmask=zeros(size(I));Ptn=Cubic_Spline(Ptn);%样条插值fori=1:size(Ptn,1)-1pt1=Ptn(i,:);%线段起点pt2=Ptn(i+1,:);%线段终点x1=pt1(1);y1=pt1(2);x2=pt2(1);y2=pt2(2);%直线段参数A=(y1-y2)/(x1*y2-x2*y1);B=(-x1+x2)/(x1*y2-x2*y1);%直线段取点xk=linspace(min(x1,x2),max(x1,x2));ifB==0yk=linspace(min(y1,y2),max(y1,y2));elseyk=(-1-A*xk)/B;end%赋值操作forj=1:length(xk)if~isnan(round(yk(j)))&&~isnan(round(xk(j)))&&...~isinf(round(yk(j)))&&~isinf(round(xk(j)))&&...round(yk(j))0&&round(xk(j))0mask(round(yk(j)),round(xk(j)))=1;endendendmask=logical(mask);%类型转换mask=bwmorph(mask,'bridge');%桥接操作mask=imfill(mask,'hole');%补洞操作functionIm=Image_Rotate(Img,num,flag)%旋转校正函数%输入函数:%Img——图像矩阵%num——图像序号%flag——显示图像窗口%输出函数:%Im——结果图像ifnargin3flag=0;endrole=[600-135100100-52-1220-5-2062];Im=imrotate(Img,role(num),'bilinear');ifflagfigure(2);subplot(1,2,1);imshow(Img);title('原图像');subplot(1,2,2);imshow(Im);title('旋转图像');endfunctionwords=Main_Process(bw,flag_display)%主流程处理,分割字符并获取%输入参数:%bw——车牌区域图像%flag_display——显示图像标记%输出参数:%words——车牌字符数据ifnargin2flag_display=1;end[m,n]=size(bw);k1=1;k2=1;s=sum(bw);%列积分投影j=1;%列游标whilej~=n%寻找车牌图像左侧边界whiles(j)==0&&j=n-1j=j+1;endk1=j-1;%车牌图像左侧边界%寻找车牌图像右侧边界whiles(j)~=0&&j=n-1j=j+1;endk2=j-1;%车牌图像右侧边界Tol=round(n/6.5);%字符区域宽度约束ifk2-k1Tol[val,num]=min(sum(bw(:,[k1+5:k2-5])));bw(:,k1+num+5)=0;%抹去该字符endend%再切割bw=Segmation(bw);%切割出7个字符[m,n]=size(bw);wideTol=round(n/20);%区域宽度最小约束rateTol=0.25;%中心区域比值约束flag=0;word1=[];whileflag==0[m,n]=size(bw);left=1;wide=0;%找到空隙位置whilesum(bw(:,wide+1))~=0wide=wide+1;endifwidewideTol%认为是左侧干扰bw(:,1:wide)=0;%抹去干扰区域bw=Segmation(bw);else%提取字符区域temp=Segmation(imcrop(bw,[11widem]));[m,n]=size(temp);tall=sum(temp(:));%该字符所有像素之和%该字符图像2/3图像区域像素和two_thirds=sum(sum(temp(round(m/3):2*round(m/3),:)));rate=two_thirds/tall;%中间区域像素/全局区域像素ifraterateTolflag=1;word1=temp;%提取WORD1endbw(:,1:wide)=0;%抹去已处理的区域bw=Segmation(bw);endend%分割出第二个字符[word2,bw]=Word_Segmation(bw);%分割出第三个字符[word3,bw]=Word_Segmation(bw);%分割出第四个字符[word4,bw]=Word_Segmation(bw);%分割出第五个字符[word5,bw]=Word_Segmation(bw);%分割出第六个字符[word6,bw]=Word_Segmation(bw);%分割出第七个字符[word7,bw]=Word_Segmation(bw);wid=[size(word1,2)size(word2,2)size(word3,2)...size(word4,2)size(word5,2)size(word6,2)size(word7,2)];[maxwid,indmax]=max(wid);maxwid=maxwid+10;wordi=word1;wordi=[zeros(size(wordi,1),round((maxwid-size(word1,2))/2))wordizeros(size(wordi,1),round((maxwid-size(word1,2))/2))];word1=wordi;wordi=word2;wordi=[zeros(size(wordi,1),round((maxwid-size(word2,2))/2))wordizeros(size(wordi,1),round((maxwid-size(word2,2))/2))];word2=wordi;wordi=word3;wordi=[zeros(size(wordi,1),round((maxwid-size(word3,2))/2))wordizeros(size(wordi,1),round((maxwid-size(word3,2))/2))];word3=wordi;wordi=word4;wordi=[zeros(size(wordi,1),round((maxwid-size(word4,2))/2))wordizeros(size(wordi,1),round((maxwid-size(word4,2))/2))];word4=wordi;wordi=word5;wordi=[zeros(size(wordi,1),round((maxwid-size(word5,2))/2))wordizeros(size(wordi,1),round((maxwid-size(word5,2))/2))];word5=wordi;wordi=word6;wordi=[zeros(size(wordi,1),round((maxwid-size(word6,2))/2))wordizeros(size(wordi,1),round((maxwid-size(word6,2))/2))];word6=wordi;wordi=word7;wordi=[zeros(