matlab实现MSER(最大极值稳定区域)来进行文本定位

1、天然场景文本定位综述    算法

     场景图像中文本占据的范围通常都较小,图像中存在着大范围的非文本区域。所以,场景图像文本定位做为一个独立步骤愈来愈受到重视。这包括从最早的CD和杂志封面文本定位到智能交通系统中的车牌定位、视频中的字幕提取,再到限制条件少,复杂背景下的场景文本定位。与此同时文本定位算法的鲁棒性愈来愈高,适用的范围也愈来愈普遍。文本定位的方式通常能够分为三种,基于连通域的、基于学习的和二者结合的方式。基于连通域的流程通常是首先提取候选文本区域,而后采用先验信息滤除部分非文本区域,最后根据候选文本字符间的关系构造文本词。基于学习的方式关键在于两个方面:一是不一样特征提取方法的使用如纹理、小波、笔画等。二是分类器的使用如支持向量机(Support Vector Machine,SVM),AdaBoost等。连通域和学习结合的方式通常在提取阶段采用连通域的方式,可是滤除阶段是经过训练样本学习分类器来实现非文本的滤除。函数

1. 基于连通域的方式学习

  连通域分析是在场景文本图像二值化后进行的,因此开始的研究集中在场景文本图像的预处理、加强和二值化上。基于连通域的方式不多须要在多尺度上进行操做,因此运算时间较快,但存在须要大量的先验信息来滤除文本区域的弊端。ui

2. 基于学习的方式spa

  基于学习的方式通常流程是先将图像分割成一个个窗口,提取窗口中图像的特征,而后利用一个训练好的分类器来将窗口分红文本和非文本,最后将文本区域连成一个文本行。基于学习的方式,计算量大,通常都在多尺度上处理,并且须要先准备好训练的数据来训练分类器。code

3. 连通域和学习结合的方式component

  这一方式通常都是分为两个阶段,阶段一是提取候选的连通区域,这个阶段通常采用的是连通域分析的方法。阶段二是文本区域和非文本区域的分类,这一阶段通常是采用分类器的方式实现的。二者结合的方式虽然没有众多的参数设置,但仍是没法摆脱训练数据的限制。视频

2、利用MSER来进行文本区域定位blog

  最大极值稳定区域是由Matas等人提出的一种仿射特征区域提取算法。其提取的区域内部灰度几乎不变可是和背景的对比十分强烈,而且该区域可以在多重阈值下保持形状不变。通常文本内部的灰度变化都比较小,而文本和背景的灰度对比度则比较大,符合最大极值稳定区域的特性,所以利用这一特性能够提取颜色聚类没法获得的部分连通域。索引

    最大极值稳定区域先将图像转换成灰度图像,而后在必定的阈值下将图像转换成一系列的二值图像。随着亮度阈值的增长或者减小,区域不断的出现、生长和合并。两个不一样阈值间的区域变化不超过必定阈值就可以被认为是稳定的。最大极值稳定区域的数学定义:定义图像 Eqn040为区域 Eqn041到灰度Eqn042 的映射Eqn043 ,其中 满Eqn044足全序结构。定义像素间的邻接关系Eqn045 。则图像中的区域 Eqn046可定义为图像上知足邻接关系的连通子集,即对于任意点 Eqn047,有下式成立

                  Eqn048(3.6)

其中 Eqn049。定义的Eqn050 边界Eqn051

                  Eqn052(3.7)

对于Eqn053Eqn054 ,有 Eqn055成立,则称 Eqn056为极大值区域,反之为极小值区域。对于一组相互嵌套的极值区域 Eqn057。若是其面积变化率

                    Eqn058(3.8)

Eqn059处取得局部最小值,则称 Eqn060为最大极值稳定区域。

在获得极值稳定区域后,经过将稳定区域赋值为1,将其他区域赋值为0就可以获得最大极值稳定区域的二值化模板。对二值化模板进行连通域分析,就获得了候选的连通域了。

3、利用matlab的detectMSERFeature来实现简单文本定位

1.处理流程

              image

  首先是输入一幅图像,想进行必要的预处理如灰度化,而后提取MSER区域(这里直接利用的是matlab自带的函数detectMSERFeature),而后将获得的区域转换成二值图像(主要是利用取得区域的坐标信息)。对获得的MSER区域二值图像进行连通域分析,先粗过滤一些明显不符合字符的区域,而后对过滤后的图像进行闭运算。闭运算以后再进行一次细滤除,最后获得包围文本区域的包围盒。先看几组效果,左边是原图,右边是定位后的图,绿色线画出来的区域,不是很明显。图是比较简单,说明这个方法仍是比较初级的,存在比较多的经验阈值。

imageimage

 

imageimage

 

二、源代码

代码仍是比较重要的,说了这么多,能运行出来的代码才是重点,不过只支持matlab2014及以上。

  整个主函数

%% 读取图片 [filename,pathname]=uigetfile('*.*','choose a picture'); path = [pathname filename]; colorImage = imread(path); figure;imshow(colorImage); %% mser区域提取 grayImage = rgb2gray(colorImage); mserRegions = detectMSERFeatures(grayImage); mserRegionsPixels = vertcat(cell2mat(mserRegions.PixelList)); %% 把mser区域的坐标系数取出来,而后将相应系数的地方赋值为真。取出mser区域。 mserMask = false(size(grayImage)); ind = sub2ind(size(mserMask), mserRegionsPixels(:,2), mserRegionsPixels(:,1)); mserMask(ind) = true; figure;imshow(mserMask); %% 粗滤除 [p_image,cwidth] =conComp_analysis(mserMask); figure;imshow(colorImage); wi= median(cwidth(:))/2; se1=strel('line',wi,0); p_image_dilate= imclose(p_image,se1); %% 细滤除 [rec_word,img_color,img_bw]=f_conComp_analysis(p_image_dilate,colorImage,p_image);

  其中的conComp_analysis函数,函数返回的是滤除掉非文本的二值图像和用于闭运算的候选值。这个函数主要是对输入的mserMask进行连通域分析,而后根据连通域的大小和高宽比,过滤掉一些非文本区域。同时为了不太多阈值设定和自适应,将每一个连通区域的宽记录在cwidth当中。

function [p_image,cwidth] =conComp_analysis(bwimg) [x,y]=size(bwimg); cwidth=[]; whole=x*y; connComp = bwconncomp(bwimg); % Find connected components threefeature = regionprops(connComp,'Area','BoundingBox','Centroid' ); broder=[threefeature.BoundingBox];%[x y width height]字符的区域 area=[threefeature.Area];%区域面积 centre=[threefeature.Centroid]; %%
for i=1:connComp.NumObjects leftx=broder((i-1)*4+1); lefty=broder((i-1)*4+2); width=broder((i-1)*4+3); height=broder((i-1)*4+4); cenx=floor(centre((i-1)*2+1)); ceny=floor(centre((i-1)*2+2)); if area(i)<80||area(i)>0.3*whole bwimg(connComp.PixelIdxList{i})=0; elseif width/height<0.1||width/height>2 bwimg(connComp.PixelIdxList{i})=0; else cwidth=[cwidth,width]; rectangle('Position',[leftx,lefty,width,height], 'EdgeColor','g'); end end p_image=bwimg;

  其中的f_conComp_analysis,这个函数就不细讲了,跟上面的相似。同时保存了彩色和灰度的文本词图像,为识别作进一步准备。

function [rec,seg_img_color,seg_img_bw] =f_conComp_analysis(P_image,colorImg,p_img) [x,y]=size(P_image); whole=x*y; j=1; rec=[]; connComp = bwconncomp(P_image); % Find connected components threefeature = regionprops(connComp,'Area','BoundingBox'); broder=[threefeature.BoundingBox];%[x y width height]字符的区域 area=[threefeature.Area];%区域面积 %%
for i=1:connComp.NumObjects leftx=floor(broder((i-1)*4+1)); lefty=floor(broder((i-1)*4+2)); width=broder((i-1)*4+3); height=broder((i-1)*4+4); %    data=grayimg_reserve(lefty:lefty+height-1,leftx:leftx+width-1); %    stda(i,:)=statxture(data); if area(i)<500||area(i)>whole*0.4 P_image(connComp.PixelIdxList{i})=0; elseif width/height<2 P_image(connComp.PixelIdxList{i})=0; %     elseif stda(i,4)<0 %     P_image(connComp.PixelIdxList{i})=0; else rect=[leftx,lefty,width,height]; rec=[rec;rect]; rectangle('Position',[leftx,lefty,width,height], 'EdgeColor','g'); seg_img_color{j}=colorImg(lefty+1:lefty+height,leftx+1:leftx+width,:); % +1 避免索引为0 seg_img_bw{j}=p_img(lefty+1:lefty+height,leftx+1:leftx+width); j=j+1; %         zone{1,j}.data=grayimg_reserve(lefty:lefty+height-1,leftx:leftx+width-1); %         zone{1,j}.location=[leftx,lefty,width,height]; %         zone{1,j}.label=j; %         j=j+1; end end pp_image=P_image;
相关文章
相关标签/搜索