當前位置:
首頁 > 最新 > 15分鐘實現數字驗證碼自動識別,基於OpenCV+Keras

15分鐘實現數字驗證碼自動識別,基於OpenCV+Keras

簡介

驗證碼是我們登錄網站、提交訂單時常常會遇到的,最近大家登陸12306搶票肯定也遇到過很多的驗證碼,在關鍵時刻還要從一堆低像素的圖片中尋找燈塔和蠟燭,實在讓人憤懣。本文從最簡單也最為常見的數字驗證碼出發,利用機器學習實現驗證碼的自動識別。

驗證碼,可以看做網站的入口,只有當正確的輸入驗證碼時才允許開始訪問網站。驗證碼的英文為CAPTCHA,全稱是全自動區分計算機和人類的公開圖靈測試(Completely Automated Public Turing test to tell Computers and Humans Apart)」,作為圖靈測試的一種,旨在確認訪問者是真正的人類還是機器,從而防止惡意程序的入侵。然而,隨著深度學習和計算機視覺技術的發展,自動識別驗證碼成為了可能。

Part

1

任務:搜集驗證碼

用時:2分鐘

我們知道,機器學習需要大量的學習樣本來進行權值參數訓練。而在短時間內收集大量的驗證碼並非易事,本文作者找到了一個很容易破解的網站,其所用的驗證碼插件可輕鬆獲得驗證碼的生成程序。有了這個生成程序就好辦啦,相當於我們不用去找樣本,找到了樣本它媽,幫我們生一批樣本出來。

作者找到的這個網站叫Really Simple CAPTCHA,先來看一下它生成的驗證碼長什麼樣子。

從上圖我們可以看出,網站插件所生成的驗證碼是4位的,包含數字和字母。從插件的PHP代碼再來確認一下,代碼如下:

從代碼里可以看到,驗證碼的位數為4位,每個字元的字體各不相同,由數字和字母構成,但是為了避免混淆不包含O和I。所以,我們總共有32個字元(8個數字+24個字母)需要識別。

Part

2

任務:工具準備

所需時間:0分鐘

所謂工欲善其事,必先利其器。本文作者所使用的工具如下:

Python 3

Python 是目前人工智慧領域中最為流行的編程語言,包含多種機器學習和計算機視覺庫。

OpenCV

OpenCV 是計算機視覺和圖像處理任務上的流行框架。在這裡,我們需要使用 OpenCV 來處理 CAPTCHA 生成的圖像,OpenCV 擁有 Python API,所以我們可以直接使用 Python 調用它。

Keras

Keras 是一個使用 Python 編寫的深度學習框架。他可以讓我們更加輕鬆地定義、訓練和使用深度神經網路——僅需編寫很少的代碼。

TensorFlow

TensorFlow 是谷歌推出與維護的機器學習庫,也是目前人工智慧領域裡最為流行的框架。我們會在 Keras 之上寫代碼,但 Keras 實際上並沒有實現神經網路運算的方法——它需要使用 TensorFlow 作為後端來完成具體的工作。

假設環境你已經安裝好了,不然的話光Tensorflow小編就能安一個星期啊。。T-T

Part

3

任務:建立驗證碼數據集

用時:3分鐘

以往的數據集和標註都要耗費數月完成,有了上文提到的網站插件我們可以很輕鬆的獲得想要的數據集。修改插件,加一個簡單的for循環,使得其自動輸出1萬個驗證碼圖片以及對應的字元。圖片為PNG格式,圖片的名字即為圖片中所包含的字元,也就是true label真實標籤。

生成的樣本數據集如下圖所示。

為了避免「鼓勵」大家去破解上面的網站,作者開放了源碼和對應的1萬張樣本。鏈接在文末,需要的小夥伴們自行下載哦~

Part

4

任務:字元分割

用時:5分鐘

有了樣本數據集,馬上我們就可以建立網路模型來訓練了。然而在訓練開始之前,還要解決一個問題。現有的樣本是由4個字元組成的,如果放在一起直接識別精度會有一定的限制,所以首先將字元分隔開,進行逐字元識別是比較優化的方案。

那麼,要怎麼分割字元呢?

不要告訴我你想用YOLO啊,雖然YOLO肯定可以實現,但是也太大費周折了吧,俗話說叫大炮打蒼蠅了~

那麼,是不是簡單的平均分割就ok呢?當然也不行啊,字元在水平方向和垂直方向的分布都是不均勻的,平均分割會帶來字元殘缺的問題。如下圖。

GIF

答案是用OpenCV。OpenCV是常用的圖像處理庫,在圖像分析時,我們經常需要檢測顏色相同的像素塊。同理,在驗證碼中,字元是黑色的,背景是白色的,利用OpenCV內置的findContours()函數可以很容易檢測像素塊的邊緣區域,實現分割。

原始的驗證碼圖像像素如下圖:

我們將灰色圖像轉為黑色,也就是將驗證碼轉換為純黑和純白兩種顏色,從而更容易尋找邊緣輪廓,轉換後的黑白圖像如下圖。

使用OpenCV的findContours()函數檢測結果如下:

接下來我們按照順序把單個字元區域與單個字元標籤對應起來就好了。

到這裡就可以進行下一步了嗎?當然不是,每一步做完都要充分檢查,確保無誤後再開展後續的工作,這樣不會帶來誤差積累,也是很好的工作習慣。

在檢查分割的字元時,我們發現了下述問題,有些字元是連在一起的,很難通過邊緣輪廓將其分隔開。如下圖:

如果直接分割結果將會是一坨:

這種情況肯定要糾正的,不然後果不堪設想,那要怎麼糾正呢?

這裡的方法就簡單粗暴了,如果一個圖片中經過OpenCV之後分割出來3個字元,那麼肯定存在著字元粘連的問題。寬度過大的字元分割我們認為其存在著粘連,並且簡單直接的把它平均分為兩部分。

最後整理一下字元,我們把相同的單個字元放在同一個路徑下,每個路徑包含多個該字元的樣本,如下圖,圖中展示了字元W的樣本,1萬張樣本里共有1147個W字元。

Part

5

任務:訓練模型

用時:5分鐘

經過上述處理過程後,我們的問題簡化成了單個字元的識別問題,與著名的MNIST識別類似,只是多了些許字母而已。由於我們的任務比較簡單,所以所需的網路模型也可以簡單點,文中作者所用的模型包含2個conv卷積層和2個fc全連接層。

使用Keras構建網路的代碼如下,有效代碼才十幾行,好簡潔有木有。

模型構建完畢後我們就可以開始訓練了,訓練代碼如下。

對於這種簡單的任務,迭代次數也不需要很多就可以收斂。最終作者用了10個Epoch,訓練精度達到了100%。

Part

6

終極目標:破解驗證碼

好了,萬事俱備,我們可以正式開始破解驗證碼了!激不激動,興不興奮!

GIF

我們也可以直接在命令行看結果,如圖。

GIF

怎麼樣,你學會了嗎?感興趣的小夥伴也可以試一下更高級別的圖片驗證碼 ,輕鬆破解12306登錄限制。

最後祝願所有的小夥伴們都能如願買到回家的車票~

以上就是全部內容啦~關注「習悅智能」,獲取更多行業新鮮資訊~


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 習悅智能 的精彩文章:

TAG:習悅智能 |