matlab實現MSER(最大極值穩定區域)來進行文本定位

本博客轉載自http://www.cnblogs.com/dawnminghuang/p/4738108.html最終解釋權歸原作者所有,請尊重版權


一、自然場景文本定位綜述    

     場景圖像中文本佔據的範圍一般都較小,圖像中存在着大範圍的非文本區域。因此,場景圖像文本定位作爲一個獨立步驟越來越受到重視。這包括從最先的CD和雜誌封面文本定位到智能交通系統中的車牌定位、視頻中的字幕提取,再到限制條件少,複雜背景下的場景文本定位。與此同時文本定位算法的魯棒性越來越高,適用的範圍也越來越廣泛。文本定位的方式一般可以分爲三種,基於連通域的、基於學習的和兩者結合的方式。基於連通域的流程一般是首先提取候選文本區域,然後採用先驗信息濾除部分非文本區域,最後根據候選文本字符間的關係構造文本詞。基於學習的方式關鍵在於兩個方面:一是不同特徵提取方法的使用如紋理、小波、筆畫等。二是分類器的使用如支持向量機(Support Vector Machine,SVM),AdaBoost等。連通域和學習結合的方式一般在提取階段採用連通域的方式,但是濾除階段是通過訓練樣本學習分類器來實現非文本的濾除。

1. 基於連通域的方式

  連通域分析是在場景文本圖像二值化後進行的,所以開始的研究集中在場景文本圖像的預處理、增強和二值化上。基於連通域的方式很少需要在多尺度上進行操作,所以運算時間較快,但存在需要大量的先驗信息來濾除文本區域的弊端。

2. 基於學習的方式

  基於學習的方式一般流程是先將圖像分割成一個個窗口,提取窗口中圖像的特徵,然後利用一個訓練好的分類器來將窗口分成文本和非文本,最後將文本區域連成一個文本行。基於學習的方式,計算量大,一般都在多尺度上處理,而且需要先準備好訓練的數據來訓練分類器。

3. 連通域和學習結合的方式

  這一方式一般都是分爲兩個階段,階段一是提取候選的連通區域,這個階段一般採用的是連通域分析的方法。階段二是文本區域和非文本區域的分類,這一階段一般是採用分類器的方式實現的。兩者結合的方式雖然沒有衆多的參數設置,但還是無法擺脫訓練數據的限制。

二、利用MSER來進行文本區域定位

  最大極值穩定區域是由Matas等人提出的一種仿射特徵區域提取算法。其提取的區域內部灰度幾乎不變但是和背景的對比十分強烈,並且該區域能夠在多重閾值下保持形狀不變。一般文本內部的灰度變化都比較小,而文本和背景的灰度對比度則比較大,符合最大極值穩定區域的特性,因此利用這一特性可以提取顏色聚類無法得到的部分連通域。

    最大極值穩定區域先將圖像轉換成灰度圖像,然後在一定的閾值下將圖像轉換成一系列的二值圖像。隨着亮度閾值的增加或者減少,區域不斷的出現、生長和合並。兩個不同閾值間的區域變化不超過一定閾值就能夠被認爲是穩定的。最大極值穩定區域的數學定義:定義圖像 Eqn040爲區域 Eqn041到灰度Eqn042 的映射Eqn043 ,其中 滿Eqn044足全序結構。定義像素間的鄰接關係Eqn045 。則圖像中的區域 Eqn046可定義爲圖像上滿足鄰接關係的連通子集,即對於任意點 Eqn047,有下式成立

                  Eqn048(3.6)

其中 Eqn049。定義的Eqn050 邊界Eqn051 爲

                  Eqn052(3.7)

對於Eqn053 和Eqn054 ,有 Eqn055成立,則稱 Eqn056爲極大值區域,反之爲極小值區域。對於一組相互嵌套的極值區域 Eqn057。如果其面積變化率

                    Eqn058(3.8)

在 Eqn059處取得局部最小值,則稱 Eqn060爲最大極值穩定區域。

在得到極值穩定區域後,通過將穩定區域賦值爲1,將其餘區域賦值爲0就能夠得到最大極值穩定區域的二值化模板。對二值化模板進行連通域分析,就得到了候選的連通域了。

三、利用matlab的detectMSERFeature來實現簡單文本定位

1.處理流程

              image

  首先是輸入一幅圖像,想進行必要的預處理如灰度化,然後提取MSER區域(這裏直接利用的是matlab自帶的函數detectMSERFeature),然後將得到的區域轉換成二值圖像(主要是利用取得區域的座標信息)。對得到的MSER區域二值圖像進行連通域分析,先粗過濾一些明顯不符合字符的區域,然後對過濾後的圖像進行閉運算。閉運算之後再進行一次細濾除,最後得到包圍文本區域的包圍盒。先看幾組效果,左邊是原圖,右邊是定位後的圖,綠色線畫出來的區域,不是很明顯。圖是比較簡單,說明這個方法還是比較初級的,存在比較多的經驗閾值。

imageimage

 

imageimage

 

2、源代碼

代碼還是比較重要的,說了這麼多,能運行出來的代碼纔是重點,不過只支持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;
複製代碼

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章