车牌识别字符识别源代码
车牌识别系统源代码
![车牌识别系统源代码](https://img.taocdn.com/s3/m/8e486323453610661ed9f47d.png)
num=0;
for j=1:b
if goal(i,j)==1
num=num+1;
end
end
if num<(b*0.1)
line_down=i;
break;
end
x(k)=uint8(x(k));
if x(k)>0 %当所选区域不为空时进行输出
11=11+1;% 用来记录输出的字符数
s(11)=char(x(k));
end
temp(32,32)=0;
imshow(temp);
end
now=now+2;
goalboundary=boundary;
s=min(goalboundary,[],1);
e=max(goalboundary,[],1);
goal=imcrop(Image,[s(2) s(1) e(2)- s(2) e(1)-s(1)]);
end
text(boundray(1,2)-35,boundray(1,1)+13,metric_string,'Color','g','FontSize',14,'FontWeight','bold');%显示匹配度字串
B6=imerode(B5,se);
[B,L]=bwboundaries(B6,4);%对边界图进行小区域联通,是车牌区域连通为一个方块
imshow(label2rgb(L,@jet,[.5 .5 .5]))%对连通区域进行标记
hold on
for k=1:length(B)
基于opencv的车牌识别的代码
![基于opencv的车牌识别的代码](https://img.taocdn.com/s3/m/3a21a44da517866fb84ae45c3b3567ec102ddc14.png)
基于opencv的车牌识别的代码车牌识别是计算机视觉领域的一个重要应用,它可以通过图像处理和模式识别技术,自动识别出车辆的车牌号码。
OpenCV是一个开源的计算机视觉库,提供了丰富的图像处理和机器学习算法,非常适合用于车牌识别的开发。
下面是一个基于OpenCV的车牌识别的代码示例:```pythonimport cv2import numpy as np# 加载车牌识别模型plate_cascade =cv2.CascadeClassifier('haarcascade_russian_plate_number.xml') # 加载车牌字符识别模型char_cascade =cv2.CascadeClassifier('haarcascade_russian_plate_number_char.xml') # 读取图像img = cv2.imread('car.jpg')# 转换为灰度图像gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# 检测车牌plates = plate_cascade.detectMultiScale(gray, 1.1, 4)# 遍历每个车牌for (x, y, w, h) in plates:# 绘制车牌区域cv2.rectangle(img, (x, y), (x+w, y+h), (255, 0, 0), 2)# 提取车牌区域plate = gray[y:y+h, x:x+w]# 检测车牌字符chars = char_cascade.detectMultiScale(plate, 1.1, 4)# 遍历每个字符for (cx, cy, cw, ch) in chars:# 绘制字符区域cv2.rectangle(img, (x+cx, y+cy), (x+cx+cw, y+cy+ch), (0, 255, 0), 2)# 提取字符区域char = plate[cy:cy+ch, cx:cx+cw]# 进行字符识别# ...# 在这里可以使用机器学习或深度学习算法对字符进行识别# 显示结果图像cv2.imshow('License Plate Recognition', img)cv2.waitKey(0)cv2.destroyAllWindows()```在这个代码示例中,首先我们加载了车牌识别模型和车牌字符识别模型。
【车牌识别】-车牌中字符分割代码详解
![【车牌识别】-车牌中字符分割代码详解](https://img.taocdn.com/s3/m/4a566fc97e192279168884868762caaedd33ba0c.png)
【车牌识别】-车牌中字符分割代码详解车牌识别项⽬中,关于字符分割的实现:思路: 1. 读取图⽚,使⽤ cv2 。
2. 将 BGR 图像转为灰度图,使⽤ cv2.cvtColor( img,cv2.COLOR_RGB2GRAY) 函数。
3. 车牌原图尺⼨(170, 722) ,使⽤阈值处理灰度图,将像素值⼤于175的像素点的像素设置为 255 ,不⼤于175的像素点的像素设置为0 。
4.观察车牌中字符,可以看到每个字符块中的每列像素值的和都不为 0 ,这⾥做了假设,将左右结构的省份简写的字也看作是由连续相邻的列组成的,如 “ 桂 ” 。
5. 对于经过阈值处理的车牌中的字符进⾏按列求像素值的和,如果⼀列像素值的和为 0,则表明该列不含有字符为空⽩区域。
反之,则该列属于字符中的⼀列。
判断直到⼜出现⼀列像素点的值的和为0,则这这两列中间的列构成⼀个字符,保存到字典character_dict 中,字典的 key 值为第⼏个字符 ( 下标从0开始 ),字典的value值为起始列的下标和终⽌列的下标。
character_dict 是字典,每⼀个元素中的value 是⼀个列表记录了夹住⼀个字符的起始列下标和终⽌列下标。
6. 之后再对字符进⾏填充,填充为170*170⼤⼩的灰度图(第三个字符为⼀个点,不需要处理,跳过即可。
有可能列数不⾜170,这影响不⼤)。
7. 对填充之后的字符进⾏resize,处理成20*20的灰度图,然后对字符分别进⾏存储。
代码实现:1### 对车牌图⽚进⾏处理,分割出车牌中的每⼀个字符并保存2# 在本地读取图⽚的时候,如果路径中包含中⽂,会导致读取失败。
34import cv25import paddle6import numpy as np7import matplotlib.pyplot as plt8#以下两⾏实现了在plt画图时,可以输出中⽂字符9 plt.rcParams['font.sans-serif']=['SimHei']10 plt.rcParams['axes.unicode_minus'] = False111213# cv2.imread() 读进来直接是BGR 格式数据,数值范围在 0~255 。
基于 OpenCV 和 Python 车牌识别系统的设计与实现代码大全
![基于 OpenCV 和 Python 车牌识别系统的设计与实现代码大全](https://img.taocdn.com/s3/m/95b10fe609a1284ac850ad02de80d4d8d15a01d9.png)
题目基于OpenCV和Python车牌识别系统的设计与实现1.1 题目的主要研究内容(1)工作的主要描述利用python中自带的opencv库中的模式识别算法制作一个简易的模式识别系统,使用自己搜集到的数据集对模型进行训练,最终完成特征提取、分类等工作,并且在最后的推理过程中,实现了车牌识别的工作。
(2)系统流程图1.2 题目研究的工作基础或实验条件项目的编程环境为python,编译器使用pycharm2021.3 x64,设计一个车牌识别系统,有GUI界面。
选择一张有车牌的图片后,完成车牌定位、倾斜校正、字符分割,最后通过k-NN 算法对车牌的字母和数字进行识别,将识别结果在GUI界面中显示出来1.3 数据集描述车牌定位就是在图片中识别出哪个位置有车牌,是字符分割和字母数字识别的前提,是车牌识别系统的关键和难点。
:例如,训练数据的目录结构树如下所示:1.4 特征提取过程描述1.对原始图像进行高斯模糊,减少噪点。
2.提取图像边缘。
首先将彩色图像转为灰度图gray,利用大核对灰度图进行开操作得到图像open,相当于对灰度图进行涂抹操作,将灰度图gray和开操作后的图像open按1:-1的比例融合得到图像add,以上操作可以将大面积灰度值相似的地方置黑,可以减少车灯、背景、地面、挡风玻璃等细节。
接着使用canny 算法对融合图像add提取边缘,得到图像canny。
3.使用横向长条作为核对边缘图像进行一次闭操作,得到图像close,相当于对边缘横向涂抹,因为一般视角车牌是宽大于高的矩形。
再对图像close进行一次开操作,得到图像open2,消除较细的线条和不大的竖向线条,从而将车牌位置的连通区域独立出来。
4.查找连通区域,通过最小外接矩形的宽高比2~5.5筛选合适的连通区域。
5.将最小外接矩形图像旋转矫正,上下左右向外扩展一点范围,避免连通区域没能覆盖车牌造成影响。
6.将连通区域原图转为HSV图像,确定图像的主要颜色,若不为蓝、黄、绿,则排除。
车牌识别模板匹配优质代码
![车牌识别模板匹配优质代码](https://img.taocdn.com/s3/m/e2e5773dccbff121dd368358.png)
close allclc[filename,filepath]=uigetfile('.jpg','输入一个需要识别的车牌图像');% 直接自动读入%file=strcat(filepath,filename); %strcat函数:连接字符串;把filepath的字符串与filename的连接,即路径/文件名I=imread(file);figure('name','原图'),imshow(I);title('原图')%图像增强% h=ones(5,5)/25; %过滤器h% I=imfilter(I,h);%真彩色增强% figure('name','真彩色增强');imshow(I);title('真彩色增强');I1=rgb2gray(I); % RGB图像转灰度图像% %figure('name','灰度处理前'),subplot(1,2,1),imshow(I1);title('灰度处理前的灰度图');% % subplot(1,2,2),imhist(I1);title('灰度处理前的灰度图直方图');%线性灰度变换I1=imadjust(I1,[0.3,0.7],[]);figure('name','灰度处理后'),subplot(1,2,1),imshow(I1);title('灰度处理后的灰度图');subplot(1,2,2),imhist(I1);title('灰度处理后的灰度图直方图');%进行中值滤波I1=medfilt2(I1);figure,imshow(I1);title('中值滤波');%边缘检测:sobel,roberts,canny,prewitt等I2=edge(I1,'roberts',0.25,'both'); %边缘检测算法,强度小于阈值0.15的边缘被省略掉,'both'两个方向检测(缺省默认)figure('name','边缘检测'),imshow(I2);title('robert算子边缘检测')se=[1;1;1];I3=imerode(I2,se);% 腐蚀Imerode(X,SE).其中X是待处理的图像,SE是结构元素对象figure('name','腐蚀后图像'),imshow(I3);title('腐蚀后的图像');se=strel('rectangle',[20,20]); % 25X25的矩形strel(膨胀、腐蚀、开运算、闭运算)是创建由指定形状shape对应的结构元素,se=strel('rectangle',20,20)%SE = strel('rectangle', MN)I4=imclose(I3,se);% 用25*25的矩形对图像进行闭运算(先膨胀后腐蚀)有平滑边界作用figure('name','平滑处理'),imshow(I4);title('平滑图像的轮廓');I5=bwareaopen(I4,1000);% 从二进制图像中移除所有少于2000像素的连接对象,消失的是连续的白色像素数量少于2000的字符figure('name','移除小对象'),imshow(I5);title('从对象中移除小对象');[y,x,z]=size(I5);% y是行数,x是列数,z是维数myI=double(I5);% 转成双精度型tic % 开始计时Blue_y=zeros(y,1);% zeros(M,N) 表示的是M行*N列的全0矩阵for i=1:yfor j=1:xif(myI(i,j,1)==1) %% 判断蓝色像素Blue_y(i,1)= Blue_y(i,1)+1;% 蓝色像素点统计endendend[temp MaxY]=max(Blue_y);% Y方向车牌区域确定[temp MaxY]临时变量MaxYPY1=MaxY; % 以下为找车牌Y方向最小值while ((Blue_y(PY1,1)>=5)&&(PY1>1))PY1=PY1-1;endPY2=MaxY; % 以下为找车牌Y方向最大值while ((Blue_y(PY2,1)>=5)&&(PY2<y))PY2=PY2+1;end% IY=I(PY1:PY2,:,:);%%%%%%%%%%%%%%%%% X方向%%%%%%%%%Blue_x=zeros(1,x);% 进一步确定x方向的车牌区域for j=1:xfor i=PY1:PY2 % 只需扫描的行if(myI(i,j,1)==1) %% 判断蓝色像素Blue_x(1,j)= Blue_x(1,j)+1; % 蓝色像素点统计endendendPX1=1;% 以下为找车牌X方向最小值while ((Blue_x(1,PX1)<5)&&(PX1<x))%% 为什么判断蓝色像素点<3(不算蓝色?)PX1=PX1+1;endPX2=x;% 以下为找车牌X方向最大值while ((Blue_x(1,PX2)<3)&&(PX2>PX1))PX2=PX2-1;endPY1=PY1-2;% 对车牌区域的校正为什么要这么+-PX1=PX1-2;PX2=PX2+3;PY2=PY2+10;dw=I(PY1:PY2-8,PX1:PX2,:);% 裁剪图像toc %t=toc; % 停止计时%figure(7),subplot(1,2,1),imshow(IY),title('行方向合理区域');figure('name','定位剪切后的彩色车牌图像'),%subplot(1,2,2),imshow(dw),title('定位剪切后的彩色车牌图像')imwrite(dw,'dw.jpg');a=imread('dw.jpg');b=rgb2gray(a);imwrite(b,'1.车牌灰度图像.jpg');figure('name','车牌处理');subplot(3,2,1),imshow(b),title('1.车牌灰度图像')%g_max=double(max(max(b)));% 以下作阈值化(灰度图转二值图)%线性灰度变换b=imadjust(b,[0.3,0.7],[]);subplot(3,2,2),imshow(b);title('2.线性灰度处理后的灰度图');%进行二值化处理d=im2bw(b,0.4);%将灰度图像进行二值化处理imwrite(d,'2.车牌二值图像.jpg');subplot(3,2,3),imshow(d),title('3.车牌二值图像');%显示二值化图像%进行中值滤波d=medfilt2(d);imwrite(d,'4.均值滤波后.jpg');subplot(3,2,4),imshow(d);title('4.中值滤波后');se=eye(2); % eye(n) 返回n乘n单一矩阵;单位矩阵[m,n]=size(d);if bwarea(d)/m/n>=0.365 % 函数bwarea 计算目标物的面积,单位是像素;bwarea/m/n即为单个像素??d=imerode(d,se);% 腐蚀elseif bwarea(d)/m/n<=0.235d=imdilate(d,se);% 膨胀endimopen(d,se);%se=eye(7);%imopen(d,se);imwrite(d,'5.膨胀或腐蚀处理后.jpg');subplot(3,2,5),imshow(d),title('5.膨胀或腐蚀处理后')%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%进行字符识别%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 寻找连续有文字的块,若长度大于某阈值,则认为该块有两个字符组成,需要分割d=qiege(d);% 调用qiege()子程序[m,n]=size(d);figure,subplot(2,1,1),imshow(d),title(n)k1=1;k2=1;j=1;s=sum(d);%sum(x)就是竖向相加,求每列的和,结果是行向量;sum(x,2)表示矩阵x的横向相加,求每行的和,结果是列向量。
车牌识别代码
![车牌识别代码](https://img.taocdn.com/s3/m/724df50552d380eb62946d3a.png)
车牌识别代码[fn,pn,fi]=uigetfile;%读入文件I=imread([pn fn]);figure,imshow(I);%显示原始图像title;Im1=rgb2gray(I);figure(2),subplot(1,2,1),imshow(Im1);title('灰度图');tic %计时开始[height,width]=size(Im1);%预处理I_edge=zeros(height,width);% 创建height*width的矩阵for i=1:width-1 % 对每一列开始遍历I_edge(:,i)=abs(I(:,i+1)-I(:,i));% 每列的值赋为原图像中左右两列相减的绝对值(即梯度) end% 归一化处理(0~255)I_edge=(255/(max(max(I_edge))-min(min(I_edge))))*(I_edge-min(min(I_edge)));figureimshow(I_edge);title('归一化处理')[I_edge,y1]=select(I_edge,height,width); %%%%%%调用select函数figureimshow(I_edge);title('选择')BW2 = I_edge;%%%%%%%%%%%%%%%%%一些形态学处理SE=strel('rectangle',[10,10]);IM2=imerode(BW2,SE);%腐蚀figureimshow(IM2);title('腐蚀');IM2=bwareaopen(IM2,20);%开运算,消除细小物体figureimshow(IM2);title('开运算');IM3=imdilate(IM2,SE);%膨胀figureimshow(IM2);title('膨胀'); %%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%投影以粗略估计车牌位置p_h=projection(double(IM3),'h'); %调用projection函数if(p_h(1)>0)p_h=[0,p_h];endp_v=projection(double(IM3),'v'); %调用projection函数if(p_v(1)>0)p_v=[0,p_v];end%%%%%%p_h=double((p_h>5));p_h=find(((p_h(1:end-1)-p_h(2:end))~=0));len_h=length(p_h)/2;%%%%%p_v=double((p_v>5));p_v=find(((p_v(1:end-1)-p_v(2:end))~=0));len_v=length(p_v)/2;%%%%%%%%%%%%%%%%%%%%%%%%%%%%粗略计算车牌候选区k=1;for i=1:len_hfor j=1:len_vs=IM3(p_h(2*i-1):p_h(2*i),p_v(2*j-1):p_v(2*j));if(mean(mean(s))>0.1)p{k}=[p_h(2*i-1),p_h(2*i)+1,p_v(2*j-1),p_v(2*j)+1];k=k+1;endendendk=k-1;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%进一步缩小车牌候选区for i=1:kedge_IM3=double(edge(double(IM3(p{i}(1):p{i}(2),p{i}(3):p{i}(4))),'canny'));[x,y]=find(edge_IM3==1);p{i}=[p{i}(1)+min(x),p{i}(2)-(p{i}(2)-p{i}(1)+1-max(x)),...p{i}(3)+min(y),p{i}(4)-(p{i}(4)-p{i}(3)+1-max(y))];p_center{i}=[fix((p{i}(1)+p{i}(2))/2),fix((p{i}(3)+p{i}(4))/2)];p_ratio(i)=(p{i}(4)-p{i}(3))/(p{i}(2)-p{i}(1));end%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%对上面参数和变量的说明:p为一胞元,用于存放每个图像块的左上和右下两个点的坐标;%存放格式为:p{k}=[x1,x2,y1,y2];x1,x2分别为行坐标,y1,y2为列坐标%p_center为一胞元,用于存放每个图像块的中心坐标,p_center{k}=[x,y];x,y分别为行,列坐标%p_ratio为一矩阵,用来存放图像块的长宽比例%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%合并临近区域%%%%%%%%如果有多个区域则执行合并if k>1n=0;ncount=zeros(1,k);for i=1:k-1%%%需要调整if条件中的比例%%%需要调整%检查是否满足合并条件if(abs(p{i}(1)+p{i}(2)-p{i+1}(1)-p{i+1}(2))<=height/30&&abs(p{i+1}(3)-p{i}(4))<=width/15) p{i+1}(1)=min(p{i}(1),p{i+1}(1));p{i+1}(2)=max(p{i}(2),p{i+1}(2));p{i+1}(3)=min(p{i}(3),p{i+1}(3));p{i+1}(4)=max(p{i}(4),p{i+1}(4)); %向后合并n=n+1;ncount(n)=i+1;endend%如果有合并,求出合并后最终区域if(n>0)d_ncount=ncount(2:n+1)-ncount(1:n);%避免重复记录临近的多个区域。
python车型识别代码
![python车型识别代码](https://img.taocdn.com/s3/m/8871038e6037ee06eff9aef8941ea76e58fa4a97.png)
python车型识别代码车型识别代码是用于识别和区分不同车辆型号的一组字符或数字。
在 Python 中,可以使用正则表达式或字符串处理方法来提取、解析和识别车型识别代码。
下面是一个示例代码,演示如何使用正则表达式来识别车型识别代码:```pythonimport redef extract_vehicle_identification_code(vehicle_description):# 定义车型识别代码的正则表达式模式pattern = r'[A-Za-z0-9]{3,7}'# 使用正则表达式在车辆描述中查找匹配的车型识别代码match = re.search(pattern, vehicle_description)if match:vehicle_identification_code = match.group()return vehicle_identification_codeelse:return None# 示例车辆描述vehicle_description = "这是一辆红色的丰田凯美瑞,车型识别代码是JTDBE32K500000111。
"# 提取车型识别代码vehicle_identification_code = extract_vehicle_identification_code(vehicle_description)if vehicle_identification_code:print("车型识别代码:", vehicle_identification_code)else:print("未找到车型识别代码")```在上述示例中,我们定义了一个`extract_vehicle_identification_code`函数,它接受一个车辆描述字符串作为输入。
函数使用正则表达式模式来匹配车型识别代码,并使用`re.search`方法在车辆描述中查找匹配的代码。
基于Python实现的车牌识别项目
![基于Python实现的车牌识别项目](https://img.taocdn.com/s3/m/ee948439905f804d2b160b4e767f5acfa1c78339.png)
基于Python实现的车牌识别项⽬车牌识别在⾼速公路中有着⼴泛的应⽤,⽐如我们常见的电⼦收费(ETC)系统和交通违章车辆的检测,除此之外像⼩区或地下车库门禁也会⽤到,基本上凡是需要对车辆进⾏⾝份检测的地⽅都会⽤到。
简介车牌识别系统(Vehicle License Plate Recognition)是计算机视频图像识别技术在车辆牌照识别中的⼀种应⽤,通常⼀个车牌识别系统主要包括以下这四个部分:车辆图像获取车牌定位车牌字符分割车牌字符识别我们再来看⼀下百科中对车牌识别技术的描述:车牌识别技术要求能够将运动中的汽车牌照从复杂背景中提取并识别出来,通过车牌提取、图像预处理、特征提取、车牌字符识别等技术,识别车辆牌号、颜⾊等信息,⽬前最新的技术⽔平为字母和数字的识别率可达到 99.7%,汉字的识别率可达到99%。
实现⽅式我们这⾥不做太复杂的车辆动态识别,只演⽰从图像中识别车牌信息,车牌识别功能的实现⽅式⼤致分为两种,⼀种是⾃⼰编写代码实现,另⼀种是借助第三⽅ API 接⼝实现。
⾃⼰实现如果我们想要通过 Python ⾃⼰⼿动编码实现车牌识别功能,可以借助⼀些 Python 库,⽐如:OpenCV、TensorFlow 等,这种⽅式因为每⼀个功能点都需要我们⾃⼰编码实现,所有会相对复杂⼀些,另⼀⽅⾯如果我们想要保证识别的准确性,可能需要做⼤量的实验,也就是说会花费更多的时间。
第三⽅接⼝现在已经有⼀些第三⽅平台实现好了车牌识别的功能,并且他们对外提供了 API 接⼝,我们只需要调⽤他们提供的接⼝即可,这种⽅式实现就相对简单了⼀些,并且通常接⼝提供⽅对外提供的接⼝功能的准确性也是基本可以保证的,原因很简单,如果接⼝功能太差的话,⼀是⾃⼰打脸,还有就是基本不会有什么⼈使⽤,也就失去了接⼝对外提供的价值了,另外第三⽅接⼝可能会收取⼀定费⽤,因此,如果现实中我们具体实现的话要综合考虑。
具体实现SDK 安装百度云 SDK 对多种语⾔提供了⽀持,⽐如:Python、Java、C++、IOS、Android 等,这⾥我们安装 Python 版的 SDK,安装很简单,使⽤pip install baidu-aip命令即可。
车牌识别开源项目汇总
![车牌识别开源项目汇总](https://img.taocdn.com/s3/m/3b8ea6f9b9f67c1cfad6195f312b3169a451ea26.png)
车牌识别开源项⽬汇总⼀.EasyPR相关讲解开源库介绍 EasyPR是⼀个中⽂的开源车牌识别系统,其⽬标是成为⼀个简单、⾼效、准确的车牌识别引擎。
相⽐于其他的车牌识别系统,EasyPR有如下特点:它基于openCV这个开源库。
这意味着你可以获取全部源代码,并且移植到java等平台。
它能够识别中⽂。
例如车牌为苏EUK722的图⽚,它可以准确地输出std:string类型的"苏EUK722"的结果。
它的识别率较⾼。
图⽚清晰情况下,车牌检测与字符识别可以达到80%以上的精度。
车牌检测(Plate Detection):对⼀个包含车牌的图像进⾏分析,最终截取出只包含车牌的⼀个图块。
这个步骤的主要⽬的是降低了在车牌识别过程中的计算量。
如果直接对原始的图像进⾏车牌识别,会⾮常的慢,因此需要检测的过程。
在本系统中,我们使⽤SVM(⽀持向量机)这个机器学习算法去判别截取的图块是否是真的“车牌”。
字符识别(Chars Recognition):有的书上也叫Plate Recognition,我为了与整个系统的名称做区分,所以改为此名字。
这个步骤的主要⽬的就是从上⼀个车牌检测步骤中获取到的车牌图像,进⾏光学字符识别(OCR)这个过程。
其中⽤到的机器学习算法是著名的⼈⼯神经⽹络(ANN)中的多层感知机(MLP)模型。
最近⼀段时间⾮常⽕的“深度学习”其实就是多隐层的⼈⼯神经⽹络,与其有⾮常紧密的联系。
通过了解光学字符识别(OCR)这个过程,也可以知晓深度学习所基于的⼈⼯神经⽹路技术的⼀些内容。
完整的EasyPR流程具体说来,EasyPR中PlateDetect与CharsRecognize各包括三个模块。
PlateDetect包括的是车牌定位,SVM训练,车牌判断三个过程,见下图。
PlateDetect过程我们获得了许多可能是车牌的图块,将这些图块进⾏⼿⼯分类,聚集⼀定数量后,放⼊SVM模型中训练,得到SVM的⼀个判断模型,在实际的车牌过程中,我们再把所有可能是车牌的图块输⼊SVM判断模型,通过SVM模型⾃动的选择出实际上真正是车牌的图块。
车牌识别系统源代码
![车牌识别系统源代码](https://img.taocdn.com/s3/m/ab800eabdbef5ef7ba0d4a7302768e9951e76efa.png)
车牌识别系统源代码k=input(‘Enter the file name:,''s’);%输入车牌照片pic=imread(k);imshow(pic);pic_gray=rgb2gray(pic);pic_gray=medfilt2(pic_gray,[3,3]);%对灰度图像进行中值滤波Image=im2bw(pic_gray,0.2);BW=edge(pic_gray,‘sobel’);%找出图像的边缘[imx,imy]=size(BW);%计算图像大小msk=[0 0 0 0 0;0 1 1 1 0;0 1 1 1 0;0 1 1 1 0;0 0 0 0 0;];B0=conv2(double(BW),double(msk));%对边缘区域进行加强se=ones(2,80);B1=imdilate(B0,se);%figure;%imshow(B1);B2=imerode(B1,se);se=ones(20,2);B3=imdilate(B2,se);B4=imerode(B3,se);se=ones(50,2);B5=imdilate(B4,se);B6=imerode(B5,se);[B,L]=bwboundaries(B6,4);%对边界图进行小区域联通,是车牌区域连通为一个方块imshow(label2rgb(L,@jet,[.5 .5 .5]))%对连通区域进行标记hold onfor k=1:length(B)boundary=B{k};plot(boundary(:,2),boundary(:,1),'w','LineWidth',2)endfor k=1:length(B) %循环遍历每个连通域的边界boundary=B{k}; %获取一条边界上的所有点delta_sq=diff(boundary).^2;perimeter=sum(sqrt(sum(delta_sq,2))); %计算边界周长area=stats(k).Area;%获取边界所围面积metric=27*area/perimeter^2;%计算匹配度metric_string=sprintf('%2.2f',metric);%要显示的匹配度字串endif metric>=0.85&&metric<=1.15&&area>1000 %截取出匹配度接近1且面积大于1000像素的连通域centroid=stats(k).Centroid;plot(centroid(1),centroid(2),'ko');%提取该连通域所对应在二值图像中的矩形区域goalboundary=boundary;s=min(goalboundary,[],1);e=max(goalboundary,[],1);goal=imcrop(Image,[s(2) s(1) e(2)- s(2) e(1)-s(1)]);endtext(boundray(1,2)-35,boundray(1,1)+13,metric_string,'Color','g','FontSize',14,'Font Weight','bold');%显示匹配度字串endgoal=~goal; %对截取图像进行反色处理figure;imshow(goal);[a,b]=size(goal);for i=a/2:-1:1 %从图像水平轴开始向上扫描,当白点数少于每行点总数的1/10时,停止扫描,并将该行定义为车牌字符区域的上限num=0;for j=1:bif goal(i,j)==1num=num+1;endendif num<(b*0.1)line_up=i;break;endendfor i=a/2:a %从图像水平中轴开始向下扫描,当白点数少于每行点总数的1/10时,停止扫描,并将该行定义为车牌字符区域的下限num=0;for j=1:bif goal(i,j)==1num=num+1;endendif num<(b*0.1)line_down=i;break;endendgoal=goal(line_up:line_down,1:b);%根据之前定义的上下限截取车牌字符区域figure;imshow(goal);%显示车牌字符区域[a,b]=size(goal);row=zeros(18);now=1;flag=0;for j=1:b %对截取出的字符区域进行列竖扫描,并且取每列总点数的十分之一作为阀值点,当每列的白点数从阀值以上掉落到阀值以下或从阀值以下上升到阀值以上时,记录该列的横坐标num=0;for i=1:aif goal(i,j)==1num=num+1;endendif flag==0if num<(a*0.1)row(now)=j;now=now+1;flag=1;endelseif num>(a*0.1)row(now)=j;now=now+1;flag=0;endendendif row(3)-row(2)>10%判断扫描出的第二块区域(扫描到的第二列与第三列之间)是否包含有效字符,如包含,则将扫描到的第二列定义为字符分割的起始列;否则,则定义第一列为起始列now=2;elsenow=1;endfigure;11=0;12=0;for k=1:8m=row(now);m=row(now+1);temp=goal(1:a,m:n);point=0;%扫描每个字符图片的白点数for i=1:afor j=1:n-mif temo(i,j)==1point= point+1;endendendif point>0.4*a*(n-m)&&n>m %当扫描到的白点数小于总点数的5分之二是放弃输出(有可能是车牌上的点状分割符)12=12+1;% 用来记录识别出的字符数subplot(1,7,12);x(k)=code(temp);%调用子程序进行字符扫描,并返回字符的ASCII码x(k)=uint8(x(k));if x(k)>0 %当所选区域不为空时进行输出11=11+1;% 用来记录输出的字符数s(11)=char(x(k));endtemp(32,32)=0;imshow(temp);endnow=now+2;endy=char(s);%将得到的ASCII码重新转换为字符并在屏幕上输出fprintf('该车辆的车牌号为:')disp(y);fprintf('输出的字符数为: %4d\\',11)fprintf('识别出的字符数为: %4d\\',12)。
车牌识别系统基于开发系统代码大全
![车牌识别系统基于开发系统代码大全](https://img.taocdn.com/s3/m/b3cdffc5d5bbfd0a79567314.png)
// 图像字符识别毕业设计View.cpp : CMyView 类的实现//#include "stdafx.h"#include "图像字符识别毕业设计.h"#include "图像字符识别毕业设计Doc.h"#include "图像字符识别毕业设计View.h"#include ".\图像字符识别毕业设计view.h"#ifdef _DEBUG#define new DEBUG_NEW#endif// CMyViewIMPLEMENT_DYNCREATE(CMyView, CView)BEGIN_MESSAGE_MAP(CMyView, CView)// 标准打印命令ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview) ON_COMMAND(ID_FILE_OPEN, OnFileOpen)ON_COMMAND(ID_IMAGE_PARAMENT, OnImageParament)ON_COMMAND(ID_FIND_CARNUMBER, OnFindCarnumber)ON_COMMAND(ID_COLOR_CRAY, OnColorCray)ON_COMMAND(ID_MEDIAN5, OnMedian5)ON_COMMAND(ID_LOG_BORDDETEC, OnLogBorddetec)ON_COMMAND(ID_OTSU_THRESHOLD, OnOtsuThreshold)ON_COMMAND(ID_CATCH_NUMBERONCE, OnCatchNumberonce) ON_COMMAND(ID_Lap_Borddetec, OnLapBorddetec)ON_COMMAND(ID_CATCH_BNUMBER, OnCatchBnumber)ON_COMMAND(ID_GET_CARNUMBER, OnGetCarnumber)ON_COMMAND(ID_GET_HCARNUMBER, OnGetHcarnumber)ON_COMMAND(ID_NUMBER_CUT, OnNumberCut)ON_COMMAND(ID_ADD_ALL, OnAddAll)ON_COMMAND(ID_NUMBER_STUDY, OnNumberStudy)ON_COMMAND(ID_FIRSTNUMBER_RECOGNISE, OnFirstnumberRecognise) ON_COMMAND(ID_SECONDNUMBER_RECOGNISE, OnSecondnumberRecognise) ON_COMMAND(ID_THIRDNUMBER_RECOGNISE, OnThirdnumberRecognise) ON_COMMAND(ID_FOURTHNUMBER_RECOGNISE, OnFourthnumberRecognise) ON_COMMAND(ID_FIFTHNUMBER_RECOGNISE, OnFifthnumberRecognise) ON_COMMAND(ID_SISTHNUMBER_RECOGNISE, OnSisthnumberRecognise) ON_COMMAND(ID_SEVENTHNUMBER_RECOGNISE, OnSeventhnumberRecognise) ON_COMMAND(ID_ZIMU_STUDY, OnZimuStudy)ON_COMMAND(ID_HANZI_STUDY, OnHanziStudy)ON_COMMAND(ID_ZHIFUSHIBIE_ZONGHE, OnZhifushibieZonghe)END_MESSAGE_MAP()// CMyView 构造/析构CMyView::CMyView(){// TODO: 在此处添加构造代码}CMyView::~CMyView(){}BOOL CMyView::PreCreateWindow(CREATESTRUCT& cs){// TODO: 在此处通过修改 CREATESTRUCT cs 来修改窗口类或// 样式return CView::PreCreateWindow(cs);}// CMyView 绘制void CMyView::OnDraw(CDC* pDC){CMyDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);if (!pDoc)return;// TODO: 在此处为本机数据添加绘制代码if (!m_Image.IsNull()){m_Image.Draw(pDC->m_hDC,0,0);}}// CMyView 打印BOOL CMyView::OnPreparePrinting(CPrintInfo* pInfo){// 默认准备return DoPreparePrinting(pInfo);}void CMyView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/){// TODO: 打印前添加额外的初始化}void CMyView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/){// TODO: 打印后添加清除过程}// CMyView 诊断#ifdef _DEBUGvoid CMyView::AssertValid() const{CView::AssertValid();}void CMyView::Dump(CDumpContext& dc) const{CView::Dump(dc);}CMyDoc* CMyView::GetDocument() const // 非调试版本是内联的{ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMyDoc)));return (CMyDoc*)m_pDocument;}#endif //_DEBUG// CMyView 消息处理程序void CMyView::OnFileOpen(){// TODO: 在此添加命令处理程序代码CString strFilter;CSimpleArray<GUID> aguidFileTypes;HRESULT hResult;// 获取CImage支持的图像文件的过滤字符串hResult =m_Image.GetExporterFilterString(strFilter,aguidFileTypes,_T( "AllImage Files") );if (FAILED(hResult)){MessageBox("GetExporterFilter调用失败!");return;}CFileDialog dlg(TRUE, NULL, NULL, OFN_FILEMUSTEXIST, strFilter);if(IDOK != dlg.DoModal())return;m_Image.Destroy();// 将外部图像文件装载到CImage对象中hResult = m_Image.Load(dlg.GetFileName());if (FAILED(hResult)) {MessageBox("调用图像文件失败!");return;}// 设置主窗口标题栏内容CString str;str.LoadString(AFX_IDS_APP_TITLE); AfxGetMainWnd()->SetWindowText(str + " - " +dlg.GetFileName());Invalidate(); // 强制调用OnDraw}void CMyView::OnImageParament(){// TODO: 在此添加命令处理程序代码CClientDC dc(this);HBRUSH hBrush;HPEN hPen;int i,x,y,k,nYChar;CString str;TEXTMETRIC tm;char *textbuf[]={"像素行的存储顺序","像素宽度","像素高度","每像素位数","每行字节数"};x=775;y=120;hPen=(HPEN) GetStockObject(WHITE_PEN);hBrush=(HBRUSH) GetStockObject(WHITE_BRUSH);dc.SelectObject(hPen);dc.SelectObject(hBrush);dc.GetTextMetrics(&tm);dc.SetTextColor(RGB(0,0,0));nYChar=(tm.tmHeight+tm.tmExternalLeading)*3/2;dc.TextOut(x+60,y-nYChar*3/2,"图像特征参数");for(i=0;i<5;i++){dc.TextOut (x,y+nYChar*i,textbuf[i]);}x+=175;k=m_Image.GetPitch();if(k<0)dc.TextOut (x,y+nYChar*0,"自下而上");elsedc.TextOut (x,y+nYChar*0,"自上而下");str.Format ("%d",abs(k));dc.TextOut (x,y+nYChar*4,str,lstrlen(str));str.Format ("%d",m_Image.GetWidth ());dc.TextOut (x,y+nYChar*1,str);str.Format ("%d",m_Image.GetHeight ());dc.TextOut (x,y+nYChar*2,str);str.Format ("%d",m_Image.GetBPP ());dc.TextOut (x,y+nYChar*3,str);if(m_Image.GetMaxColorTableEntries ()){dc.TextOut (x-175,y+nYChar*6,"调色板单元数");k=m_Image.GetMaxColorTableEntries ();str.Format ("%d",k);dc.TextOut (x,y+nYChar*6,str);}elsedc.TextOut (x-175,y+nYChar*6,"真彩色图像,无调色板");}void CMyView::OnFindCarnumber(){// TODO: 在此添加命令处理程序代码}struct IMAGEPARAMENT {int nWidth;int nHeight;int nBitCount;int nBytesPerLine;int nBytesPerPixel;int nNumColors;int nSize;};void GetImageParament(CImage *pImg,struct IMAGEPARAMENT *ppImgParam){if (pImg->IsNull()) return;ppImgParam->nWidth = pImg->GetWidth();ppImgParam->nHeight = pImg->GetHeight();ppImgParam->nBitCount = pImg->GetBPP();ppImgParam->nBytesPerLine =(pImg->GetWidth()*pImg->GetBPP()+31)/32*4;ppImgParam->nBytesPerPixel = pImg->GetBPP()/8;if (pImg->GetBPP()<=8)ppImgParam->nNumColors= 1 << pImg->GetBPP();elseppImgParam->nNumColors= 0;ppImgParam->nSize =ppImgParam->nBytesPerLine*ppImgParam->nHeight;}void ImageCopy(CImage *pImgn,CImage *pImgm){struct IMAGEPARAMENT P;RGBQUAD ColorTab[256];CDC *pOrigDC,*pDC;GetImageParament(pImgm,&P);if (!pImgn->IsNull())pImgn->Destroy();pImgn->Create(P.nWidth,P.nHeight,P.nBitCount,0);if (P.nNumColors>0){pImgm->GetColorTable(0,P.nNumColors,ColorTab);pImgn->SetColorTable(0,P.nNumColors,ColorTab);}pOrigDC= CDC::FromHandle(pImgm->GetDC());pDC = CDC::FromHandle(pImgn->GetDC());pDC->BitBlt(0,0,P.nWidth,P.nHeight,pOrigDC,0,0,SRCCOPY);pImgm->ReleaseDC();pImgn->ReleaseDC();}void ColorToGray(CImage *pImgn,CImage *pImgm){int i, x, y;int gray[256];BYTE *cbuf,*gbuf;RGBQUAD ColorTab[256];CImage gpImg;CString str1;struct IMAGEPARAMENT P;GetImageParament(pImgm,&P);if (P.nBitCount<8) return;gpImg.Create(P.nWidth,P.nHeight,8,0);for (i=0; i<256; i++){ColorTab[i].rgbBlue = ColorTab[i].rgbGreen =ColorTab[i].rgbRed = i;}gpImg.SetColorTable(0,256,ColorTab);if (pImgm->GetBPP()<=8) { pImgm->GetColorTable(0,P.nNumColors,ColorTab);for (i=0; i<P.nNumColors; i++){gray[i] = (int) (0.11*ColorTab[i].rgbBlue +0.59*ColorTab[i].rgbGreen +0.30*ColorTab[i].rgbRed);}for (y=0; y<P.nHeight; y++) {cbuf = (BYTE*) pImgm->GetPixelAddress(0,y);gbuf = (BYTE*) gpImg.GetPixelAddress(0,y);for (x=0; x<P.nWidth; x++)gbuf[x] = (BYTE) gray[cbuf[x]];}}else {for (y=0; y<P.nHeight; y++) {cbuf = (BYTE*) pImgm->GetPixelAddress(0,y);gbuf = (BYTE*) gpImg.GetPixelAddress(0,y);for (x=0,i=0; x<P.nWidth; x++,i+=P.nBytesPerPixel) { gbuf[x] = (BYTE) (0.11*cbuf[i] + 0.59*cbuf[i+1] +0.30*cbuf[i+2]);}}}ImageCopy(pImgn,&gpImg);gpImg.Destroy();}void CMyView::OnColorCray(){// TODO: 在此添加命令处理程序代码CString str1;ColorToGray(&m_Image,&m_Image);str1.LoadString(AFX_IDS_APP_TITLE);AfxGetMainWnd()->SetWindowText(str1 + " - " +"灰度图");Invalidate();}int MedValue(int *buf,int n,int m){int i,j,k,f;for(i=1;i<n;i++){for(j=n-1,f=0;j>=i;j--){if(buf[j]>buf[j+1]){k=buf[j];buf[j]=buf[j+1];buf[j+1]=k;f=1;}}if(f==0) break;}return(buf[m]);}int buff1[5];void Median5(BYTE **list0,BYTE**list1,int DX,int DY){int flag=5;for(int i=1;i<DY-1;i++){for(int j=1;j<DX-1;j++){buff1[0]=list1[i-1][j];buff1[1]=list1[i][j];buff1[2]=list1[i+1][j];buff1[3]=list1[i][j-1];buff1[4]=list1[i][j+1];list0[i][j]=(BYTE)MedValue(buff1,flag,flag/2);}}}BYTE** Create2DList(CImage *pImg){struct IMAGEPARAMENT P;int i;BYTE **list;GetImageParament(pImg,&P);list=(BYTE**)malloc(P.nHeight*sizeof(BYTE*));for (i=0;i<P.nHeight;i++)list[i]=(BYTE*) pImg->GetPixelAddress(0,i);return(list);}void CMyView::OnMedian5(){// TODO: 在此添加命令处理程序代码struct IMAGEPARAMENT PP;BYTE **list1,**list0;ImageCopy(&m_Image1,&m_Image);list1=(BYTE **)Create2DList(&m_Image);list0=(BYTE **)Create2DList(&m_Image1);GetImageParament(&m_Image,&PP);Median5(list0,list1,PP.nWidth,PP.nHeight);ImageCopy(&m_Image,&m_Image1);CString str2;str2.LoadString(AFX_IDS_APP_TITLE);AfxGetMainWnd()->SetWindowText(str2 + " - " +"5点中值滤波");Invalidate();}int Mask[3][3],Mask5[5][5],Scale,Offset;void WINAPI Template(BYTE **list0,BYTE **list1,int Dx,int Dy){int i,j,g;for (i=1;i<Dy-1;i++) {for (j=1;j<Dx-1;j++) {g = (Mask[0][0]*list1[i-1][j-1]+Mask[0][1]*list1[i-1][j]+Mask[0][2]*list1[i-1][j+1]+Mask[1][0]*list1[i][j-1]+Mask[1][1]*list1[i][j] +Mask[1][2]*list1[i][j+1]+Mask[2][0]*list1[i+1][j-1]+Mask[2][1]*list1[i+1][j] +Mask[2][2]*list1[i+1][j+1])/Scale+Offset;if (g>0xff) g=0xff;else if (g<0) g=0;list0[i][j] = (BYTE) g;}}}void WINAPI TemplateB(BYTE **list0,BYTE **list1,int Dx,int Dy,int t) { // t x t 邻域处理共用程序 (t = 3 or 5)int i,j,g,m,n,*p;for (i=t/2;i<Dy-t/2;i++) {for (j=t/2;j<Dx-t/2;j++) {g=0;p=&Mask5[0][0];for (m=i-t/2;m<=i+t/2;m++) {for (n=j-t/2;n<=j+t/2;n++)g+=(*p++)*list1[m][n];}g=g/Scale+Offset;if (g>0xff) g=0xff;else if (g<0) g=0;list0[i][j] = g;}}}void WINAPI Laplacian(BYTE **list0,BYTE **list1,int Dx,int Dy)//拉普拉斯算法{Scale=1;Offset=1;Mask[0][0]=Mask[0][2]=Mask[2][0]=Mask[2][2]=-1;Mask[0][1]=Mask[2][1]=Mask[1][0]=Mask[1][2]=-1;Mask[1][1]=8;Template(list0,list1,Dx,Dy);Offset=0;}void CMyView::OnLapBorddetec(){// TODO: 在此添加命令处理程序代码struct IMAGEPARAMENT PP;BYTE **list1,**list0;ImageCopy(&m_Image1,&m_Image);list1=(BYTE **)Create2DList(&m_Image);list0=(BYTE **)Create2DList(&m_Image1);GetImageParament(&m_Image,&PP);Laplacian(list0,list1,PP.nWidth,PP.nHeight);ImageCopy(&m_Image,&m_Image1);CString str2;str2.LoadString(AFX_IDS_APP_TITLE);AfxGetMainWnd()->SetWindowText(str2 + " - " +"laplacian变换");Invalidate();}void WINAPI LoG(BYTE **list0,BYTE **list1,int Dx,int Dy){ // 高斯型拉普拉斯算法int mask[25]={ 0, 0,-1, 0, 0,0,-1,-2,-1, 0,-1,-2,16,-2,-1,0,-1,-2,-1, 0,0, 0,-1, 0, 0};Scale=1; Offset=254;memcpy(Mask5,mask,25*sizeof(int));TemplateB(list0,list1,Dx,Dy,5);Offset=0;}void CMyView::OnLogBorddetec(){// TODO: 在此添加命令处理程序代码struct IMAGEPARAMENT PP;BYTE **list1,**list0;ImageCopy(&m_Image1,&m_Image);list1=(BYTE **)Create2DList(&m_Image);list0=(BYTE **)Create2DList(&m_Image1);GetImageParament(&m_Image,&PP);LoG(list0,list1,PP.nWidth,PP.nHeight);ImageCopy(&m_Image,&m_Image1);CString str2;str2.LoadString(AFX_IDS_APP_TITLE);AfxGetMainWnd()->SetWindowText(str2 + " - " +"log变换");Invalidate();}int MaxMin(double *tab,int flag){double max,min;int i,p,q;max=min=tab[128];p=q=128;for (i=0;i<256;i++) {if (tab[i]>max) {max=tab[i];p=i;}if (tab[i]<min) {min=tab[i];q=i;}}if (flag==1) {for (i=0;i<256;i++)tab[i]=120*(max-tab[i])/(max-min);}else {for (i=0;i<256;i++)tab[i]=120*(tab[i]-min)/(max-min);p=q;}return(p);}void Release2DList(BYTE** list){free(list);}void SetAllPalette(CImage *pImg, RGBQUAD *ColorTab){struct IMAGEPARAMENT P;GetImageParament(pImg,&P);pImg->SetColorTable(0, P.nNumColors, ColorTab);}void SetPalette(CImage *pImg,int n,int r,int g,int b){RGBQUAD ColorTab;ColorTab.rgbBlue = b;ColorTab.rgbGreen = g;ColorTab.rgbRed = r;pImg->SetColorTable(n, 1, &ColorTab);}int WINAPI Otsu(long *pg) // 大津法取阈值{int i,j,p;double m0,m1,M0,M1,u,v,w[256];M0=M1=0;for (i=0;i<256;i++) {M0+=pg[i]; M1+=pg[i]*i;}for (j=0;j<256;j++) {m0=m1=0;for (i=0;i<=j;i++) {m0+=pg[i]; m1+=pg[i]*i;}if (m0) u=m1/m0;else u=0;if (M0-m0) v=(M1-m1)/(M0-m0);else v=0;w[j]=m0*(M0-m0)*(u-v)*(u-v);}p=MaxMin(w,1);return(p);}long pg[256];void Threshold(CImage *pImgm,double ff){struct IMAGEPARAMENT P;BYTE **list,*lpBuf;RGBQUAD ColorTab[256];int x,y,thre;//int t;//int tab[256],buf[20],bn;GetImageParament(pImgm,&P);list=(BYTE**) Create2DList(pImgm);//histog(list,pg,0,0,P.nWidth,P.nHeight);thre=Otsu(pg);for (y=0;y<P.nHeight;y++) {lpBuf=(BYTE*) pImgm->GetPixelAddress(0,y);for (x=0;x<P.nWidth;x++,lpBuf++) {if (*lpBuf>=thre) *lpBuf=1;else *lpBuf=0;}}memset(ColorTab,0,1024);SetAllPalette(pImgm,ColorTab);SetPalette(pImgm,1,255,255,255);Release2DList(list);}void CMyView::OnOtsuThreshold()//二值化响应函数{// TODO: 在此添加命令处理程序代码Threshold(&m_Image,0);CString str2;str2.LoadString(AFX_IDS_APP_TITLE);AfxGetMainWnd()->SetWindowText(str2 + " - " +"OTSU法二值化");Invalidate();}int InImage(CImage *pImg,int x,int y){struct IMAGEPARAMENT P;GetImageParament(pImg,&P);if ((x<0)||(y<0)||(x>=P.nWidth)||(y>=P.nHeight)) return 0;else return 1;}DWORD GetPixelValue(CImage *pImg,int x,int y){struct IMAGEPARAMENT P;BYTE *lp;DWORD dd=0;GetImageParament(pImg,&P);if ((P.nBitCount<8)||(!InImage(pImg,x,y))) return 0;lp = (BYTE*) pImg->GetPixelAddress(x,y);memcpy(&dd,lp,P.nBytesPerPixel);return(dd);}void SetPixelValue(CImage *pImg,int x,int y,DWORD c){struct IMAGEPARAMENT P;BYTE *lp;GetImageParament(pImg,&P);if ((P.nBitCount<8)||(!InImage(pImg,x,y))) return;lp = (BYTE*) pImg->GetPixelAddress(x,y);memcpy(lp,&c,P.nBytesPerPixel);}void CMyView::OnCatchNumberonce()//白字法{// TODO: 在此添加命令处理程序代码struct IMAGEPARAMENT P4,P5;int a[300];GetImageParament(&m_Image,&P4);int i,D,Dmin=3,T=0,T1=0,Tmin=5, Numbery=0,Numberx=0;ImageCopy(&NumberOnce,&m_Image);for (int y=P4.nHeight-5;y>=0;y--){ i=0;for (int x=0;x<P4.nWidth;x++){if (GetPixelValue(&m_Image,x,y)==1)a[i++]=x;//取该行白点存数组a}for(int j=1;j<i;j++){D=a[j]-a[j-1];if(D>=Dmin&&D<=4*Dmin) T++;if(D>4*Dmin) T=0;//判断为字符间距if(T==Tmin){T1++;while(T1==3){Numbery=y;Numberx=a[j-Tmin];//free(a);break;}}}if(Numbery!=0)break;}ImageCopy(&m_Image,&NumberOnce);GetImageParament(&m_Image,&P5);for ( int y=0;y<P5.nHeight;y++){for ( int x=0;x<P5.nWidth;x++){ //if(x==Numberx||y==Numbery) SetPixelValue(&m_Image,x,y,1);//调试专用//elseif(x>0&&x<115+Numberx&&y<Numbery+5&&y>Numbery-15);else//if (GetPixelValue(&m_Image,x,y)==1)SetPixelValue(&m_Image,x,y,0);}}CString str4;str4.LoadString(AFX_IDS_APP_TITLE);AfxGetMainWnd()->SetWindowText(str4+ " - " +"车牌粗定位");Invalidate();}void CMyView::OnCatchBnumber()//黑字法{// TODO: 在此添加命令处理程序代码struct IMAGEPARAMENT P4,P5;int a[300];GetImageParament(&m_Image,&P4);int i,D,Dmin=3,T=0,T1=0,Tmin=7,Numbery=0,Numberx=0;ImageCopy(&NumberOnce,&m_Image);for (int y=P4.nHeight-5;y>=0;y--){ i=0;for (int x=0;x<P4.nWidth;x++){if (GetPixelValue(&m_Image,x,y)==0)a[i++]=x;//取该行黑点存数组a}for(int j=1;j<i;j++){D=a[j]-a[j-1];if(D>=Dmin&&D<=4*Dmin) T++;if(D>4*Dmin) T=0;//判断为字符间距if(T==Tmin){T1++;while(T1==3){Numbery=y;Numberx=a[j-Tmin];//free(a);break;}}}if(Numbery!=0)break;}ImageCopy(&m_Image,&NumberOnce);GetImageParament(&m_Image,&P5);for ( int y=0;y<P5.nHeight;y++){for ( int x=0;x<P5.nWidth;x++){ //if(x==Numberx||y==Numbery) SetPixelValue(&m_Image,x,y,0);//调试专用// elseif(x>0&&x<115+Numberx&&y<Numbery+5&&y>Numbery-15);else//if (GetPixelValue(&m_Image,x,y)==1)SetPixelValue(&m_Image,x,y,0);}}CString str4;str4.LoadString(AFX_IDS_APP_TITLE);AfxGetMainWnd()->SetWindowText(str4+ " - " +"车牌粗定位");Invalidate();}int x1,x2,y1,y2;void CMyView::OnGetCarnumber()//精定位{// TODO: 在此添加命令处理程序代码struct IMAGEPARAMENT P6,P7;int T=0,k=0,tabmin=3,Tmin=2,Dimin=3,Di;int tab[800];int b[800];GetImageParament(&m_Image,&P6);ImageCopy(&NumberOnce,&m_Image);for (int i=0;i<P6.nWidth ;i++) //统计每列像素数据{tab[i]=0;for(int j=0;j<P6.nHeight ;j++){if(GetPixelValue(&m_Image,i,j)==1)//统计白点数存tab[i]tab[i]++;}}for (int i=0;i<P6.nWidth ;i++)//生成等差数列b[i]{ if(tab[i]>=tabmin) T++;if(tab[i]<tabmin) T=0;b[i]=T;}int tmax1[50];int Numberx1=0,Numberx2=0;for (int i=1;i<P6.nWidth ;i++)//求b[i]局部最大值bmax1[50]对应下标tmax1【50】{if(b[i]>=Tmin&&b[i+1]==0){tmax1[k++]=i-b[i];}}int c=0,cmin=2;for(int i=0;i<k-1;i++)//精确定位左位置Numberx1{ Di=tmax1[i+1]-tmax1[i];if(Di>=Dimin&&Di<=8*Dimin)c++;elsec=0;while(c==cmin){Numberx1=tmax1[i+1-cmin];break;}int tmax2[50];k=0;for (int i=P6.nWidth-1;i>0 ;i--)//求b[i]局部最大值bmax2[50]对应下标tmax2【50】{if(b[i-1]>=Tmin&&b[i]==0){tmax2[k++]=i;}}c=0;for(int i=0;i<k-1;i++)//精确定位右位置Numberx2{ Di=tmax2[i]-tmax2[i+1];if(Di>=Dimin&&Di<=8*Dimin)c++;elsec=0;while(c==5){Numberx2=tmax2[i+1-5];break;}}if(Numberx2-Numberx1<100)Numberx2=Numberx1+120;x1=Numberx1;x2=Numberx2;ImageCopy(&m_Image,&NumberOnce);GetImageParament(&m_Image,&P7);for ( int y=0;y<P7.nHeight;y++){for ( int x=0;x<P7.nWidth;x++){ if(x>Numberx1&&x<Numberx2);//else SetPixelValue(&m_Image,x,y,0);}}CString str4;str4.LoadString(AFX_IDS_APP_TITLE);AfxGetMainWnd()->SetWindowText(str4+ " - " +"车牌水平方向精定位Invalidate();}void CMyView::OnGetHcarnumber()//竖直方向定位{// TODO: 在此添加命令处理程序代码struct IMAGEPARAMENT P6,P7;int T=0,tabmin=14,Tmin=3,Numbery1=0,Numbery2=0;int tab[300];GetImageParament(&m_Image,&P6);ImageCopy(&NumberOnce,&m_Image);for (int i=0;i<P6.nHeight;i++) //统计每行像素数据{tab[i]=0;for(int j=0;j<P6.nWidth ;j++){if(GetPixelValue(&m_Image,j,i)==1)//统计白点数存tab[i]tab[i]++;}}for (int i=0;i<P6.nHeight;i++){ if(tab[i]>tabmin)T++;else T=0;if(T==Tmin){Numbery1=i-Tmin;break;}}T=0;for (int i=P6.nHeight-1;i>0;i--){ if(tab[i]>tabmin)T++;else T=0;if(T==Tmin){Numbery2=i+Tmin;break;}}if(Numbery2-Numbery1<10)y1=Numbery1;y2=Numbery2;ImageCopy(&m_Image,&NumberOnce);GetImageParament(&m_Image,&P7);for ( int y=0;y<P7.nHeight;y++){for ( int x=0;x<P7.nWidth;x++){ if(y>Numbery1&&y<Numbery2);//// else if((x1<=x&&x2>=x)&&(y==y1||y==y2))SetPixelValue(&m_Image,x,y,1);else SetPixelValue(&m_Image,x,y,0);}}CString str4;str4.LoadString(AFX_IDS_APP_TITLE);AfxGetMainWnd()->SetWindowText(str4+ " - " +"车牌竖直方向精定位");Invalidate();}void CMyView::OnAddAll()//定位算法综合{// TODO: 在此添加命令处理程序代码CMyView::OnColorCray();CMyView::OnLapBorddetec();CMyView::OnOtsuThreshold();//二值化响应函数CMyView::OnCatchNumberonce();//白字法CMyView::OnGetCarnumber();//精定位CMyView::OnGetHcarnumber();//竖直方向定位}int N7[7];int N0=0,N1=10,N2=20,N3=30,N4=40,N5=50,N6=60;void CMyView::OnNumberCut(){// TODO: 在此添加命令处理程序代码struct IMAGEPARAMENT P6,P7;int T=0,k=0,tabmin=1,Tmin=3;int tab[800];GetImageParament(&m_Image,&P6);ImageCopy(&NumberOnce,&m_Image);for (int i=0;i<P6.nWidth ;i++) //统计每列像素数据{tab[i]=0;for(int j=0;j<P6.nHeight ;j++){if(GetPixelValue(&m_Image,i,j)==1)//统计白点数存tab[i]tab[i]++;}}for (int i=0;i<P6.nWidth ;i++)//生成等差数列b[i]{ if(tab[i]>=tabmin) T++;if(tab[i]<tabmin) T=0;b[i]=T;}for (int i=1;i<P6.nWidth ;i++)//精确定位左位置N0{if(b[i]>=Tmin&&b[i+1]==0){N0=i-b[i];break;}}for (int i=N0+15;i<P6.nWidth ;i++)//精确定位左位置N1{if(b[i]>=Tmin&&b[i+1]==0){N1=i-b[i];break;}}for (int i=N1+15;i<P6.nWidth ;i++)//精确定位左位置N2{if(b[i]>=Tmin&&b[i+1]==0){N2=i-b[i];break;}}for (int i=N2+15;i<P6.nWidth ;i++)//精确定位左位置N3{if(b[i]>=Tmin&&b[i+1]==0){N3=i-b[i];break;}}{if(b[i]>=Tmin&&b[i+1]==0){N4=i-b[i];break;}}for (int i=N4+15;i<P6.nWidth ;i++)//精确定位左位置N5{if(b[i]>=Tmin&&b[i+1]==0){N5=i-b[i];break;}}for (int i=N5+15;i<P6.nWidth ;i++)//精确定位左位置N6{if(b[i]>=Tmin&&b[i+1]==0){N6=i-b[i];x2=N6+12;break;}}N7[0]=N0;N7[1]=N1;N7[2]=N2;N7[3]=N3;N7[4]=N4;N7[5]=N5;N7[6]=N6;for(int j=3;j<7;j++){if(N7[j]-N7[j-1]>15)N7[j]=N7[j-1]+15;}ImageCopy(&m_Image,&NumberOnce);GetImageParament(&m_Image,&P7);for ( int y=0;y<P7.nHeight;y++){for ( int x=0;x<P7.nWidth;x++){if((y>=y1&&y<=y2)&&(x==N7[0]||x==N7[1]||x==N7[2]||x==N7[3]||x==N7[ 4]||x==N7[5]||x==N7[6]||x==N7[6]+13))SetPixelValue(&m_Image,x,y,1);if((x1<=x&&x2+1>=x)&&(y==y1||y==y2))SetPixelValue(&m_Image,x,y,1);}}CString str4;str4.LoadString(AFX_IDS_APP_TITLE);AfxGetMainWnd()->SetWindowText(str4+ " - " +"字符分割");Invalidate();}double FN[4];int p,pmax;//数字相似度int p1;//汉字相似度int p2;//字母相似度double P[10]={};//数字识别器double P1[31]={};//汉字识别器double P2[24]={};//字母识别器const double JING[4]={};//部分汉字编码京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼const double JINTJ[4]={};const double HU[4]={10,13,12,1};const double YUCHQ[4]={};const double JIHB[4]={};const double YUHN[4]={};const double YUN[4]={};const double LIAO[4]={};const double HEI[4]={};const double XIANG[4]={};const double WAN[4]={};const double LUSD[4]={};const double XIN[4]={};const double SU[4]={13,9,7,9};//SU[4]={14,14,10,10}const double ZHE[4]={};const double GUIGX[4]={};const double GANGS[4]={};const double JINSHX[4]={};const double MENG[4]={};const double SHAN[4]={};const double JIJL[4]={};const double MIN[4]={};const double GUIGZH[4]={};const double YUE[4]={};const double QING[4]={};const double ZANG[4]={};const double CHUAN[4]={};const double NING[4]={};const double QIONG[4]={};const double AA[4]={7,2,13,12};//部分字母编码const double BB[4]={};const double CC[4]={16,11,10,11};const double DD[4]={12,10,15,12};const double EE[4]={18,13,11,11};const double FF[4]={18,11,9,0};const double GG[4]={};const double HH[4]={12,16,7,7};const double JJ[4]={};const double KK[4]={16,7,8,9};const double LL[4]={12,2,12,11};const double MM[4]={14,11,10,9};const double NN[4]={};const double PP[4]={};const double QQ[4]={};const double RR[4]={};const double SS[4]={};const double TT[4]={};const double UU[4]={};const double VV[4]={};const double YY[4]={};const double ZZ[4]={};const double LI[4]={12,11,10,12};//0~9编码const double YI[4]={6,2,6,2};const double ER[4]={11,17,12,10};const double SA[4]={8,17,7,11};const double SI[4]={4,15,17,19};const double WU[4]={9,14,15,14};const double LU[4]={9,9,10,11};const double QI[4]={5,14,4,5};const double BA[4]={14,14,14,14};const double JU[4]={17,13,9,10};int N;void CMyView::OnHanziStudy()//汉字识别共用{struct IMAGEPARAMENT P7;GetImageParament(&m_Image,&P7);//ImageCopy(&NumberOnce,&m_Image);for ( int y=0;y<P7.nHeight;y++){for ( int x=0;x<P7.nWidth;x++){if((y>=y1&&y<=y2)&&(x==N7[0]||x==N7[1]||x==N7[2]||x==N7[3]||x==N7[ 4]||x==N7[5]||x==N7[6]||x==N7[6]+13))SetPixelValue(&m_Image,x,y,0);if((x1<=x&&x2+1>=x)&&(y==y1||y==y2))SetPixelValue(&m_Image,x,y,0);}}//ImageCopy(&m_Image,&NumberOnce);int i=0,k;//int su[4];//double p=0;CClientDC dc(this);HBRUSH hBrush;HPEN hPen;hPen=(HPEN) GetStockObject(WHITE_PEN); hBrush=(HBRUSH) GetStockObject(WHITE_BRUSH);dc.SelectObject(hPen);dc.SelectObject(hBrush);dc.SetTextColor(RGB(0,0,0));CString str;for(int x=N+1;x<=N+6;x++)for (int y=y1+1;y<=y1+6;y++){k=GetPixelValue(&m_Image,x,y);FN[i]=FN[i]+k;}i++;for(int x=N+7;x<=N+12;x++)for (int y=y1+1;y<=y1+6;y++){k=GetPixelValue(&m_Image,x,y);FN[i]=FN[i]+k;}i++;for(int x=N+1;x<=N+6;x++)for (int y=y1+7;y<=y1+12;y++){k=GetPixelValue(&m_Image,x,y);FN[i]=FN[i]+k;}i++;for(int x=N+7;x<=N+12;x++)for (int y=y1+7;y<=y1+12;y++){k=GetPixelValue(&m_Image,x,y);FN[i]=FN[i]+k;}for(i=0;i<4;i++){str.Format ("%g",FN[i]);dc.TextOut (30*i+15,50,str,2);//FN[i]=0;}for(i=0;i<4;i++){if(FN[i]<=JING[i]) P1[0]=P1[0]+(FN[i]+1)/(JING[i]+1);else P1[0]=P1[0]+(JING[i]+1)/(FN[i]+1);}for(i=0;i<4;i++){if(FN[i]<=JINTJ[i]) P1[1]=P1[1]+(FN[i]+1)/(JINTJ[i]+1);else P1[1]=P1[1]+(JINTJ[i]+1)/(FN[i]+1);}for(i=0;i<4;i++){if(FN[i]<=HU[i]) P1[2]=P1[2]+(FN[i]+1)/(HU[i]+1);else P1[2]=P1[2]+(HU[i]+1)/(FN[i]+1);}for(i=0;i<4;i++){if(FN[i]<=YUCHQ[i]) P1[3]=P1[3]+(FN[i]+1)/(YUCHQ[i]+1);else P1[3]=P1[3]+(YUCHQ[i]+1)/(FN[i]+1);}for(i=0;i<4;i++){if(FN[i]<=JIHB[i]) P1[4]=P1[4]+(FN[i]+1)/(JIHB[i]+1);else P1[4]=P1[4]+(JIHB[i]+1)/(FN[i]+1);}for(i=0;i<4;i++){if(FN[i]<=YUHN[i]) P1[5]=P1[5]+(FN[i]+1)/(YUHN[i]+1);else P1[5]=P1[5]+(YUHN[i]+1)/(FN[i]+1);}for(i=0;i<4;i++){if(FN[i]<=YUN[i]) P1[6]=P1[6]+(FN[i]+1)/(YUN[i]+1);else P1[6]=P1[6]+(YUN[i]+1)/(FN[i]+1);}for(i=0;i<4;i++){if(FN[i]<=LIAO[i]) P1[7]=P1[7]+(FN[i]+1)/(LIAO[i]+1);else P1[7]=P1[7]+(LIAO[i]+1)/(FN[i]+1);}for(i=0;i<4;i++){if(FN[i]<=HEI[i]) P1[8]=P1[8]+(FN[i]+1)/(HEI[i]+1);else P1[8]=P1[8]+(HEI[i]+1)/(FN[i]+1);}for(i=0;i<4;i++){if(FN[i]<=XIANG[i]) P1[9]=P1[9]+(FN[i]+1)/(XIANG[i]+1);else P1[9]=P1[9]+(XIANG[i]+1)/(FN[i]+1);。
车牌识别(附源代码)
![车牌识别(附源代码)](https://img.taocdn.com/s3/m/e80f6bed960590c69ec37676.png)
车牌识别(附源代码)车牌识别电子1301 孙洪江 2013234020113一、目的与要求车牌定位系统的目的在于正确获取整个图像中车牌的区域,并识别出车牌号。
通过设计实现车牌识别系统,能够提高学生分析问题和解决问题的能力,还能培养一定的科研能力二、设计原理:牌照自动识别是一项利用车辆的动态视频或静态图像进行牌照号码、牌照颜色自动识别的模式识别技术。
其硬件基础一般包括触发设备、摄像设备、照明设备、图像采集设备、识别车牌号码的处理机等,其软件核心包括车牌定位算法、车牌字符分割算法和光学字符识别算法等。
某些牌照识别系统还具有通过视频图像判断车辆驶入视野的功能称之为视频车辆检测。
一个完整的牌照识别系统应包括车辆检测、图像采集、牌照识别等几部分。
当车辆检测部分检测到车辆到达时触发图像采集单元,采集当前的视频图像。
牌照识别单元对图像进行处理,定位出牌照位置,再将牌照中的字符分割出来进行识别,然后组成牌照号码输出。
三、详细设计步骤:为了进行牌照识别,需要以下几个基本的步骤:a.牌照定位,定位图片中的牌照位置;b.牌照字符分割,把牌照中的字符分割出来;c.牌照字符识别,把分割好的字符进行识别,最终组成牌照号码。
牌照识别过程中,牌照颜色的识别依据算法不同,可能在上述不同步骤实现,通常与牌照识别互相配合、互相验证。
(1)牌照定位:自然环境下,汽车图像背景复杂、光照不均匀,如何在自然背景中准确地确定牌照区域是整个识别过程的关键。
首先对采集到的视频图像进行大范围相关搜索,找到符合汽车牌照特征的若干区域作为候选区,然后对这些侯选区域做进一步分析、评判,最后选定一个最佳的区域作为牌照区域,并将其从图象中分割出来。
(2)牌照字符分割 :se=strel('rectangle',[25,25]);%构造结构元素以正方形构造一个seI4=imclose(I3,se);figure(5),imshow(I4);title('smothing image');结果如下所示:6. 删除二值图像的小对象I5=bwareaopen(I4,2000);%去除聚团灰度值小于2000的部分figure(6),imshow(I5);title('remove the small objects'); %用imshow函数显示滤波后图像结果如下所示:7.车牌定位[y,x,z]=size(I5);%返回I5各维的尺寸,存储在x,y,z中myI=double(I5);%将I5转换成双精度tic %tic表示计时的开始,toc表示计时的结束Blue_y=zeros(y,1);%产生一个y*1的零阵for i=1:yfor j=1:xif(myI(i,j,1)==1)Blue_y(i,1)=Blue_y(i,1)+1;%蓝色像素点统计endendend[temp MaxY]=max(Blue_y);%Y方向车牌区域确定PY1=MaxY;while ((Blue_y(PY1,1)>=5)&&(PY1>1))PY1=PY1-1;endPY2=MaxY;while ((Blue_y(PY2,1)>=5)&&(PY2<y))PY2=PY2+1;endIY=I(PY1:PY2,:,:);Blue_x=zeros(1,x);%进一步确定x方向的车牌区域for j=1:xfor i=PY1:PY2if(myI(i,j,1)==1)Blue_x(1,j)=Blue_x(1,j)+1;endendendPX1=1;while ((Blue_x(1,PX1)<3)&&(PX1<x))PX1=PX1+1;endPX2=x;while ((Blue_x(1,PX2)<3)&&(PX2>PX1))PX2=PX2-1;endPX1=PX1-1;%对车牌区域的校正PX2=PX2+1;dw=I(PY1:PY2-8,PX1:PX2,:);t=toc;figure(7),subplot(1,2,1),imshow(IY),title ('Line direction areas'); figure(7),subplot(1,2,2),imshow(dw),title ('positioning color images');8.字符分割与识别对分割出的彩色车牌图像进行灰度转换、二值化、均值滤波、腐蚀膨胀以及字符分割以从车牌图像中分离出组成车牌号码的单个字符图像,对分割出来的字符进行预处理(二值化、归一化),然后分析提取,对分割出的字符图像进行识别给出文本形式的车牌号码。
基于opencv的车牌识别的代码
![基于opencv的车牌识别的代码](https://img.taocdn.com/s3/m/40d456aa7d1cfad6195f312b3169a4517723e5c8.png)
基于opencv的车牌识别的代码车牌识别技术在现代交通管理、智能停车场等领域有着广泛的应用。
而基于 OpenCV 实现车牌识别是一种常见且有效的方法。
下面我们就来详细探讨一下实现车牌识别的代码逻辑和关键步骤。
首先,在开始编写代码之前,我们需要确保已经安装好了 OpenCV库以及相关的依赖项。
接下来,我们逐步分解车牌识别的主要流程。
第一步,图像采集。
这可以通过摄像头实时获取图像,或者读取已经存在的图片文件。
```pythonimport cv2从摄像头获取图像cap = cv2VideoCapture(0)或者读取图片文件image = cv2imread('platejpg')```第二步,图像预处理。
这一步的目的是提高图像质量,以便后续的处理。
常见的操作包括灰度化、高斯模糊去噪、边缘检测等。
```python灰度化gray_image = cv2cvtColor(image, cv2COLOR_BGR2GRAY)高斯模糊blurred_image = cv2GaussianBlur(gray_image, (5, 5), 0)Canny 边缘检测edges = cv2Canny(blurred_image, 50, 150)```第三步,车牌定位。
这是整个车牌识别中最关键的步骤之一。
通常会利用车牌的形状、颜色、纹理等特征来定位车牌。
```python寻找轮廓contours, _= cv2findContours(edges, cv2RETR_EXTERNAL,cv2CHAIN_APPROX_SIMPLE)for contour in contours:计算轮廓的面积和周长area = cv2contourArea(contour)perimeter = cv2arcLength(contour, True)根据面积和周长等条件筛选出可能的车牌区域if area > 1000 and perimeter > 300:获取车牌区域的矩形边界x, y, w, h = cv2boundingRect(contour)提取车牌区域plate_image = imagey:y + h, x:x + w```第四步,字符分割。
python 对车牌字母o与i的处理
![python 对车牌字母o与i的处理](https://img.taocdn.com/s3/m/b6b382193a3567ec102de2bd960590c69fc3d86f.png)
1. 起因近年来,随着城市交通的日益繁忙和车辆管理的越来越严格,车牌识别技术变得愈发重要。
然而,由于字母 o 与 i 在车牌上非常相似,这给车牌识别系统带来了一定的挑战。
2. 问题分析a. o 与 0:在某些字体中,字母 o 和数字 0 的形状非常相似,容易混淆。
b. i 与 1:同样地,字母 i 和数字 1 在某些情况下也难以区分。
3. 解决方案针对这一问题,研究人员提出了一些解决方案,其中 Python 作为一种强大的编程语言,在处理车牌识别中的 o 与 i 问题上发挥了重要作用。
4. 图像处理a. 利用 Python 的图像处理库,可以对车牌图像进行预处理,包括灰度化、边缘检测、二值化等操作,以便更好地识别 o 与 i。
b. 通过调整图像的对比度、亮度等参数,可以进一步凸显 o 和 i 的区别,有助于车牌识别系统的准确识别。
5. 字符识别a. 基于Python 的机器学习和深度学习库,可以构建字符识别模型,对车牌中的 o 和 i 进行分类识别。
b. 通过大量的训练数据和精心设计的神经网络结构,可以提高字符识别的准确率,从而避免 o 和 i 的混淆。
6. 文字处理a. 利用 Python 的文本处理库,可以对车牌识别结果进行进一步的处理和纠正。
b. 通过匹配车牌号与车辆信息数据库中的记录,可以对识别结果进行验证和修正,从而排除 o 与 i 的歧义。
7. 结语Python 在处理车牌识别中的 o 与 i 问题上发挥了巨大的作用,为提高车辆管理效率和城市交通安全贡献了力量。
相信随着技术的不断进步,我们将能够更好地应对车牌识别中的各种挑战。
8. 深度学习在字符识别中的应用近年来,深度学习技术在字符识别领域取得了巨大的突破,而Python作为一种强大的编程语言,为深度学习模型的构建和训练提供了便利。
通过深度学习,我们可以构建端到端的车牌识别系统,从而更加准确地区分车牌中的 o 和 i。
深度学习模型可以通过多层神经网络来学习输入图像的特征,并进行字符的分类识别。
车牌识别matlab代码
![车牌识别matlab代码](https://img.taocdn.com/s3/m/0410f5e7e009581b6bd9eb60.png)
close allclc[fn,pn,fi]=uigetfile('ChePaiKu\*.jpg','选择图片');YuanShi=imread([pn fn]);%输入原始图像figure(1);subplot(3,2,1),imshow(YuanShi),title('原始图像');%%%%%%%%%%1、图像预处理%%%%%%%%%%%YuanShiHuiDu=rgb2gray(YuanShi);%转化为灰度图像subplot(3,2,2),imshow(YuanShiHuiDu),title('灰度图像');BianYuan=edge(YuanShiHuiDu,'robert',0.09,'both');%Robert算子边缘检测subplot(3,2,3),imshow(BianYuan),title('Robert算子边缘检测后图像');se1=[1;1;1]; %线型结构元素FuShi=imerode(BianYuan,se1); %腐蚀图像subplot(3,2,4),imshow(FuShi),title('腐蚀后边缘图像');se2=strel('rectangle',[30,30]); %矩形结构元素TianChong=imclose(FuShi,se2);%图像聚类、填充图像subplot(3,2,5),imshow(TianChong),title('填充后图像');YuanShiLvBo=bwareaopen(TianChong,2000);%从对象中移除面积小于2000的小对象figure(2);subplot(2,2,1),imshow(YuanShiLvBo),title('形态滤波后图像');%%%%%%%%%%2、车牌定位%%%%%%%%%%%[y,x]=size(YuanShiLvBo);%size函数将数组的行数返回到第一个输出变量,将数组的列数返回到第二个输出变量YuCuDingWei=double(YuanShiLvBo);%%%%%%%%%%2.1、车牌粗定位之一确定行的起始位置和终止位置%%%%%%%%%%%Y1=zeros(y,1);%产生y行1列全零数组for i=1:yfor j=1:xif(YuCuDingWei(i,j)==1)Y1(i,1)= Y1(i,1)+1;%白色像素点统计endendend[temp,MaxY]=max(Y1);%Y方向车牌区域确定。
数字图像处理车牌识别课程设计matlab实现附源代码
![数字图像处理车牌识别课程设计matlab实现附源代码](https://img.taocdn.com/s3/m/82d8d2e35ef7ba0d4a733b52.png)
精品实验项目字符识别预处理的设计与实现专业:电子信息工程*名:**学号:**********指导老师:***目录一、实验类型:设计性实验 (3)二、实验目的 (3)三、实验设备:扫描仪、安装有MATLAB软件的计算机 (3)四、实验内容及原理 (3)(1)字符图像的获取 (3)(2)字符图像预处理 (3)(3)字符图像分割 (3)(4)函数的作用 (4)五、实验步骤 (8)1.载入车牌图像: (8)2.将彩图转换为灰度图并绘制直方图: (9)3. 用roberts算子进行边缘检测: (10)4.图像实施腐蚀操作: (10)5.平滑图像 (11)6. 删除二值图像的小对象 (12)7.车牌定位 (12)8.字符分割与识别 (14)9.车牌识别: (20)六、思考题 (27)一、实验类型:设计性实验二、实验目的1. 掌握图像的获取、预处理和分割的原理及MATLAB实现方法。
2. 掌握使用扫描仪和计算机获取数字图像的方法,理解扫描仪的原理。
3. 自学一种字符图像的分割算法并用MA TLAB编程实现该算法。
三、实验设备:扫描仪、安装有MATLAB软件的计算机四、实验内容及原理(1)字符图像的获取用扫描仪获取图像是字符图像处理常用的数字化过程的方法之一。
以办公设备中常用的台式扫描仪为例,其主要性能指标有x、y方向的分辨率、色彩分辨率(色彩位数)、扫描幅面和接口方式等,这些指标都可以从扫描仪的说明手册中获得。
分辨率的单位是dpi(Dot Per Inch),意思是每英寸的像素点数。
扫描仪工作时,首先由可移动带状光源将光线照在欲输入的图稿上,并沿y方向扫描稿件,产生表示图像特征的反射光或透射光。
照射到原稿上的光线经反射后穿过一个很窄的缝隙,形成沿x方向的光带,经光学系统采集和过滤成RGB三色光带分别照射到RGB分量的CCD上,CCD将光信号转换为模拟电信号。
内部电路的A/D变换器将模拟电信号转变为数字电子信号输送给计算机。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
//if ( l <= t )
//每列
for ( j = 0; j < nWidth; j++ )//(逻辑上的)
{
pos[i][j] = 0;
*lpSrc++;
*lpSrc++;
*lpSrc++;
if ( l <= lmax )
{
l = j - col_s[i];
if ( r[i] != 0 )
lr_proportion = (float)l/(float)r[i];
*lpSrc++;
}
dwBaseIndex += OneLineBytes;
}
FirstColFlag = false;
r[i] = 0;
col_s[i] = 0;
//每列
if ( pixel == 255 )
{
sum++;
if ( FirstColFlag == true )
{
//每行允许的最小跳变点间距(以车牌宽度为参考,略大)
//const int xt = 120;
const int lmin = 120;
//每行起始点和终止点之间允许的最小跳变点数
else
lr_proportion = 65535;
//如果该点是跳变点
//每行的起始点和终止点之间的跳变点数
int r[1000];
//找到每行起始点的标志符
bool FirstColFlag;
//当前点到起始点的距离
int l;
pos[i][j] = 1;
jump_col[i]++;
}
{// 该函数处理的是32位图,lpbyBits32是指向32位图图像数据的指针
//第一步, 进行参数合法性检测
ASSERT(lpbyBits32);
if((x > (nScanWidth - 1)) || (y > (nScanHeight - 1))) return FALSE;
车牌识别字符识别源代码
部分代码如下:
bool CImageLocation::LocateMark(LPBYTE lpbyBits32, int x, int y, int nWidth, int nHeight, int nScanWidth, int nScanHeight, LPRECT p_markRect)
//像素值
pixel = (BYTE)*lpSrc;
//如果该点是跳变点
/* int sum = 0;
float ave = 0;
//每个跳变点的位置, 二维数组大小与图像对应
int pos[82][884];
//每行跳变点的数量
int jump_col[250];
for ( j = 0; j < nWidth; j++ )//(逻辑上的)
{
//像素值
pixel = (BYTE)*lpSrc;
//当前点到起始点的距离超过多少时开始比较比值
const int l_max = 100;
//当前点到起始点的距离与跳变点数量的比值
float lr_proportion;
//当前点到起始点的距离与跳变点数量的比值的范围
//是从纵向来确定车牌区域可能处于的列范围, 并为下一步车牌区域行范围的确定提供依据
//每行
for ( i = 0; i < nHeight; i++ )//(逻辑上的)
{
lpSrc = lpbyBits32 + dwBaseIndex;
int black = 0;
//连续黑点的最大数目, 即相邻两个跳变点之间的最大距离
const int black_max = 50;
dwBaseIndex = 0;
//第一次全图扫描的输出是每行可能的起始点和终止点, 以及起始点和终止点之间的跳变点数量
if ( pixel == 255 )
{
//如果已找到该行的起始点
long OneLineBytes = (long)nWidth * 4;
//开始数据基索引
DWORD dwBaseIndex = y * OneLineBytes + 4 * x;
//有效区域的宽度和高度
ave = (float)sum / (float)nHeight;*/
//每行允许的最大跳变点间距(以车牌宽度为参考,略大)
//const int t = 250;
const int lmax = 250;
int w = min(nWidth, nScanWidth - x);
int h = min(nHeight, nScanHeight - y);
if(w * h == 0) return FALSE;
//调试功能
for ( i = 0; i < nHeight; i++ )//(逻辑上的)
{
lpSrc = lpbyBits32 + dwBaseIndex;
jump_col[i] = 0;
const float lr_p_min = (float)3.9;
const float lr_p_max = (float)13.0;
//连续黑点的数目, 实际上是相邻两个跳变点的距离
//(应设为车牌区域每行左端到右端的跳变点数的平均数,有待探索)
const int m = 13;
//每行可能的起始点和终止点(假设图像高度不超过1000行, 每行都有)
int col_s[1000], col_e[1000];
//循环变量
long i, j;
//像素值
BYTE pixel;
//图像数据索引
BYTE* lpSrc;
ห้องสมุดไป่ตู้ //图像每行的字节数