MATLAB簡易驗證碼識別程序介紹.
簡介
本文要識別的驗證碼是這種:
第一步: 二值化
所謂二值化就是把不需要的信息通通去除,比如背景,干擾線,干擾像素等等,只剩下需要識別的文字,讓圖片變成2進制點陣。
第二步: 文字分割
為了能識別出字符,需要對要識別的文字圖圖片進行分割,把每個字符作為單獨的一個圖片看待。
第三步: 標準化
對于部分特殊的驗證碼,需要對分割后的圖片進行標準化處理,也就是說盡量把每個相同的字符都變成一樣的格式,減少隨機的程度。最簡單的比如旋轉還原,復雜點的比如扭曲還原等等。比如本文中分割后的數字1和8寬度不一致,把他們的寬度填充一致,就是標準化的一種。
可以看到上面切割后的字符1最右邊一列像素都為0。
第四步: 學習 & 識別
這一步可以用很多種方法,最簡單的就是模板對比,對每個出現過的字符進行處理后把點陣變成字符串,標明是什么字符后,通過字符串對比來判斷相似度。
在文章的后半部分會詳細解釋我采用的算法。
訓練集學習tran.m
width = 132; height = 20;%共10張驗證碼 x 11個數字 共分割出 110張字符圖片 %每個字符圖片 高度20 x 寬度9 共 180個像素 data = zeros(110, 180);
chars = zeros(180, 10); %用于存儲10個數字字符的特征值 每個字符大小為20x9
for name = 0:9 im = imread(sprintf('%d.jpg', name)); %讀取圖片 im = im2bw(im) == 0; %第一步:二值化 黑色1 白色0
%第二步: 分割 black = sum(im) ~= 0; %20x132矩陣 從上向下求和為 1x132 不等于0 則橫坐標對應的一列有字符像素 white = sum(im) == 0; %20x132矩陣 從上向下求和為 1x132 等于0 則橫坐標對應的一列沒有字符像素 lower = find(min([black 0],[1 white])); %獲取11個字符的開始下標 upper = find(min([0 black],[white 1])) - 1; %獲取11個字符的結束下標 for i=1:11 ch = im(:,lower(i):upper(i)); %截取單個字符 ch(20, 9) = 0; %第三步: 字符二值化矩陣大小標準化為20x9 data(name*11 + i ,:) = ch(:); %字符圖片數據存入data end
end
%第四步: 學習 & 識別 class = clusterdata(data, 10); %將110個字符圖片分為10類
%各個分類號對應的實際數字(人工識別后寫進去的- -) num = [5 3 6 8 9 0 7 2 1 4];
for i = 1:10 %各類中的字符圖片取均值 im = mean(data(class == i, :)) > 0.5;
chars(:, num(i) + 1) = im; %存儲 end</pre>驗證碼識別ocr.m
function ret = ocr(filename) load; ret = zeros(1, 11); im = imread(filename); im = im2bw(im) == 0; %第一步: 二值化%第二步: 分割 black = sum(im) ~= 0; white = sum(im) == 0; lower = find(min([black 0],[1 white])); upper = find(min([0 black],[white 1])) - 1; for i=1:11 ch = im(:,lower(i):upper(i)); ch = ch(:); ch(180) = 0; %第三步標準化 %第四步: 識別 [~, num] = max(sum(min(repmat(ch, 1, 10), chars))); ret(i) = num-1; end
end</pre>