基于MATLAB的图片中文字的提取及识别

基于 MATLAB 的图片中文字的提取及识别


摘要

随着现代社会的发展,信息的形式和数量正在迅猛增长。其中很大一部分是图像,图像可以把事物生动地呈现在我们面前,让我们更直观地接受信息。同时,计算机已经作为一种人们普遍使用的工具为人们的生产生活服务。从图像中提取文字属于信息智能化处理的前沿课题,是当前人工智能与模式识别领域中的研究热点。由于文字具有高级语义特征, 对图片内容的理解、索引、检索具有重要作用,因此,研究图片文字提取具有重要的实际意义。又由于静态图像文字提取是动态图像文字提取的基础,故着重介绍了静态图像文字提取技术。

关键词:MATLAB 图像处理 文字提取 文字识别




一.引言


v2-1f2ee62b8388864e0cfd4379386c9ace_b.jpg

随着计算机科学的飞速发展,以图像为主的多媒体信息迅速成为重要的信息传递媒介, 在图像中,文字信息(如新闻标题等字幕) 包含了丰富的高层语义信息,提取出这些文字, 对于图像高层语义的理解、索引和检索非常有帮助。图像文字提取又分为动态图像文字提取和静态图像文字提取两种,其中,静态图像文字提取是动态图像文字提取的基础,其应用范围更为广泛,对它的研究具有基础性,

所以本文主要讨论静态图像的文字提取技 术。静态图像中的文字可分成两大类: 一种是图像中场景本身包含的文字, 称为场景文字; 另一种是图像后期制作中加入的文字, 称为人工文字,如右图所示。场景文字由于其出现的位置、小、颜色和形态的随机性, 一般难于检测和提取;而人工文字则字体较规范、大小有一定的限度且易辨认,颜色为单色, 相对与前者更易被检测和提取,

又因其对图像内容起到说明总结的作用,故适合用来做图像的索引和检索关键字。对图像中场景文字的研究难度大,目前这方面的研究成果与文献也不是很丰富,本文主要讨论图像中人工文字提取技术。


二.静态图像中文字的特点


静态图像中文字(本文特指人工文字,下同)具有以下主要特征:

  1. 文字位于前端,且不会被遮挡;
  2. 文字一般是单色的;
  3. 文字大小在一幅图片中固定,并且宽度和高度大体相同,从满足人眼视觉感受的角度来说,图像中文字的尺寸既不会过大也不会过小;
  4. 文字的分布比较集中;
  5. 文字的排列一般为水平方向或垂直方向;
  6. 多行文字之间,以及单行内各个字之间存在不同于文字区域的空隙。在静态图片文字的检测与提取过程中, 一般情况下都是依据上述特征进行处理的。


三.文字提取、识别的一般流程


静态图像文字提取一般分为以下步骤:文字区域检测与定位、文字分割与文字提取、文字后处理。其流程如图1所示。


v2-c20692ac07950d1c52c41da24fb87b0e_b.jpg


(图1)


四.文字提取、识别的详细步骤

v2-d6af4a866ad1af8fe3b5ca07b33546ba_b.jpg

在Matlab中调用i1=imread('字符.jpg'),可得到原始图像,如图2所示:

(图2)


  1. 调用i2=rgb2gray(i1),则得到了灰度图像,如图3所示:


v2-a33ad22cb4211122a465ecabf90ad49a_b.jpg


(图3)


调用a=size(i1);b=size(i2);可得到:a=3,b=2 即三维图像变成了二维灰度图像



  1. 调用i3=(i2>=thresh);其中thresh为门限,在

i3  0, i2  thresh

1, i2  thresh


[0,255]之间



这里,i2_max=double(max(max(i2))); %获取亮度最大值i2_min=double(min(min(i2))); %获取亮度最小值thresh=round(i2_max-((i2_max-i2_min)/3));

得到二值图像,如图4所示:




v2-70a9b91b09b50d1ff302fb276022d194_b.jpg



(图4)


  1. 把二值图像放大观察,可看到离散的黑点


v2-b5f6befe7845598d0e45e56aa271c087_b.jpg

对其采用腐蚀膨胀处理,得到处理后的图像,如图5所示

(图5)


可见,腐蚀膨胀处理后的图像质量有了很大的改观。


v2-942726c34105f0b7bb24adea40348d0a_b.jpg

横向、纵向分别的腐蚀膨胀运算比横向、纵向同时的腐蚀膨胀运算好上很多,图6可看出差别:

(图6)


v2-f7f9628eb836a8f63425bebe1f064bd2_b.jpg

对腐蚀膨胀后的图像进行Y方向上的区域选定,限定区域后的图像如图7所示: 扫描方法:中间往两边扫


(图7)



v2-df1905ce45bfc83e464f19a7ee67dce9_b.jpg

纵向扫描后的图像与原图像的对照,如图8所示:

(图8)


v2-f9ffac1fd2b1bb2c4b3a140e7fe0fac1_b.jpg

对腐蚀膨胀后的图像进行X方向上的区域选定,限定区域后的图像如图9所示: 扫描方法:两边往中间扫

(图9)



v2-bca895ea46483fc332880ce9cbc898fb_b.jpg

纵向扫描后的图像与原图像的对照,如图10所示:

(图10)


  1. 调用i8=(iiXY~=1),使背景为黑色(0),字符为白色(1),便于后期处理。背景交换后的图像如图11所示:




v2-e542e8be34b19940f8903876625a3467_b.jpg



(图11)


  1. 调用自定义函数(字符获取函数)i9=getchar(i8),得到图像如图12所示:


v2-9e25ef745220e613d190145c64ab9055_b.jpg


(图9)


v2-3cf92786094658f3da303e32b75650ea_b.jpg

调用自定义的字符获取函数对图像进行字符切割,并把切割的字符装入一维阵列,切割过程如图12所示:

(图12)


  1. 调用以下代码,可将阵列word中的字符显示出来,如图13所示:

for j=1:cnum %cnum为统计的字符个数subplot(5,8,j),imshow(word{j}),title(int2str(j)); %显示字符

end




v2-56a202cb4f42a5182da68f587df3672f_b.jpg


(图13)



可以看到,字符宽度不一致


  1. 调用以下代码,将字符规格化,便于识别:

for j=1:cnum

word{j}=imresize(word{j},[40 40]); %字符规格化成40×40的

end


v2-80d080356f12caf2dcb140ce9c7b3e46_b.jpg

得到规格化之后的字符如图14所示:

(图14)


  1. 调用以下代码创建字符集:

code=char('由于作者水平有限书中难免存在缺点和疏漏之处恳请读批评指正,。');

将创建的字符集保存在一个文件夹里面,以供匹配时候调用,如图15所示:




v2-5477e2290f72963e49e018d852b38b92_b.jpg


(图15)


  1. 字符匹配采用模板匹配算法:将现有字符逐个与模板字符相减,认为相减误差最小的现有字符与该模板字符匹配。



假设:字符 A  

 0

1 0 0 1  1 1 1 1 1 0 0 1
0 0 1 0 1 1 1 1 0 1 1 0


1

 ,模板字符T  

1 0  1  0

0

 0

0 0 1  0 0

 ,模板字符T  

0  2 

0

 0

0 0 1

1 1 

0 0 1

0


sum(sum(abs( A T1)))  8, sum(sum(abs( A T 2)))  2

也就是说,字符A与模板字符T1 更相似,我们可以认为字符集中的字符T 2 就是字符A。经模板匹配,可得字符信息如下:

由于读者书评有限书中难免存在缺点和纰漏之处,恳请读者批评指正。


v2-1c83a450099211b0edfb52d8385cd499_b.jpg

效果如图16所示:

(图16)


  1. 调用以下代码,将字符放入newtxt.txt文本:


new=['newtxt','.txt']; c=fopen(new,'a+'); fprintf(c,'%s\n',Code(1:cnum)); fclose(c);


v2-22971b115954ef60280b4f0799b3d815_b.jpg

newtxt.txt文本内容如图17所示:

(图17)



参考文献

[1] 樊昀, 王润生.从图像中提取文字[J] .国防科技大学学报,2002,24 (1) :59-62.

  1. 王健,王晨.基于静态图片的文本提取技术的研究[J] .延边大学学报(自然科学版) , 2007,33 (2) :124-128.
  2. 夏莹,马少平,孙茂松等.计算机语言学方法在中文文字识别后处理中的应用[J] .中文信息,1996, (2) :50-51.
  3. 郑阿奇,曹戈,赵阳.MATLAB 实用教程[M].北京:电子工业出版社
  4. 程卫国,冯峰,姚东,徐听.MATLAB5.3 应用指南[M].北京:人民邮电出版社
  5. 陈杨.MATLAB 6.X图像编程与图像处理[M].西安:西安电子科技大学出版社



  1. 阮秋琦.数字图像处理[M].电子工业出版社,2001 年.
  2. 徐建华.图像处理与分析[M].科学出版社,1999 年.



附录

主程序源代码:

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%%

%%%%%%%%%%%%%%% 数字图象处理大作业 %%%%%%%%%%%%%%%%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%%

%————————图片中文字的提取及识别————————%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%%

tic

I=imread('字符.jpg'); %打开图片

%figure(1);imshow(I);title('原始图像','color','b');


I=rgb2gray(I); %RGB图片转化成灰度图像

%figure(2);imshow(I);title('灰度图像','color','b');


i_max=double(max(max(I))); %获取亮度最大值i_min=double(min(min(I))); %获取亮度最小值

thresh=round(i_max-((i_max-i_min)/3)); %计算灰度图像转化成二值图像的门限thresh I=(I>=thresh); %I为二值图像

%figure(3);imshow(I);title('二值图像','color','b');


seY=[1;1;1]; %构造结构元素I=imdilate(I,seY); %腐蚀图像I=imerode(I,seY); %膨胀图像seX=[1 1 1];

I=imdilate(I,seX); I=imerode(I,seX);

%figure(4);imshow(I);title('腐蚀膨胀后的图像','color','b');


ii=double(I);

[m,n]=size(ii); %获取图像大小信息

%确定文字区域

%纵向扫描countY=zeros(m,1); for i=1:m

for j=1:n

if ii(i,j)==0





end



end


end

countY(i,1)=countY(i,1)+1;


[maxY indexY]=max(countY); tempY1=indexY;

while (countY(tempY1,1)>3) && (tempY1>1) tempY1=tempY1-1;

end tempY2=indexY;

while (countY(tempY2,1)>3) && (tempY2<m) tempY2=tempY2+1;

end tempY1=tempY1-1; tempY2=tempY2+1;

iiY=I(tempY1:tempY2,:); %确定了Y方向上的文字区域

%figure(5);imshow(iiY);title('Y方向区域大致确定后的图像','color','b');


%横向扫描countX=zeros(1,n); for j=1:n

for i=tempY1:tempY2 if ii(i,j)==0

countX(1,j)=countX(1,j)+1;




end


end

end


tempX1=1;

while (countX(1,tempX1)<3) && (tempX1<n) tempX1=tempX1+1;

end tempX2=n;

while (countX(1,tempX2)<3) && (tempX2>1) tempX2=tempX2-1;

end tempX1=tempX1-1; tempX2=tempX2+1;

iiXY=iiY(:,tempX1:tempX2); %确定了整体的文字区域

%figure(6);imshow(iiXY);title('X、Y方向区域都大致确定后的图像','color','b');


ii=(iiXY~=1);%黑色背景,白色字体

%figure(7);imshow(ii);title('背景和文字交换颜色的图像','color','b'); ii=bwareaopen(ii,200); %删除面积小于200的杂质图像


%figure(8);imshow(ii);title('删除杂质干扰的图像','color','b');


myI=charslice(ii); %限定文字区域

%figure(9);imshow(ii);title('限定文字区域的图像','color','b');


y1=10;y2=0.25;flag=0;

maxnum=40;k=1; %maxnum为字符个数限定值,k用于统计实际字符个数word=cell(1,maxnum); %建立单元阵列,用于储存字符


figure(10)

while size(myI,2)>10 %当myI的长度小等于10,可确定没有字符了[word{k},myI]=getword(myI); %获取字符

k=k+1;


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%%%%%%%%%%


if k==2

subplot(5,1,1);imshow(myI);title('第一次切割后的图像','color','b');

end

if k==3

subplot(5,1,2);imshow(myI);title('第二次切割后的图像','color','b');

end

if k==5

subplot(5,1,3);imshow(myI);title('第四次切割后的图像','color','b');

end

if k==16

subplot(5,1,4);imshow(myI);title('第十五次切割后的图像','color','b');

end

end

subplot(5,1,5);imshow(myI);title('最后一次切割后的图像','color','b');

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%%%%%%%%%%%%%%


cnum=k-1; %实际字符总个数


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%%%%%%%%%%%%%%

figure(11); for j=1:cnum

subplot(5,8,j),imshow(word{j}),title(int2str(j)); %显示字符end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%%%%%%%%%%%%%%



for j=1:cnum

word{j}=imresize(word{j},[40 40]); %字符规格化成40×40的

end figure(12); for j=1:cnum

subplot(5,8,j),imshow(word{j}),title(int2str(j)); %显示字符end


for j=1:cnum

imwrite(word{j},[int2str(j),'.jpg']); %保存字符end


defx=40;defy=40;

code=char('由于作者水平有限书中难免存在缺点和疏漏之处恳请读批评指正,。');%创建字符集

codenum=size(code,2); %获取字符集中字符个数for i=1:cnum

ch=int2str(i); %数字转化为字符tempbw=imread([ch '.jpg']); %打开预匹配字符for k=1:codenum

fname=strcat('C:\Users\Administrator\Desktop\ 数字图像处理\ 字符匹配库

\',code(k),'.jpg'); %字符匹配库中的字符sample=imread(fname); subsam=abs(tempbw-sample); %作比较

count=sum(sum(subsam)); %匹配误差统计

err(k)=count;







end

end

figure(13); imshow(ii);

tt=title(['文字信息: ', Code(1:cnum)],'Color','b'); %显示字符信息set(tt,'fontsize',24); %设置字体

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%将图片文字写入newtxt文本new=['newtxt','.txt']; c=fopen(new,'a+'); fprintf(c,'%s\n',Code(1:cnum)); fclose(c);


t=toc


charslice(字符分割)函数源代码:

%字符分割

function y=charslice(ii) [m,n]=size(ii); top=1;bottom=m;left=1;right=n; while sum(ii(top,:))==0 && top<m

top=top+1;

end

ydiff=bottom-top; xdiff=right-left;

y=imcrop(ii,[left top xdiff ydiff]);


getword(字符获取)函数源代码:

%字符获取

function [word,result]=getword(ii) word=[];flag=0;y1=8;y2=0.5; while flag==0

[m,n]=size(ii); wide=0;

while sum(ii(:,wide+1))~=0 && wide<=n-2 wide=wide+1;

end

temp=charslice(imcrop(ii,[1 1 wide m])); [m1,n1]=size(temp);

if wide<y1 && n1/m1>y2 ii(:,1:wide)=0;

if sum(sum(ii))~=0

ii=charslice(ii); % 切割出最小范围

else word=[];flag=1; end


else


word=charslice(imcrop(ii,[1 1 wide m])); ii(:,1:wide)=0;








end






end

if sum(sum(ii))~=0; ii=charslice(ii); flag=1;

else ii=[]; end


result=ii;

猜你喜欢

转载自blog.csdn.net/TuTu998/article/details/120177055