找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 9950|回复: 8
打印 上一主题 下一主题
收起左侧

车牌识别matlab 源码+字符模板

  [复制链接]
跳转到指定楼层
楼主
这是我们去年设计自己做的,主要是matlab源码和自制的字符模板!目前还有很多缺陷 求指正

资料下载:
chepaishibie.zip (229.89 KB, 下载次数: 350)

程序源码

  1. function [d]=main(jpg)
  2. close all
  3. clc
  4. I=imread('car1.jpg');
  5. figure(1),imshow(I);title('原图')
  6. I1=rgb2gray(I);
  7. figure(2),subplot(1,2,1),imshow(I1);title('灰度图');
  8. figure(2),subplot(1,2,2),imhist(I1);title('灰度图直方图');
  9. I2=edge(I1,'roberts',0.15,'both');
  10. figure(3),imshow(I2);title('robert算子边缘检测')
  11. se=[1;1;1];
  12. I3=imerode(I2,se);
  13. figure(4),imshow(I3);title('腐蚀后图像');
  14. se=strel('rectangle',[25,25]);
  15. I4=imclose(I3,se);
  16. figure(5),imshow(I4);title('平滑图像的轮廓');
  17. I5=bwareaopen(I4,2000);
  18. figure(6),imshow(I5);title('从对象中移除小对象');
  19. [y,x,z]=size(I5);
  20. myI=double(I5);
  21. tic
  22. Blue_y=zeros(y,1);
  23. for i=1:y
  24.     for j=1:x
  25.              if(myI(i,j,1)==1)
  26.   
  27.                 Blue_y(i,1)= Blue_y(i,1)+1;%蓝色像素点统计
  28.             end  
  29.      end      
  30. end
  31. [temp MaxY]=max(Blue_y);%Y方向车牌区域确定
  32. PY1=MaxY;
  33. while ((Blue_y(PY1,1)>=5)&&(PY1>1))
  34.         PY1=PY1-1;
  35. end   
  36. PY2=MaxY;
  37. while ((Blue_y(PY2,1)>=5)&&(PY2<y))
  38.         PY2=PY2+1;
  39. end
  40. IY=I(PY1:PY2,:,:);
  41. %%%%%% X方向 %%%%%%%%%
  42. Blue_x=zeros(1,x);%进一步确定x方向的车牌区域
  43. for j=1:x
  44.      for i=PY1:PY2
  45.             if(myI(i,j,1)==1)
  46.                 Blue_x(1,j)= Blue_x(1,j)+1;               
  47.             end  
  48.      end      
  49. end
  50.   
  51. PX1=1;
  52. while ((Blue_x(1,PX1)<3)&&(PX1<x))
  53.        PX1=PX1+1;
  54. end   
  55. PX2=x;
  56. while ((Blue_x(1,PX2)<3)&&(PX2>PX1))
  57.         PX2=PX2-1;
  58. end
  59. PX1=PX1-1;%对车牌区域的校正
  60. PX2=PX2+1;
  61.   dw=I(PY1:PY2-8,PX1:PX2,:);
  62. t=toc;
  63. figure(7),subplot(1,2,1),imshow(IY),title('行方向合理区域');
  64. figure(7),subplot(1,2,2),imshow(dw),title('定位剪切后的彩色车牌图像')
  65. imwrite(dw,'dw.jpg');
  66. [filename,filepath]=uigetfile('dw.jpg','输入一个定位裁剪后的车牌图像');
  67. jpg=strcat(filepath,filename);
  68. a=imread('dw.jpg');
  69. b=rgb2gray(a);
  70. imwrite(b,'1.车牌灰度图像.jpg');
  71. figure(8);subplot(3,2,1),imshow(b),title('1.车牌灰度图像')
  72. g_max=double(max(max(b)));
  73. g_min=double(min(min(b)));
  74. T=round(g_max-(g_max-g_min)/3); % T 为二值化的阈值
  75. [m,n]=size(b);
  76. d=(double(b)>=T);  % d:二值图像
  77. imwrite(d,'2.车牌二值图像.jpg');
  78. figure(8);subplot(3,2,2),imshow(d),title('2.车牌二值图像')
  79. figure(8),subplot(3,2,3),imshow(d),title('3.均值滤波前')

  80. % 滤波
  81. h=fspecial('average',3);
  82. d=im2bw(round(filter2(h,d)));
  83. imwrite(d,'4.均值滤波后.jpg');
  84. figure(8),subplot(3,2,4),imshow(d),title('4.均值滤波后')

  85. % 某些图像进行操作
  86. % 膨胀或腐蚀
  87. % se=strel('square',3);  % 使用一个3X3的正方形结果元素对象对创建的图像进行膨胀
  88. % 'line'/'diamond'/'ball'...
  89. se=eye(2); % eye(n) returns the n-by-n identity matrix 单位矩阵
  90. [m,n]=size(d);
  91. if bwarea(d)/m/n>=0.365
  92.     d=imerode(d,se);
  93. elseif bwarea(d)/m/n<=0.235
  94.     d=imdilate(d,se);
  95. end
  96. imwrite(d,'5.膨胀或腐蚀处理后.jpg');
  97. figure(8),subplot(3,2,5),imshow(d),title('5.膨胀或腐蚀处理后')

  98. % 寻找连续有文字的块,若长度大于某阈值,则认为该块有两个字符组成,需要分割
  99. d=qiege(d);
  100. [m,n]=size(d);
  101. figure,subplot(2,1,1),imshow(d),title(n)
  102. k1=1;k2=1;s=sum(d);j=1;
  103. while j~=n
  104.     while s(j)==0
  105.         j=j+1;
  106.     end
  107.     k1=j;
  108.     while s(j)~=0 && j<=n-1
  109.         j=j+1;
  110.     end
  111.     k2=j-1;
  112.     if k2-k1>=round(n/6.5)
  113.         [val,num]=min(sum(d(:,[k1+5:k2-5])));
  114.         d(:,k1+num+5)=0;  % 分割
  115.     end
  116. end
  117. % 再切割
  118. d=qiege(d);
  119. % 切割出 7 个字符
  120. y1=10;y2=0.25;flag=0;word1=[];
  121. while flag==0
  122.     [m,n]=size(d);
  123.     left=1;wide=0;
  124.     while sum(d(:,wide+1))~=0
  125.         wide=wide+1;
  126.     end
  127.     if wide<y1   % 认为是左侧干扰
  128.         d(:,[1:wide])=0;
  129.         d=qiege(d);
  130.     else
  131.         temp=qiege(imcrop(d,[1 1 wide m]));
  132.         [m,n]=size(temp);
  133.         all=sum(sum(temp));
  134.         two_thirds=sum(sum(temp([round(m/3):2*round(m/3)],:)));
  135.         if two_thirds/all>y2
  136.             flag=1;word1=temp;   % WORD 1
  137.         end
  138.         d(:,[1:wide])=0;d=qiege(d);
  139.     end
  140. end
  141. % 分割出第二个字符
  142. [word2,d]=getword(d);
  143. % 分割出第三个字符
  144. [word3,d]=getword(d);
  145. % 分割出第四个字符
  146. [word4,d]=getword(d);
  147. % 分割出第五个字符
  148. [word5,d]=getword(d);
  149. % 分割出第六个字符
  150. [word6,d]=getword(d);
  151. % 分割出第七个字符
  152. [word7,d]=getword(d);
  153. subplot(5,7,1),imshow(word1),title('1');
  154. subplot(5,7,2),imshow(word2),title('2');
  155. subplot(5,7,3),imshow(word3),title('3');
  156. subplot(5,7,4),imshow(word4),title('4');
  157. subplot(5,7,5),imshow(word5),title('5');
  158. subplot(5,7,6),imshow(word6),title('6');
  159. subplot(5,7,7),imshow(word7),title('7');
  160. [m,n]=size(word1);

  161. % 商用系统程序中归一化大小为 40*20,此处演示
  162. word1=imresize(word1,[40 20]);
  163. word2=imresize(word2,[40 20]);
  164. word3=imresize(word3,[40 20]);
  165. word4=imresize(word4,[40 20]);
  166. word5=imresize(word5,[40 20]);
  167. word6=imresize(word6,[40 20]);
  168. word7=imresize(word7,[40 20]);

  169. subplot(5,7,15),imshow(word1),title('1');
  170. subplot(5,7,16),imshow(word2),title('2');
  171. subplot(5,7,17),imshow(word3),title('3');
  172. subplot(5,7,18),imshow(word4),title('4');
  173. subplot(5,7,19),imshow(word5),title('5');
  174. subplot(5,7,20),imshow(word6),title('6');
  175. subplot(5,7,21),imshow(word7),title('7');
  176. imwrite(word1,'1.jpg');
  177. imwrite(word2,'2.jpg');
  178. imwrite(word3,'3.jpg');
  179. imwrite(word4,'4.jpg');
  180. imwrite(word5,'5.jpg');
  181. imwrite(word6,'6.jpg');
  182. imwrite(word7,'7.jpg');
  183. liccode=char(['0':'9' 'A':'Z' '苏豫陕鲁京辽浙']);  %建立自动识别字符代码表  
  184. SubBw2=zeros(40,20);
  185. l=1;
  186. for I=1:7
  187.       ii=int2str(I);
  188.      t=imread([ii,'.jpg']);
  189.       SegBw2=imresize(t,[40 20],'nearest');
  190.         if l==1                 %第一位汉字识别
  191.             kmin=37;
  192.             kmax=43;
  193.         elseif l==2             %第二位 A~Z 字母识别
  194.             kmin=11;
  195.             kmax=36;
  196.         else l>=3               %第三位以后是字母或数字识别
  197.             kmin=1;
  198.             kmax=36;
  199.         
  200.         end
  201.         
  202.         for k2=kmin:kmax
  203.             fname=strcat('F:\edge 下载\车牌识别3 第二版\车牌识别\程序与图像\字符模板\',liccode(k2),'.jpg');
  204.             SamBw2 = imread(fname);
  205.             for  i=1:40
  206.                 for j=1:20
  207.                     SubBw2(i,j)=SegBw2(i,j)-SamBw2(i,j);
  208.                 end
  209.             end
  210.            % 以上相当于两幅图相减得到第三幅图
  211.             Dmax=0;
  212.             for k1=1:40
  213.                 for l1=1:20
  214.                     if  ( SubBw2(k1,l1) > 0 | SubBw2(k1,l1) <0 )
  215.                         Dmax=Dmax+1;
  216.                     end
  217.                 end
  218.             end
  219.             Error(k2)=Dmax;
  220.         end
  221.         Error1=Error(kmin:kmax);
  222.         MinError=min(Error1);
  223.         findc=find(Error1==MinError);
  224.         Code(l*2-1)=liccode(findc(1)+kmin-1);
  225.         Code(l*2)=' ';
  226.         l=l+1;
  227. end
  228. figure(10),imshow(dw),title (['车牌号码:', Code],'Color','b');

  229. function [word,result]=getword(d)
  230. word=[];flag=0;y1=8;y2=0.5;
  231.     while flag==0
  232.         [m,n]=size(d);
  233.         wide=0;
  234.         while sum(d(:,wide+1))~=0 && wide<=n-2
  235.             wide=wide+1;
  236.         end
  237.         temp=qiege(imcrop(d,[1 1 wide m]));
  238.         [m1,n1]=size(temp);
  239.         if wide<y1 && n1/m1>y2
  240.             d(:,[1:wide])=0;
  241.             if sum(sum(d))~=0
  242.                 d=qiege(d);  % 切割出最小范围
  243.             else word=[];flag=1;
  244.             end
  245.         else
  246.             word=qiege(imcrop(d,[1 1 wide m]));
  247.             d(:,[1:wide])=0;
  248.             if sum(sum(d))~=0;
  249.                 d=qiege(d);flag=1;
  250.             else d=[];
  251.             end
  252.         end
  253.     end
  254. %end
  255.           result=d;
  256.          
  257.          
  258.           function e=qiege(d)
  259. [m,n]=size(d);
  260. top=1;bottom=m;left=1;right=n;   % init
  261. while sum(d(top,:))==0 && top<=m
  262.     top=top+1;
  263. end
  264. while sum(d(bottom,:))==0 && bottom>=1
  265.     bottom=bottom-1;
  266. end
  267. while sum(d(:,left))==0 && left<=n
  268.     left=left+1;
  269. end
  270. while sum(d(:,right))==0 && right>=1
  271.     right=right-1;
  272. end
  273. dd=right-left;
  274. hh=bottom-top;
  275. e=imcrop(d,[left top dd hh]);
复制代码


评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏6 分享淘帖 顶2 踩
回复

使用道具 举报

沙发
ID:57657 发表于 2016-10-17 15:32 | 只看该作者
车牌后面带字的能否被识别?比如教练车以及大型货车之类的。
回复

使用道具 举报

板凳
ID:430187 发表于 2018-11-23 15:34 | 只看该作者
你好,我参考了您车牌识别的程序,但是我换了图片,识别之后还是和您的识别结果一样,没有根据图片的实际内容识别出来,是怎么回事?
回复

使用道具 举报

地板
ID:470595 发表于 2019-4-15 14:28 | 只看该作者
Nora红豆抹茶 发表于 2018-11-23 15:34
你好,我参考了您车牌识别的程序,但是我换了图片,识别之后还是和您的识别结果一样,没有根据图片的实际内 ...

您好,我也遇到和您一样的问题    请问您的问题决解了吗   能否解答一下这个问题
回复

使用道具 举报

5#
ID:461935 发表于 2019-6-22 16:30 | 只看该作者
有车牌图吗
回复

使用道具 举报

6#
ID:436824 发表于 2020-1-3 21:34 | 只看该作者
数字无法识别,现实的都是M,该怎么解决
回复

使用道具 举报

7#
ID:917230 发表于 2021-6-22 19:05 来自手机 | 只看该作者
车牌第一个字为左右结构识别分开了怎么办,就像渝它分成了氵和俞有时候就只有俞
回复

使用道具 举报

8#
ID:1012605 发表于 2022-3-23 22:15 | 只看该作者
跟网上的很多人做的一模一样,,,
回复

使用道具 举报

9#
ID:1025848 发表于 2022-5-11 23:00 | 只看该作者
字符模板不存在怎么弄啊
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表