陳以山+張勇
摘要:驗(yàn)證碼是各大網(wǎng)站用以防范計(jì)算機(jī)自動程序惡意攻擊的手段之一。通過使用數(shù)字圖像處理中的圖片分割、開閉運(yùn)算等手段,能夠識別絕大部分網(wǎng)站的驗(yàn)證碼。對驗(yàn)證碼識別技術(shù)的研究,既能及早發(fā)現(xiàn)驗(yàn)證碼的漏洞,也能對諸如車牌識別、手寫識別等技術(shù)起到促進(jìn)作用。
關(guān)鍵詞:驗(yàn)證碼識別;數(shù)字圖像處理;圖片分割;圖片開運(yùn)算;模圖片閉運(yùn)算
中圖分類號:TP311 文獻(xiàn)標(biāo)識碼:A 文章編號:1009-3044(2017)01-0190-03
1 研究背景
驗(yàn)證碼(CAPTCHA)是“Completely Automated Public Turing test to tell Computers and Hunmans Apart”(全自動區(qū)分計(jì)算機(jī)和人類的圖靈測試)的縮寫,是一種區(qū)分當(dāng)前用戶是人類還是計(jì)算機(jī)的自動程序。在測試中,用戶需要根據(jù)程序生成的一個問題做出正確的回答,程序據(jù)此來判斷該用戶是人類還是計(jì)算機(jī)。驗(yàn)證碼種類繁多,大體有基于字符的圖片驗(yàn)證碼、基于問答的驗(yàn)證碼、聲音驗(yàn)證碼等。
目前,應(yīng)用最廣泛的是基于字符的圖片驗(yàn)證碼,它具有容易產(chǎn)生、不受用戶背景知識和文化差異的影響,且暴力破解的難度很大,使用主流的編程語言,很容易可以產(chǎn)生一個包含隨機(jī)字母或者數(shù)字的圖片。為了增加識別難度,在生成圖片時,往往會加上諸多干擾因素,比如加上前景、背景,字符粘連,字符變形、歪斜等。
驗(yàn)證碼為互聯(lián)網(wǎng)安全作出了很大貢獻(xiàn),但我們不能忽視驗(yàn)證碼所存在的漏洞,研究驗(yàn)證碼自動識別算法,能夠及早發(fā)現(xiàn)驗(yàn)證碼設(shè)計(jì)存在的漏洞,并在據(jù)此作出調(diào)整,以增加驗(yàn)證碼的安全性。同時,驗(yàn)證碼識別作為一種圖靈測試,綜合了數(shù)字圖像處理、模式識別、人工智能等領(lǐng)域的研究成果,也對其他應(yīng)用如車牌識別、手寫文字識別等具有參考作用。
本文所研究的驗(yàn)證碼識別算法,主要分為圖片預(yù)處理、字符分割、模式識別三個步驟。由于各個應(yīng)用所使用的驗(yàn)證碼識別難度不一樣,需要根據(jù)具體的驗(yàn)證碼特點(diǎn),進(jìn)行具體分析,這里選取了CSDN的驗(yàn)證碼作為主要分析對象。
2 圖片預(yù)處理
1) 彩色圖片灰度化
大部分彩色圖像都是采用的RGB顏色模式,但是其并不能反映圖像的形態(tài)特征,只是從光學(xué)的原理上進(jìn)行了顏色的調(diào)配?;叶然倪^程就是將有RGB三通道的彩色圖像轉(zhuǎn)化為灰度圖像的處理,僅保留機(jī)器識別時所需要的必要信息,以便于后面的處理操作。在灰度化的過程中,一般是根據(jù)一定的系數(shù)將三維的RGB色彩降低為一維的灰度值。本人選取的灰度計(jì)算公式為:
其中,R、G、B分別是像素點(diǎn)在三個顏色通道的值,Grey為該像素點(diǎn)對應(yīng)的灰度值。具體計(jì)算方法為:依次讀取圖片每個像素點(diǎn),獲取其RGB值,取三者的平均值作為新圖片對應(yīng)像素點(diǎn)的灰度值。彩色圖片灰度化后的結(jié)果如表1所示:
2) 灰度圖片二值化
經(jīng)過灰度化的圖片,每個像素點(diǎn)的灰度值為0~255之間的任意數(shù)。由于驗(yàn)證碼圖片中背景色與字符顏色具有較大差異,可以通過設(shè)定閾值的方法,區(qū)分背景和字符?;叶戎荡笥陂撝档南袼攸c(diǎn),灰度值都設(shè)置為255,小于等于閾值的像素點(diǎn),灰度值都設(shè)置為0,具體計(jì)算公式為:
T值得選取在圖片二值化過程中至關(guān)重要,選取適當(dāng)?shù)腡,可以在一定程度上去除圖片噪音,增強(qiáng)字符輪廓。為了更精確的獲得圖像信息,這里采用近似一維Means方法尋找二值化閾值,該方法的大致步驟如下:
a. 設(shè)置一個初始閾值T=127
b. 根據(jù)閾值將每個像素?cái)?shù)據(jù)P分為字符數(shù)據(jù)G1和背景數(shù)據(jù)G2
c. G1的平均值是M1,G2的平均值是M2
d. 新的閾值T1=
e. 如果T1與T不相等,則回到步驟b;如果相等,則T1就是最終的閾值
灰度圖片經(jīng)過二值化后,效果如表1所示:
3) 圖片降噪
由于驗(yàn)證碼圖片中有許多噪音,這會極大影響到后期的識別效果,我們需要對圖片進(jìn)行降噪處理,盡量保留圖片中的字符信息,擦除噪音。圖片降噪方法有很多,這里使用滑動窗口的方法來進(jìn)行降噪處理。具體方法是:取圖像中每個像素點(diǎn)的灰度值,將該值和其四周的八個像素點(diǎn)的值進(jìn)行排序,取中值作為這個像素點(diǎn)的最終值??紤]到圖片噪聲一般都是相對獨(dú)立的像素點(diǎn),而字符區(qū)域一般是連成片的像素點(diǎn),因此該方法可以去除孤立的噪音像素點(diǎn)。驗(yàn)證碼圖片的降噪效果如表3所示:
4) 圖片開運(yùn)算
為了便于對圖片進(jìn)行分割,需要對圖片進(jìn)行形態(tài)學(xué)處理。形態(tài)學(xué)處理表現(xiàn)為一種領(lǐng)域運(yùn)算形式,通過一種特殊定義的被稱為“結(jié)構(gòu)單元”的領(lǐng)域,在每個像素位置上它與二值圖像對應(yīng)的區(qū)域進(jìn)行特定的邏輯運(yùn)算,邏輯運(yùn)算的結(jié)果輸出為圖像對應(yīng)的相應(yīng)像素。為了使得字符輪廓平滑,抑制字符邊界的小的噪點(diǎn),我們使用了結(jié)構(gòu)開變換。即對圖像先腐蝕,再膨脹。
在腐蝕操作中,定義A用B結(jié)構(gòu)單元腐蝕,記作A⊙B,表示為:
圖片腐蝕實(shí)現(xiàn)java代碼實(shí)現(xiàn)如下:
/*腐蝕
* @param source 輸入圖像灰度值的二維數(shù)組
* @param threshold 當(dāng)與運(yùn)算結(jié)果值小于閾值時,圖像點(diǎn)的值仍然設(shè)為0
* sData 結(jié)構(gòu)數(shù)組
* @return 輸出圖像灰度值的二維數(shù)組*/
private static int[][] correde(int[][] source,int threshold){
int width=source[0].length;
int height=source.length;
int[][] result=new int[height][width];
for(int i=0;i
for(int j=0;j if(i>0&&j>0&&i int max =0; for(int k=0;k int x=k/3; int y=k%3; if(sData[k]!=0){ if(source[i-1+x][j-1+y]>max){ max=source[i-1+x][j-1+y]; }}} if(max result[i][j]=0; }else{ result[i][j]=max; } }else{ result[i][j]=source[i][j]; }}} return result; } 在膨脹操作中,定義A用B結(jié)構(gòu)單元擴(kuò)張,記作A⊕B,表示為: A⊕B = 圖片膨脹實(shí)現(xiàn)java代碼實(shí)現(xiàn)如下: /* 膨脹運(yùn)算 * @param source 輸入圖像灰度值的二維數(shù)組 * @param shreshold 當(dāng)灰度值大于閾值(小于閾值127)時并且結(jié)構(gòu)元素為1(0)時,認(rèn)為對應(yīng)位置匹配上; * sData 結(jié)構(gòu)數(shù)組 * @return 輸出圖像灰度值的二維數(shù)組*/ private static int[][] dilate(int[][] source,int threshold){ int width=source[0].length; int height=source.length; int[][] result=new int[height][width]; for(int i=0;i for(int j=0;j if(i>0&&j>0&&i int max =0; ///對結(jié)構(gòu)元素進(jìn)行遍歷 for(int k=0;k int x=k/3; int y=k%3; if(sData[k]!=0){ ///不為0時,必須全部大于閾值,否則就設(shè)置為0并結(jié)束遍歷 if(source[i-1+x][j-1+y]>=threshold){ if(source[i-1+x][j-1+y]>max){ max=source[i-1+x][j-1+y]; } }else{ ////與結(jié)構(gòu)元素不匹配,賦值0,結(jié)束遍歷 max=0; break; }}} result[i][j]=max; }else{ result[i][j]=source[i][j]; }}} return result; } 在實(shí)踐中,我們使用的結(jié)構(gòu)體為一個3*3的矩陣: 開運(yùn)算效果如表4所示: 3 字符分割與識別 為了便于識別,需要將驗(yàn)證碼圖片進(jìn)行分割,使得分割后的每個圖片中只出現(xiàn)一個字符。由于待分析的驗(yàn)證碼無字符粘連現(xiàn)象,故而我們使用比較簡單的豎直投影法。假定背景色為白色(灰度值255),字符顏色為黑色(灰度值0),從左到右掃描圖片的每列像素點(diǎn),如果一列的灰度值總和小于閾值T,就認(rèn)為這是字符列,如果小于閾值T,則認(rèn)為這是間隔列。一次掃描之后,記錄所有字符開始列和間隔開始列,并據(jù)此分割圖片。 在字符識別階段,首先需要制作樣本庫,樣本需要包含所有可能出現(xiàn)的字符。樣本字符圖片統(tǒng)一使用26*26像素的圖片,背景色用0表示,字符色用1表示,也就是一個26*26的矩陣。對于待識別的字符圖片,首先采用雙線性差值算法,把圖片變?yōu)?6*26大小,采用同樣的方法來獲得圖片對應(yīng)的矩陣。在樣本庫中,使用漢明距離獲得當(dāng)前字符圖片與樣本庫中各個圖片的距離最近的一個圖片,該圖片所代表的值即是驗(yàn)證碼對應(yīng)字符的值。 4 識別效果 根據(jù)上述步驟,我們采用了java代碼實(shí)現(xiàn)了算法,并對CSDN網(wǎng)站的1000張驗(yàn)證碼圖片進(jìn)行了識別,總體識別率大約為60%,識別的難點(diǎn)主要出現(xiàn)在易于被混淆的字符上,例如字母O、D和數(shù)字0,字母Z和數(shù)字2等字符。 5 總結(jié)與展望 本文對驗(yàn)證碼圖片的識別做了深入研究,依次采用了圖片灰度化、二值化、圖片降噪、圖片開運(yùn)算等數(shù)字圖像處理方法對驗(yàn)證碼圖片進(jìn)行了預(yù)處理,使得識別效果有了顯著的提高。下一步可以研究以下幾個方面:1)改進(jìn)字符識別算法,可以采用SVM算法或者基于神經(jīng)網(wǎng)絡(luò)的學(xué)習(xí)算法;2)解決字符粘連時的字符分割問題;3)提升圖片降噪的效果。 參考文獻(xiàn): [1] Simon Haykin.Neural networks: a comprehensive foundation[M].2nded.USA: Prentice Hall,1998:443-483. [2] 岡薩雷斯.數(shù)字圖像處理[D].3版北京:電子工業(yè)出版社,2011. [3] 彭洪江.低照度圖像的降噪算法與實(shí)現(xiàn)[D].武漢理工大學(xué),2014 . [4] 陳紹林.車牌定位與字符分割算法的研究及實(shí)現(xiàn)[D].西安電子科技大學(xué),2013. [5] Serge Belongie Jitendra Malik Jan Puzicha. Matching with Shape Contexts [M].2000. [6] 文曉陽,高能,夏魯寧,等.高效的驗(yàn)證碼識別技術(shù)與驗(yàn)證碼分類思想[J].計(jì)算機(jī)工程, 2009(8):63. [7] 王璐.驗(yàn)證碼識別技術(shù)研究[D].中國科學(xué)技術(shù)大學(xué),2011. [8] 成洪靜,陳立潮,張英俊,等.基于SVM的多分類器構(gòu)造算法的研究[J].計(jì)算機(jī)技術(shù)與發(fā)展,2008 (12):109-112.