MATLAB身份证号码识别的代码

%身份证识别程序。识别身份证上面的身份证号码,并且单独提取出来,形成一副仅剩身份证号码的二值区域图像

clc;

clear all;

close all;

A=imread('E:\张强\matlab程序调试2015\matlab程序调试~网上例子\id_indentification_pic.jpg');  %读入图像

I1=rgb2gray(A);      %灰度处理,自动取值二值化

level=graythresh(I1);  

I2=im2bw(I1,level);

I3=~I2;

figure;

imshow(I3);

I4=bwareaopen(I3,25); %去除小面积区域(降噪)

I=~I4;

% figure;

% imshow(I4);

[y x]=size(I);   %先确定身份证号码所在的大概区域(身份证号码都在身份证的右下角)

A2=imcrop(I,[x/3 y/2 2*x/3 y/2]);

% figure;

% imshow(A2);

se = strel('square',40);  %进行开运算,使图像形成几个连通域

bw= imopen(A2,se);

% figure;

% imshow(bw);

%%%%%%寻找连通域的边缘,并且把每个连通域的边界画出来

[B,L] = bwboundaries(bw,4);     %使用了函数bwboundaries

figure;

imshow(label2rgb(L, @jet, [.5 .5 .5]));%label2rgb 把标签矩阵转化为彩色图像

hold on ;

for k = 1:length(B)

 boundary = B{k};

 plot(boundary(:,2),boundary(:,1),'r','LineWidth',2);  %将物体的边界画出来

end

% 找到每个连通域的质心及面积

stats = regionprops(L,'Area','Centroid');    

%%%%%% 循环历遍每个连通域的边界,得到匹配度特征范围内的物体(即截出身份证号码的位置图片)

for k = 1:length(B)

  boundary = B{k};% 获取一条边界上的所有点

  delta_sq = diff(boundary).^2;  % 计算边界周长  

  perimeter = sum(sqrt(sum(delta_sq,2)));% 计算边界周长  

  area = stats(k).Area;  % 获取边界所围面积

  metric =80*area/perimeter^2; % 计算匹配度

  

  % 要显示的匹配度字串

  metric_string = sprintf('%2.2f',metric);    %在图上显示字符串(匹配度的值)

  

  %%%%%% 标记出匹配度接近1的连通域(只有匹配度在0.8与1.1之间的连通域才画出来)

  if metric >= 0.8 && metric <= 1.1

    centroid = stats(k).Centroid;

    plot(centroid(1),centroid(2),'ko'); %将对应的质心画出来

    % 提取该连通域所对应在二值图像中的矩形区域

    goalboundary = boundary;

    s = min(goalboundary, [], 1);    %%%怎么有两个参数

    e = max(goalboundary, [], 1);

    

  %将目标区域分别向两侧延伸7个像素

  goal = imcrop(A2,[s(2)-7 s(1) e(2)-s(2)+14 e(1)-s(1)]);

  end

  % 显示匹配度字串

  text(boundary(1,2)-35,boundary(1,1)+13,...

    metric_string,'Color','g',...

'FontSize',14,'FontWeight','bold');

end

goal = ~goal;   %将目标区域进行反处理

figure,imshow(goal)

%%%%将18个字符单独一一截取出来,并且显示在同一个figure中

%求出目标区域的长度,并且求出等分为18个字符之后的长度

cs=size(goal,2);   

sz=cs/18;   

%定义变量t1、t2,分别为每个切割的起点和终点,以及它们的计算方法

t1=(0:17)*sz+1;

t2=(1:18)*sz;

%%%%将字符单独切割出来,并且显示在同一个figure中

figure;

k=0;

%将目标区域从左至右开始切割提取(对每一个单一的字符块做相应处理(对应字符块的矩阵做相应处理))

for i=1:18        %每个身份证上的身份证号码都有18个字符

%     temp=goal(:,t1(i):t2(i), :);

    temp=goal(:,t1(i):t2(i));

    temp=bwareaopen(temp,20); %对切割后的图像做降噪处理(去除小面积区域)

    temp=id_identification_qiege(temp);    %调用自己编写的子函数(对图像进一步处理,去除每个字符周围的全零行)

    temp=imresize(temp,[30,20]);  %对temp进行缩放,缩放到指定[30,20]的尺寸。指定宽度和高度

    k=k+1;

    subplot(1,18,k);  %在一个窗口同时显示最后得到的字符

    imshow(temp);

end

自己编写的子函数

%定义函数功能切割

function e=id_identification_qiege(d)

[m,n]=size(d);  %确定图像大小

top=1;bottom=m;left=1;right=n; %初始定义top bottom left right

%从第一行开始,自上而下,如果此行的和为0且top<=m ,则top自加一

%当不全是零的时候结束

while sum(d(top,:))==0 && top<=m  

    top=top+1;

end

%从最后一行开始,自下而上,如果此行的和为0且bottom>=1,则bottom自减一

%当不全是零的时候结束

while sum(d(bottom,:))==0 && bottom>=1

    bottom=bottom-1;

end

%从第一列开始,自左而右,如果此行的和为0且left<=n,则left自加一

%当不全是零的时候结束

while sum(d(:,left))==0 && left<=n

    left=left+1;

end

%从最后一列开始,自右而左,如果此行的和为0且left<=n,则right自减一

%当不全是零的时候结束

while sum(d(:,right))==0 && left<=n

    right=right-1;

end

%确定切割范围

dd=right-left;

hh=bottom-top;

e=imcrop(d,[left top dd hh]);

  • 6
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值