基于matlab的文字识别算法

摘 要

   本课程设计主要运用MATLAB的仿真平台设计进行文字识别算法的设计与仿真。也就是用于实现文字识别算法的过程。从图像中提取文字属于信息智能化处理的前沿课题,是当前人工智能与模式识别领域中的研究热点。由于文字具有高级语义特征,对图片内容的理解、索引、检索具有重要作用,因此,研究图片文字提取具有重要的实际意义。又由于静态图像文字提取是动态图像文字提取的基础,故着重介绍了静态图像文字提取技术。随着计算机科学的飞速发展,以图像为主的多媒体信息迅速成为重要的信息传递媒介,在图像中,文字信息(如新闻标题等字幕)包含了丰富的高层语义信息,提取出这些文字,对于图像高层语义的理解、索引和检索非常有帮助。

 关键字:文字识别算法;静态图像文字提取;检索

目录

1 课程设计目的

2 课程设计要求

3 相关知识

4 课程设计分析

5 系统实现

6 系统测试与分析

6.1  文字识别算法仿真结果

6.2 基于字符及单词的识别

6.2.1 基于字符的识别

6.2.2 基于单词的识别

6.3  现存算法的问题

6.3.1 大多文字识别方法依赖于人工定义的特征

6.3.2 脱离上下文的字符识别易造成显著的歧义

6.3.3 简单的单词整体识别有着较大的局限性

6.3.4 训练样本制作繁琐

7 参考文献

1 课程设计目的

图像文字提取又分为动态图像文字提取和静态图像文字提取两种,其中,静态图像文字提取是动态图像文字提取的基础,其应用范围更为广泛,对它的研究具有基础性,所以本文主要讨论静态图像的文字提取技术。静态图像中的文字可分成两大类:一种是图像中场景本身包含的文字, 称为场景文字; 另一种是图像后期制作中加入的文字,称为人工文字,如右图所示。场景文字由于其出现的位置、小、颜色和形态的随机性,一般难于检测和提取;而人工文字则字体较规范、大小有一定的限度且易辨认,颜色为单色,相对与前者更易被检测和提取,又因其对图像内容起到说明总结的作用,故适合用来做图像的索引和检索关键字。对图像中场景文字的研究难度大,目前这方面的研究成果与文献也不是很丰富,本文主要讨论图像中人工文字提取技术。

静态图像中文字的特点

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

(1)文字位于前端,且不会被遮挡;

(2)文字一般是单色的;

(3)文字大小在一幅图片中固定,并且宽度和高度大体相同,从满足人眼视觉感受的角度来说,图像中文字的尺寸既不会过大也不会过小;

(4)文字的分布比较集中,排列一般为水平方向或垂直方向;

(6)多行文字之间,以及单行内各个字之间存在不同于文字区域的空隙。在静态图片文字的检测与提取过程中,一般情况下都是依据上述特征进行处理的。

数字图象处理

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

图1 静态文字处理流程图

2 课程设计要求

在高速发展的计算机软硬件技术的支撑下,多媒体技术的发展非常迅速,计算机技术从传统的办公和计算逐渐向人工智能和数字娱乐发展。在人工智能技术中,对环境信息的拾取处理和响应显得尤为重要,其中文本信息占环境信息很大一部分,为了使人工智能系统更为完善,则需要系统能够像人眼一样对周围环境信息进行理解,尤其是环境信息中的文本信息。

实验表明,人类日常生活中,50%以上的信息量来源于眼睛捕捉的周围环境的图像,人眼可以快速捕捉到图像中感兴趣的信息,而对于计算机来说,一幅图像仅仅是杂乱的数据,如何让计算机想人眼一样快速读取图像中的信息并进行分类及检索等相应处理,一直是多年来计算机视觉和模式识别研究者们探索的问题,如果能很好解决这些问题,能给工业生产及国防科技带来巨大的改进。文字是信息存储和传递的重要载体,在很多由摄像设备拍摄的图片中,都存在或多或少的文字,比如路牌、店名、车站牌、商品简介等,识别图片中的文字对计算机理解图像的整体内容有非常重大的作用。如何将图片中的文字信息抽象出来形成具有完整语义的信息,再将其表达出来用于信息传递,从而辅助人类的生产和生活是研究计算机视觉的学者们多年来一直致力于解决的问题。研究如何对自然场景图片中的字符进行识别,提取出有用信息,在获取图片文本信息的各个领域都有极大的商业价值。

场景文字识别在日常生活也有着重要的地位,例如车牌的识别,盲人对周边环境信息的获取、图书馆管理的数字化和髙效化,以及网络中对指定的内容的图像和视频的检索等。

自然场景文本识别,就是将提取出来的自然场景图片中的进行识别,提取出信息用于进一步的处理。在对场景文字识别的研究中,获取自然场景图片时候,由于背景物体、光线、阴影、拍摄角度引起的图片背景千变万化,摄像器材的精度、拍摄人员的技术等软硬件的不同为拍摄同样的自然场景图片也带来了相当大的差别,被拍摄的图片中包含的文字大小、颜色、书写风格的各不相同等因素都为自然场景文字识别的实现增加的相当的难度。需要对自然场景图片中的识别首先需要对图片中的文本进行定位,然后再对己经精确定位的图片进行识别。文本定位技术作为整个自然场景文本信息获取系统中的基础技术,已经得到较好发展,相同地,文本识别技术在近年来也得到了比较好的发展,但是由于文本的复杂性和随机性,较文本定位技术来说,文本识别技术发展较为缓慢。

3 相关知识

1. 在Matlab中调用i1=imread(‘8.jpg’),可得到原始图像,如图所示:

图2  文字识别算法调制器模型

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

图3 灰度图像

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

3. 调用i3=(i2》=thresh);其中thresh为门限,介于图4所示之间

图4  thresh门限值

图5 取得二值

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

图6 二值图像

4. 把二值图像放大观察,可看到离散的黑点 对其采用腐蚀膨胀处理,得到处理后的图像,如图所示

图7 腐蚀膨胀处理后的二值图像

可见,腐蚀膨胀处理后的图像质量有了很大的改观。横向、纵向分别的腐蚀膨胀运算比横向、纵向同时的腐蚀膨胀运算好上很多。

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

6、对腐蚀膨胀后的图像进行X方向上的区域选定,限定区域后的图像如图11所示: 扫描方法:两边往中间扫,纵向扫描后的图像与原图像的对照。

7. 调用i8=(iiXY~=1),使背景为黑色(0),字符为白色(1),便于后期处理。8. 调用自定义函数(字符获取函数)i9=getchar(i8)。

9、调用自定义的字符获取函数对图像进行字符切割,并把切割的字符装入一维阵列。

10.调用以下代码,可将阵列word中的字符显示出来。

for j=1:cnum %cnum为统计的字符个数

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

end

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

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

end

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

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

将创建的字符集保存在一个文件夹里面,以供匹配时候调用。

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

图8 字符匹配

也就是说,字符A与模板字符T1更相似,我们可以认为字符集中的字符T2就是字符A。经模板匹配。

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

new=[‘newtxt’,‘.txt’];

 c=fopen(new,‘a+’);

fprintf(c,‘%s
’,Code(1:cnum));

fclose(c);

4 课程设计分析

1、算法具有局限性。对于左右结构的字符(如:川)容易造成误识别,“川”字将会被识别成三部分。当图片中文字有一定倾斜角度时,这将造成识别困难。

2、模板匹配效率低。对于处理大小为m&TImes;m的字符,假设有n个模板字符,则识别一个字符至少需要m&TImes;m×n×2次运算,由于汉字有近万个,这将使得运算量十分巨大!此次字符识 别一共花了2.838秒。

3、伸缩范围比较小。对于受污染的图片,转换成二值图像将使字符与污染源混合在一起。对于具体的图片,需反复选择合适的thresh进行二值化处理,甚至在处理之前必须进行各种滤波。

5 系统实现

文字识别算法仿真代码如下:

function [Stroke]= StrDetect01(LeftD,Y1,Y2,ST,PT)

% ST为结构阈值,为了指定高度和宽度结构变化的不同

SL=0;

SR=0;

SV=0;

Count=0;

%PT=5;    % 突变的阈值

Str='T'; % T表示结构未定,Str用于保存当前的基本结构

Stroke='T'; % 用于保存基本结构

Range=Y2-Y1+1; % 字符的宽度或者高度

for j=Y1:Y2

    Count=Count+1;

    

    if (abs(LeftD(j))<PT)

           if (LeftD(j)<0)

                   SL=SL+1;

               else if (LeftD(j)>0)

                   SR=SR+1;

               else

                   SV=SV+1;

               end

           end

    else       % 检测到突变的决策

        if ((Count>=fix(Range/4)+1))   % 设定字符轮廓可能发生的突变范围

            if ((SL>=3)&&(SR>=3))

                  Str='C';

            else if ((SV>=2*(SL+SR))&&((max(SL,SR)<3)||(min(SL,SR)<2)))

                  Str='V';

               else if ((SL>SR)&&((SL>=0.5*SV)&&((SR<=1)||(SL>(SR+SV)))))

                       Str='L';

                     else if ((SR>SL)&&((SR>=0.5*SV)&&((SL<=1)||(SL>(SR+SV)))))

                              Str='R';

                              else if (max(SL,SR)>=3)&&(min(SL,SR)>=2)

                                  Str='C';

                              end

                          end

                     end

               end

           end

         Stroke=[Stroke Str];  

     end

         if ((j>=2+Y1)&&((j<=Y2-2)))

              Stroke=[Stroke 'P'];

         end     

        SL=0;

        SR=0;

        SV=0;

        Count=0;

        Str='T';

    end

end

%========= 提取结构 ===============%

if (Count>=fix(Range/4)+1) % 发生突变后,剩余部分可能无法形成字符结构

if ((SL>=ST)&&(SR>=ST))

    Str='C';

else if ((SV>=2*(SL+SR))&&((max(SL,SR)<3)||(min(SL,SR)<2)))

         Str='V';

     else if ((SL>SR)&&((SL>=0.5*SV)&&((SR<=2)||(SL>=(SR+SV)))))

              Str='L';

          else if ((SR>SL)&&((SR>=0.5*SV)&&((SL<=2)||(SL>=(SR+SV)))))

                   Str='R';

               else if (max(SL,SR)>=3)&&(min(SL,SR)>=2)

                        Str='C';

                    end     

               end

           end

       end

   end

Stroke=[Stroke Str];

function [Numeral]=Recognition(StrokeTop,StrokeLeft,StrokeRight,StrokeBottom,Comp)

% 采用四边的轮廓结构特征和笔划统计(仅针对 0 和 8)识别残缺数字

% Comp 是用于识别 0和8 的底部补充信息

StrT='T';

StrL='T';

StrR='T';

StrB='T';

RStr='T'; % 用于保存识别出的数字

[temp XT]=size(StrokeTop);

[temp XL]=size(StrokeLeft);

[temp XR]=size(StrokeRight);

%[temp XB]=size(StrokeBottom);

for Ti=2:XT

    if (StrokeTop(Ti)=='C')

        if ((XL==2)&&(XR==2))

             if ((Comp>=3)||((StrokeBottom(2)~='C')&&(StrokeLeft(2)=='C')&&(StrokeRight(2)=='C')))

                 RStr='8';

             else

                 RStr='0';

             end     

        else if ((StrokeLeft(XL)=='L')&&(StrokeLeft(XL-1)=='P')&&(StrokeLeft(2)~='C'))

                 RStr='2';

             else if ((StrokeLeft(2)=='C')&&(XL>=3)&&(StrokeLeft(3)=='P'))

                      RStr='9';

                  else if (XL>2)

                          for Li=2:XL

                              if (StrokeLeft(Li)=='P')

                                  RStr='3';

                              end

                          end

                      else if (XL==2)

                              for Ri=2:XR-1

                                  if (StrokeRight(Ri)=='P')

                                      RStr='6';

                                  end

                              end

                          end  

                      end  

                  end    

             end

         end     

    else if  (StrokeTop(Ti)=='V')  % Top

            if ((XR==2)&&(StrokeRight(2)=='C')) % 数字 3 右端只有一个结构

                RStr='3';       

            else if ((XR==2)&&((StrokeLeft(2)=='P')||(StrokeLeft(3)=='P')||(StrokeLeft(XL)=='V')))

                      RStr='7';

                  else if (XR>2)

                        for Ri=2:XR

                            if (StrokeRight(Ri)=='P')

                                RStr='5';

                            end

                        end

                        end

                  end

I0=imread('8.jpg');% 必须为二值图像

I=im2bw(I0,0.4);

[y0 x0]=size(I);

Range=sum((~I)');

Hy=0;

for j=1:y0

    if (Range(j)>=1)

        Hy=Hy+1;

    end

end

RangeX=sum((~I));

Wx=0;

for i=1:x0

    if (RangeX(i)>=1)

        Wx=Wx+1;

    end

end

Amp=24/Hy;             % 将文字图像归一化到24像素点的高度。

I=imresize(I,Amp);

[y x]=size(I);

%I=bwmorph(~I,'skel',Inf);

%I=~I;

tic

%====== 基本结构 =======%

% 第一类:竖(V);左斜(L);右斜(R);突变(P)

% 第二类:左半圆弧(C);右半圆弧(Q)

% 的三类:结构待定(T);

%=====================================%

Left=zeros(1,y);         % 左端轮廓检测

for j=1:y

        i=1;

    while ((i<=x)&&(I(j,i)==1))

        i=i+1;

    end

    if (i<=x)          

        Left(j)=i;

    end    

end

for j=1:y-1

    LeftD(j)=Left(j+1)-Left(j);

end

%========== 结构特征提取 =============%

j=1;

while ((Left(j)<1)&&(j<y))

       j=j+1;       

end

Y1=j;

j=y;

while ((Left(j)<1)&&(j>1))

       j=j-1;

end

Y2=j-1;      % 去掉急剧变化的两端

%============== 右边 ==================%

Right=zeros(1,y);         % 左端轮廓检测

for j=1:y

        i=x;

    while ((i>=1)&&(I(j,i)==1))

        i=i-1;

    end

    if (i>=1)          

        Right(j)=i;

    end    

end

for j=1:y-1

    RightD(j)=Right(j+1)-Right(j);

end

%=====================================%

Top=zeros(1,x);         % 顶端轮廓检测

for i=1:x

        j=1;

    while ((j<=y)&&(I(j,i)==1))

        j=j+1;

    end

    if (j<=y)          

        Top(i)=j;

    end    

end

for i=1:x-1

    TopD(i)=Top(i+1)-Top(i);

end

%==============================%

i=1;

while ((Top(i)<1)&&(i<x))

       i=i+1;       

end

X1=i;

i=x;

while ((Top(i)<1)&&(i>1))

       i=i-1;

end

X2=i-1;      % 去掉急剧变化的两端

%===================================%

Bottom=zeros(1,x);      % 底部轮廓检测

for i=1:x

        j=y;

    while ((j>=1)&&(I(j,i)==1))

        j=j-1;

    end

    if (j>=1)

        Bottom(i)=j;

    end    

end

for i=1:x-1

    BottomD(i)=Bottom(i+1)-Bottom(i);

end

%========== 数字 1 的宽度特征 =========%

Width=zeros(1,y);

for j=1:y

    Width(j)=Right(j)-Left(j);

end    

W=m

6 系统测试与分析

6.1  文字识别算法仿真结果

识别原图如图9(a)所示,仿真结果如图9(b)所示。

图9(a)识别原图

图9(b) 仿真结果

6.2 基于字符及单词的识别

6.2.1 基于字符的识别

Strokelets: A Learned Multi-scale Representation for Scene Text Recognition(CVPR 2014)通过聚类图像块来学习中层笔画特征,然后使用霍夫(HOG)投票算法检测字符。在笔画特征和HOG特征的基础上,使用随机森林分类器来进行字符分类。

End-to-end scene text recognition(2011)借鉴计算机视觉通用的目标检测方法,提出了一个新的文本识别系统。他们利用字符置信度以及字符之间的空间约束关系,给出最可能的检测和识别结果。但是该算法只能用于水平方向排列的文本的检测识别。

End-to-End Text Recognition with Hybrid HMM Maxout Models(2013)和PhotoOCR: Reading Text in Uncontrolled Conditions(2013)等人通过无监督的二分类技术或有监督的分类器,将单词图像分割为潜在的字符区域。

End-to-End Text Recognition with Hybrid HMM Maxout Models(2013)使用一种复杂的,包含分割、矫正以及字符识别的CNN网络,结合使用固定词典的隐马尔科夫模型(HMM),生成最终的识别结果。

PhotoOCR系统使用基于HOG特征的神经网络分类器,对分割得到的候选结果进行打分,使用结合N元语言模型(N-gram)的Beam搜索算法,得到候选字符集合。最后,再进一步使用语言模型和形状模型对候选字符组合进行重新排序。

Deep Features for Text Spotting(2014)结合了文本一非文本分类器、字符分类器、二元语言模型分类器,对整张图进行稠密的基于滑动窗口的扫描。最后结合固定词典,对图片中的单词进行分析。

 基于字符的识别技术依赖于使用字符分类器对图像进行逐字符识别,最终将识别得到的字符进行集成,得到图像中的整个单词。

6.2.2 基于单词的识别

Scene Text Recognition using Higher Order Language Priors以及Large-Lexicon Attribute-Consistent Text Recognition in Natural Images的工作依旧依赖于显式的字符分类器,但是通过构建一个图结构来推导整个单词。这会遇到和基于字符识别方法类似的困难。

Whole is Greater than Sum of Parts: Recognizing Scene Text Words(2013)使用整张文字图片来识别单词:他们使用基于梯度的特征图与预先制作好的单词图像进行对比,利用动态k近邻来判断当前图片所包含的单词。该方法依赖于一个固定词典以及预先生成的单词图片。

 Label embedding for text recognition(2013)使用集成的Fisher向量以及结构化的支持向量机框架来建立图片和整个单词编码的关系。

Word Spotting and Recognition with Embedded Attributes(2014)进一步探索了单词编码的概念,他们为图片和单词字符串创建了一个编码空间。这其实是Supervised mid-level features for word image representation(2014)方法的扩展:显式利用字符级别的训练数据来学习中间特征。

Multi-digit Number Recognition from Street View Imagery using Deep Convolutional Neural Networks(2013)等人使用深度CNN对整张图片进行编码,并使用多个位置敏感的字符级分类器来进行文字识别。他们在街景门牌号识别任务中取得了极大的成功。他们还将该模型应用到长达8位的验证码识别任务上,并使用了合成的训练数据对模型进行训练。该方法在goggle街景门牌号识别任务中获得了96%以上的识别率。同时还在对goggle验证码识别任务中获得了99%以上的识别率。

Synthetic Data and Artificial Neural Networks for Natural Scene Text Recognition(2014)和Reading Text in the Wild with Convolutional Neural Networks(2014)对上述模型做了细微变动:取消了预测字符长度的分类器,并引入了结束符表示文字结尾。他们随后证明了,使用合成的训练数据训练出的模型,能够成功应用到现实世界的识别问题中。将单词编码为向量是一种可行的词典单词识别方法,但是在无约束情况下,字符之间可以任意组合。当字符数量足够多时,基于固定长度向量编码的方法性能会显著下降。

但是依然存在一些不足:一些研究将深度学习技术用于单个字符的识别步骤中,但整体框架依旧遵循传统处理流程设计,因此在其它步骤中依旧会遇到绪论所述问题。Good fellow等人的研究使用纯神经网络直接完成整个识别流程,取

得了业界领先的成绩。但是由于他们需要使用固定大小的图像作为输入,并且将输入图像编码为固定长度的特征向量,在图片中字符较多的情况下,模型的识别精度会显著下降。另一方面,由于他们的模型没有对图片进行显式地字符定位和分割,因此无法得知每个字符在原图中所处位置。

6.3  现存算法的问题

6.3.1 大多文字识别方法依赖于人工定义的特征

虽然有大量工作研究如何定义一组好的文字特征,但是大部分实际应用的特征都不具有通用性。在极端情况下(如图10(a)),很多特征几乎无效或甚至无法提取,如笔画特征,形状特征,边缘特征等。另一方面,定义和提取人工特征也是一件极为耗时耗力的工作。

6.3.2 脱离上下文的字符识别易造成显著的歧义

基于字符的识别方法通常以字符为处理单位,通过分割或者滑动窗口搜索的方法,将单个字符进行分离。然后利用字符分类器来预测字符分类。然而,在复杂情况下,字符的分割非常困难,而强行分割则会破坏字符结构。另外,字符的识别需要上下文的参与,如图10(b)所示。该图中的单词为defence,若将d、f、 n分离后再进行字符识别,识别成功率会明显下降。

图10 极端情况下的文字识别

6.3.3 简单的单词整体识别有着较大的局限性

基于整个单词的识别方法直接从整幅图片中提取特征,然后进行识别。然而, 该类方法面可能临以下三个问题:

    a)难以应对无约束情况下的识别。多个字符的组合不一定形成字典中的单词,有很多时候,图像中的文字由随机字符组成(如产品型号、验证码、商标名称)。以单词为单位进行识别的方法无法应对此类情况。

    b)长字符串识别正确率显著下降。当字符数量增多时(如20个左右),图片的情况会变得更为复杂,一些整体识别方法的性能会显著下降。

    c)缺乏字符定位功能。很多时候,文字识别不仅仅需要了解图像中包含的 文字内容,还需要了解每个字符在原图中的位置。基于字符的识别方法天然带有字符定位功能。而有些整体识别的方法则缺失了此类性质。如 Good fellow等人的整体识别方法。

6.3.4 训练样本制作繁琐

不少算法的训练依赖于详细的训练样本标注结果:不仅需要知道每张训练样本中包含的文字,还需要知道每个文字所处的位置。有些算法还需要结合切分好的单字符训练样本、多字符训练样本。有些算法为了进行文字区域非文字区域检测,还需要制作包含文字的正例样本和反例样本。为了获得良好的机器学习效果,大部分的机器学习算法都要求尽量使用丰富、大量、贴近真实世界的样本进行训练。因此,对样本制作要求苛刻的识别算法会加大人工工作量,进而难以通用。