寫爬蟲有一個繞不過去的問題就是驗證碼,現在驗證碼分類大概有4種:
-
影象類
-
滑動類
-
點選類
-
語音類
今天先來看看影象類,這類驗證碼大多是數字、字母的組合,國內也有使用漢字的。在這個基礎上增加噪點、幹擾線、變形、重疊、不同字型顏色等方法來增加識別難度。
相應的,驗證碼識別大體可以分為下麵幾個步驟:
-
灰度處理
-
增加對比度(可選)
-
二值化
-
降噪
-
傾斜校正分割字元
-
建立訓練庫
-
識別
由於是實驗性質的,文中用到的驗證碼均為程式生成而不是批次下載真實的網站驗證碼,這樣做的好處就是可以有大量的知道明確結果的資料集。
當需要真實環境下需要獲取資料時,可以使用結合各個大碼平臺來建立資料集進行訓練。
生成驗證碼這裡我使用Claptcha這個庫,當然Captcha這個庫也是個不錯的選擇。
為了生成最簡單的純數字、無幹擾的驗證碼,首先需要將claptcha.py的285行_drawLine做一些修改,我直接讓這個函式傳回None,然後開始生成驗證碼:
這裡需要註意ubuntu的字型路徑,也可以在網上下載其他字型使用。生成驗證碼如下:
可以看出,驗證碼有形變。對於這類最簡單的驗證碼,可以直接使用谷歌開源的tesserocr來識別。
首先安裝:
然後開始識別:
可以看出,對於這種簡單的驗證碼,基本什麼都不做識別率就已經很高了。有興趣的小夥伴可以用更多的資料來測試,這裡我就不展開了。
接下來,在驗證碼背景新增噪點來看看:
生成驗證碼如下:
識別:
效果還可以。接下來生成一個字母數字組合的:
生成驗證碼如下:
第3個為小寫字母o,第4個為大寫字母O,第5個為數字0,第6個為小寫字母z,第7個為大寫字母Z,最後一個是數字2。人眼已經跪了有木有!但現在一般驗證碼對大小寫是不做嚴格區分的,看自動識別什麼樣吧:
人眼都跪的計算機當然也廢了。但是,對於一些幹擾小、形變不嚴重的,使用tesserocr還是十分簡單方便的。然後將修改的claptcha.py的285行_drawLine還原,看新增幹擾線的情況。
加了條幹擾線就完全識別不出來了,那麼有沒有什麼辦法去除幹擾線呢?
雖然圖片看上去是黑白的,但還需要進行灰度處理,否則使用load()函式得到的是某個畫素點的RGB元組而不是單一值了。處理如下:
處理後的圖片如下:
可以看出處理後圖片銳化了很多,接下來嘗試去除幹擾線,常見的4鄰域、8鄰域演演算法。所謂的X鄰域演演算法,可以參考手機九宮格輸入法,按鍵5為要判斷的畫素點,4鄰域就是判斷上下左右,8鄰域就是判斷周圍8個畫素點。如果這4或8個點中255的個數大於某個閾值則判斷這個點為噪音,閾值可以根據實際情況修改。
處理後的圖片如下:
好像……根本沒卵用啊?!確實是這樣的,因為示例中的圖片幹擾線的寬度和數字是一樣的。對於幹擾線和資料畫素不同的,比如Captcha生成的驗證碼:
從左到右依次是原圖、二值化、去除幹擾線的情況,總體降噪的效果還是比較明顯的。另外降噪可以多次執行,比如我對上面的降噪後結果再進行依次降噪,可以得到下麵的效果:
再進行識別得到了結果:
另外,從圖片來看,實際資料顏色明顯和噪點幹擾線不同,根據這一點可以直接把噪點全部去除,這裡就不展開說了。
第一篇文章,先記錄如何將圖片進行灰度處理、二值化、降噪,並結合tesserocr來識別簡單的驗證碼,剩下的部分在下一篇文章中和大家一起分享。
作者:roy
來源:
http://www.hi-roy.com/2017/09/19/Python%E9%AA%8C%E8%AF%81%E7%A0%81%E8%AF%86%E5%88%AB/