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;
相關文章
相關標籤/搜索