Matlab表格识别

输入纸质表格,输出excel文件
主程序输入I=imread(‘文件名’)的图片,I1为矩阵,再使用xlwrite(‘文件名’,I1),得到excel文件。
需要预先训练好一个CNN网络(看matlab深度学习帮助文档),保存为et.mat。
效果
在这里插入图片描述

%主程序 excel_id.m
function I1=excel_id(I)
global fi;
fi=0;
load 'et.mat';%加载CNN

I=cutall(I);%变黑白,去除空白
for i=1:10
    if length(I)<=400
    break;
    end
I=imresize(I,0.9);%缩小图片
end
PA=cutline3(I);%分割成一个个单元格
[y,x]=size(PA);

for i=1:x
    for j=1:y
        PA2 = num_cut2(suo2(PA{j,i}));%提取一个个字符
        sum=calcu(PA2,et);%识别字符,连起来
        output{j,i}=sum;%保存结果
    end
end
I1=output;
end

%去除空白部分
function T = cutall(I)
I=im2bw(I,0.43);%变黑白
[y, x]=size(I);
y2=floor(y/2);x2=floor(x/2);%定位四个点,提取表格主要部分
for i=1:x
    if I(y2,i)==0
        cut11=i;
        break
    end
end
for i=1:x
    if I(y2,x+1-i)==0
        cut12=x+1-i;
        break
    end
end        
for j=1:y
    if I(j,x2)==0
        cut21=j;
        break
    end
end        
for j=1:y
    if I(y+1-j,x2)==0
        cut22=y+1-j;
        break
    end
end       
T=I(cut21:cut22,cut11:cut12);
end

%分割成一个个单元格
function PA = cutline4(I)
%I=imread('49-3-BW01.jpg');
[y, x]=size(I);
p=sum(I);
I1=I';
q=sum(I1);%计算水平和垂直投影
signnew=1;sign=1;
for i=floor(0.05*x):floor(0.95*x)
    if((i-signnew)>floor(0.05*x))
        if p(i) <= 0.4*y 
            sign=[sign i];%记录符合的点
            signnew=i;
        end
    end
end          
   sign=[sign x]; 
[H11,W11]=size(sign);
signnew2=1;sign2=1;
for j=floor(0.05*y):floor(0.95*y)
    if((j-signnew2)>floor(0.05*y))
        if q(j) <= 0.4*x 
           sign2=[sign2 j];%记录符合的点
            signnew2=j;
        end
    end
end
sign2=[sign2 y];
[H22,W22]=size(sign2);
PA=cell(W22-1,W11-1);
se=strel('square',2);
I=imerode(I,se);
I=qubiankuang(I);%去边框
for i=1:(W11-1)
for j=1:(W22-1)
    PA{j,i}=I(sign2(1,j):sign2(1,j+1),sign(1,i):sign(1,i+1));%分割
    end
end
end

%去除边框
function I1=qubiankuang(I)
I=im2bw(I);
I1=imcomplement(I);
[ L, num]=bwlabel(I1,8);%连通域标记
x=find(L==1);%找出边框所在位置
for i=x
    I1(i)=0;%去除边框
end
I1=imcomplement(I1);
end

%剪去边缘
function s=suo2(Img)
[y, x]=size(Img);
s4=floor(0.95*y);
s3=ceil(0.1*y);
s2=floor(0.95*x);
s1=ceil(0.01*x);%减去边缘

Img=Img(s3:s4,s1:s2);
s=Img;
end

%分离出一个个字符
function PA2 = num_cut2(Img)
global fi;
Img=im2uint8(Img);
[y, x]=size(Img);
[~,~,c]=size(Img);
if  c==1
    f2= ~im2bw(Img);
else 
    Img=rgb2gray(Img);
    f2= ~im2bw(Img);
end
f=f2;
f=bwareaopen(f,50);
str=strel('square',2);
 f=imdilate(f,str);
fi=fi+1;figure(fi);
imshow(f);
[L,num] = bwlabel(f,8);%标注二进制图像中已连接的部分
Feastats = regionprops(L,'basic');%计算图像区域的特征尺寸
Area=[Feastats.Area];%区域面积
b=[Feastats.BoundingBox];%[x y width height]字符的大小
sub=cell(1,num);%存储分割后的图像

fi=fi+1;figure(fi);
%分割过程
for i=1:num
    a=floor(b((i-1)*4+2));%b中字符的特性是按4个一组放的,前两个为左上顶点坐标,后两个为长宽。
     if a==0
         a=1;
    end
    e=b((i-1)*4+4);
    d=floor(b((i-1)*4+1));

     if d==0
         d=1;
     end
    g=b((i-1)*4+3);
   if( g<=0.8*x && e<=0.95*y)
    sub{1,i}=f2(a:a+e,d:d+g);%取出字符块
     subplot(1,num,i);imshow(sub{1,i});
   end
end
hold on
for k=1:num
    [r,c]=find(L==k);
    rbar=mean(r);
    cbar=mean(c);    plot(cbar,rbar,'Marker','o','MarkerEdgeColor','k','MarkerFaceColor','k','MarkerSize',10);    plot(cbar,rbar,'Marker','*','MarkerEdgecolor','w');
end
PA2=sub;
end

%对每个单元格识别出结果
function num = calcu(PA2,net)
[y,x]=size(PA2);
y1m=1;
for i=1:x
    [y1,x1]=size(PA2{1,i});
    if y1>y1m
        y1m=y1;%计算最大字符高度
    end
end
n=0;si=[];
for i=1:x
    [y1,x1]=size(PA2{1,i});
    if(y1 > floor(0.3*y1m))%防止过小的物体被当做字符
       n=n+1;
       si=[si i];
    end
end
PA3=cell(1,n);
for i=1:n
        PA3{1,i}=PA2{1,si(i)};
    end
 PA2=PA3;
 [y,x]=size(PA2);
sum=[];
for i=1:x
    imin=Tresize(PA2{1,i});%缩放图片使其符合CNN输入尺寸
   pred=classify(net,imin);%识别
   N=char(pred);
   sum=[sum N];%保存结果
end
num=sum;
end

%缩放图片使其符合CNN输入
function T = Tresize(T1)
T=imcomplement(T1);
[y, x]=size(T);
AD=ones(floor(0.1*y),x);
T=[AD; T; AD];
[y, x]=size(T);
AD=ones(y,floor((y-x)/3));
T=[AD T AD];%增添空白区域使其符合输入
T=imresize(T,[16 16]);%缩放
T=im2uint8(T);
end
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值