簡單驗證碼識別(matlab)
昨天晚上一個朋友給我發了一些驗證碼的圖片,希望能有一個自動識別的程序。

我看了看這些樣本,發現都是很規則的印刷體數字,而且還沒有角度旋轉,所以我就直接使用數字的面積和周長兩個特征量來進行檢測,發現效果還是蠻不錯的。
在實驗中,主要問題是‘6’和‘9’兩個數字的面積和周長都是完全一樣的,所以這時候我又添加了一個重心的特征。
有些蛋疼的是數字‘4’和‘0’竟然面積是一樣的。。。所以只好再引入橢圓離心率特征來判別。
圖像也沒有怎么預處理,就是簡單的閾值化,再使用ostu分割。
具體代碼如下
- d=dir('*.jpeg'); %讀jpeg文件
- %% 預設模板,每一行對應一個數字
- FD=[56,35.3137084989848,0.651415462867714;
- 45,41.6568542494924,0.928960924132855;
- 47,53.4558441227157,0.873324561446361;
- 54,57.4558441227157,0.842543936832893;
- 52,35.3137084989848,0.773979329527851;
- 57,56.9705627484771,0.828808732648540;
- 61,47.2132034355964,0.727827684501222;
- 35,41.5563491861041,0.892307587953152;
- 65,36.9705627484771,0.799839490167419;
- 61,47.2132034355964,0.727827684501222;
- ];
-
- for i=1:64
- Im=imread(d(i).name);
- I=rgb2gray(Im); %灰度化
- I(I>140)=255; %簡單閾值化,去除大面積背景干擾,這個再精細的話可以划分bins,將較大的bins過濾掉。
- level=graythresh(I);
- Ib=im2bw(I,level); %二值化
- cc=bwconncomp(~Ib); %尋找閉合區域
- L=labelmatrix(cc); %分配目標標簽
- area=regionprops(L,'Area'); %獲得目標面積
- area=[area(:).Area];
- perimeter=regionprops(L,'Perimeter'); %獲得目標周長
- perimeter=[perimeter(:).Perimeter];
- Ecc=regionprops(L,'Eccentricity'); %獲得目標離心率
- ecc=[Ecc(:).Eccentricity];
- centroid=regionprops(L,'Centroid'); %獲得目標中心
- str='';
- for j=1:length(area)
- if perimeter(j)>30 %進一步去除小噪聲干擾
- nump=[area(j),perimeter(j),ecc(j)];
- dis=sum((repmat(nump,10,1)-FD).^2,2);
- [~,Ind]=min(dis);
- if Ind==7||Ind==10
- % 數字6和9通過豎直方向上的中心判定,這個能用的原因在於數據中數字都是一行上的,平均中心應該在一半高度位置
- cet=centroid(j).Centroid;
- if cet(2)<size(Ib,1)/2;
- Ind=10;
- else
- Ind=7;
- end
- end
- str=[str,num2str(Ind-1)];
- end
- end
- subplot(8,8,i),imshow(Im);title(str);hold on
-
- end
部分實驗結果


代碼里主要函數
功能:regionprops(英文get the properties of region)用來度量圖像區域屬性的函數.常用來統計被標記的區域的面積分布,顯示區域總數。
語法:STATS = regionprops(L,properties)
描 述:測量標注矩陣 L中每一個標注區域的一系列屬性。L 中不同的正整數元素對應不同的區域, 例如:L 中等於整數1的元素對應區域1;L 中等於整數2的元素對應區域2;以此類推。
返回值STATS 是一個長度為 max(L(:))的結構數組,結構數組的相應域定義了每一個區域相應屬性下的度量。 properties 可以是由逗號分割的字符串列表,包含字符串的單元數組,單個字符串 'all' 或者 'basic'。如果 properties 等於字符串 'all',則所有下述字串列表中的度量數據都將被計算,如果properties 沒有指定或者等於 'basic',則屬性 'Area'、'Centroid' 和'BoundingBox' 將被計算。
'Area'圖像各個區域中像素總個數
'BoundingBox' 包含相應區域的最小矩形
'Centroid' 每個區域的質心(重心)
'MajorAxisLength' 與區域具有相同標准二階中心矩的橢圓的長軸長度(像素意義下)
'MinorAxisLength' 與區域具有相同標准二階中心矩的橢圓的短軸長度(像素意義下)
'Eccentricity' 與區域具有相同標准二階中心矩的橢圓的離心率(可作為特征)
'Orientation' 與區域具有相同標准二階中心矩的橢圓的長軸與x軸的交角(度)
'Image' 與某區域具有相同大小的邏輯矩陣
'FilledImage' 與某區域具有相同大小的填充邏輯矩陣
'FilledArea' 填充區域圖像中的on像素個數
'ConvexHull' 包含某區域的最小凸多邊形
'ConvexImage' 畫出上述區域最小凸多邊形
'ConvexArea' 填充區域凸多邊形圖像中的on像素個數
'EulerNumber' 幾何拓撲中的一個拓撲不變量——歐拉數
'Extrema' 八方向區域極值點
'EquivDiameter' 與區域具有相同面積的圓的直徑
'Solidity' 同時在區域和其最小凸多邊形中的像素比例
'Extent' 同時在區域和其最小邊界矩形中的像素比例
'PixelIdxList' 存儲區域像素的索引下標
'PixelList' 存儲上述索引對應的像素坐標
'Perimeter' 圖像各個區域邊界地區的周長
總結
這個問題里面的樣本實在是太簡單,對於有旋轉的,大小不同的數字驗證碼識別應該對數字提取旋轉不變的特征點信息,以及離心率,方向像素直方圖等多種信息融合才能得到較好結果。
另外還有一點就是圖像的預處理,因為更復雜的驗證碼包含各種噪聲,這就要求字符檢測器有更好的魯棒性。