驗證碼的主要目的是強制人機互動來抵禦機器自動化攻擊,為了確保伺服器系統的穩定和使用者資訊的安全,越來越多的網站採用了驗證碼技術。圖片驗證碼是目前最常用的一種,本文也主要討論這種驗證碼的識別。最近在一個爬蟲專案中遇到了驗證碼,需要機器自動識別繞過。這些驗證碼大都解析度都較低,本身資訊量不大。通常被加入一種或多種干擾因素:各種背景干擾,噪聲點畫素,字型形變和累疊,字元位置隨機及個數不定,反色等情況。在網上調研了資料和文獻後,分別採用OCR識別和模板庫匹配方法對不同型別驗證碼進行了識別。主要過程可以分解為三個步驟:1.圖片清理,2.字元切分,3.字元識別。以下結合工作經驗和調研內容講解一些常用的驗證碼識別方法和過程。1.圖片清理圖片清理是為接下來的機器學習或模板匹配階段做準備的,指透過灰度化、二值化、干擾點清理等過程,得到比較乾淨的圖片資料
驗證碼中的噪音點通常是用來增加破解難度的隨機元素,它們可以是點、線、形狀或其他非字母數字的圖形。下面我會描述一個典型的帶有噪音點的驗證碼的例子,並且解釋一下這些噪音是如何被加入到驗證碼中的。
以上圖片是一個對比圖,展示了一個帶噪音點的驗證碼與其乾淨版本的對比。左邊的圖片顯示了包含扭曲的字母和數字的驗證碼,周圍散佈著隨機的噪音點和線條。右邊的圖片則是同一驗證碼的乾淨版本,沒有噪音點或線條,只有清晰的字母和數字可見。這有助於理解噪音點在驗證碼中的實際效果。
為了增加識別難度,驗證碼影像上新增了以下型別的噪音:
1.隨機點噪音:在整個影像的背景上隨機分佈的小黑點或小白點,這些點的密度不均勻,有的地方密集,有的地方稀疏。
2.隨機線條噪音:在影像中新增一些斜的、彎曲的或者直的細線,線條的顏色可能與字母相同或不同,但足以干擾識別。
3.扭曲和變形:字母本身可能經過扭曲處理,比如旋轉、拉伸或壓縮,使得字母的形狀變得不規則。
4.背景干擾:可能有雜色的背景,或是背景圖案,這增加了額外的識別難度。
5.模糊效果:整個影像或部分割槽域可能應用了模糊效果,使得字母邊緣變得不清晰。
6.顏色變化:字母可能使用了漸變色,或者背景與字母之間的對比度較低,使得區分更加困難。
** 如何新增噪音**
在生成驗證碼時,噪音可以透過程式語言中的圖形庫來新增,如Python的PIL庫或OpenCV庫。例如,隨機點噪音可以透過在迴圈中隨機選擇影像中的座標並設定畫素值來實現。線條噪音可以透過繪製隨機角度和長度的線條來完成。扭曲和變形則可以透過影像變換函式實現,而模糊效果通常由影像卷積濾波器如高斯模糊來完成。
去除噪音
驗證碼噪音的去除通常涉及影像處理和機器學習技術,包括但不限於:
濾波:使用高斯濾波、中值濾波等技術減少隨機點噪音。
二值化:透過閾值分割將影像轉換為黑白,有助於去除背景噪音。
形態學操作:如膨脹和腐蝕,用於清理細小的噪音點。
連通元件分析:識別和分離影像中的獨立字元。
深度學習:使用卷積神經網路(CNNs)等模型進行特徵提取和分類,以識別驗證碼中的有效資訊。
艾埃巨擘 www.ai9v.cn
該方法的優點是:原理簡單直觀;可以針對不同網站定製最佳化;對於扭曲的字母和數字識別率較高。缺點是:開發量大,需要定製開發;需要收集大量的字元圖片庫;字元變化很多的情況,匹配次數增加速度下降;對於字元有粘連的圖片識別率低;5. 支援向量機 支援向量機通俗來講是一種二類分類模型,其基本模型定義為特徵空間上的間隔最大的線性分類器,其學習策略便是間隔最大化,最終可轉化為一個凸二次規劃問題的求解。實際應用上,往往遇到的是非線性可分得情況,因此透過核函式把低維向量對映到更高維空間,使得樣本滿足線性可分。 驗證碼識別問題實際上是其中單個字元識別問題,而在字元可窮舉的情況下,比如只有英文字元和數字,單個字元識別問題其實是一個分類問題。一個英文字母或數字表示一類,而驗證碼中切分後得到的單個字元需要被機器自動分到某一類。一般情況下,把單個字元的灰度圖片轉成整形陣列,陣列的每一個元素表示圖片的一個畫素,即一個特徵維度。我們切分得到的圖片大小為10x16=160畫素,即有160個特徵,當特徵數量多且特徵之間關係不明確時,採用支援向量機分類比較合適。 LIBSVM 是臺灣大學林智仁(Lin Chih-Jen)副教授等開發設計的一個簡單、易於使用和快速有效的SVM模式識別與迴歸的軟體包,他不但提供了編譯好的可在Windows系統的執行檔案,還提供了原始碼,方便改進、修改以及在其它作業系統上應用。該軟體還有一個特點,就是對SVM所涉及的引數調節相對比較少,提供了很多的預設引數,利用這些預設引數就可以解決很多問題;並且提供了互動檢驗(Cross Validation)的功能。主要引數使用:多類別(C-SVC=0),radial basis function(kernel_type=2),訓練和預測程式碼如下。對於 這樣輕微變形的驗證碼,有字母和數字共36個類別,收集訓練樣本共778個字元圖的情況下,單字元預測準確率接近100%:
labels = [] samples = []for ch in captchaTemplate.keys(): for table in captchaTemplate[ch]: labels.append(ord(ch)) samples.append(map(lambda e:e/255., table)) problem = svm_problem(labels, samples) model = svm_train(problem, '-t 2 -c 500')print len(samples) data = map(lambda e:e/255., list(Image.open(TESTFILE).getdata(TESTFILE))) y = ord('z') prediction = svm_predict([y,], [data,], model)print prediction
該方法的優點是:無需設計快速的影像匹配演算法;只要圖片切分方法合適,對於扭曲傾斜的字母和數字識別率也較高;並且可以針對不同型別的驗證碼做定製最佳化。缺點是:支援向量機原理比較複雜,無法直觀解釋,需要了解支援向量機等機器學習方法。6. 神經網路 以上驗證碼識別都依賴於字元切分,切分的好壞幾乎直接決定識別的準確程度。而對於有字元粘連的圖片,往往識別率就會低很多。目前驗證碼識別最先進的是谷歌在識別“街景”影像中門牌號碼中使用的一套的演算法。該演算法將定位、分割和識別等幾個步驟統一起來,採用一種“深度卷積神經網路”(deep convolutional neural network)方法進行識別,準確率可以達到99%以上。谷歌拿自有的reCAPTCHA驗證碼做了測試,結果發現,對於難度最大的reCAPTCHA驗證碼,新演算法的準確率都達到 99.8%,這可能也好於大多數人為驗證。 驗證碼作為一種輔助安全手段在Web安全中有著特殊的地位,瞭解驗證碼識別的方法和原理,不僅有利於繞過驗證碼抓取網站內容,而且有利於設計更安全合理的驗證碼。