【人工智能】圖像識別之小白天書——驗證碼篇(2)

介紹


哈嘍!久等了各位!對於上一篇文章的戛然而止,我正某人在這裏先給大家賠不是了。不過話說回來,這也是秉承着我們互聯網“小步快跑”的原則嘛!每次只學一點點,但是我們永不止步!當你在某訂閱號打開了一篇文章,打眼兒一看,我的天!這文章有一本金瓶…啊不,一本紅樓夢那麼長,能感受到的只有壓力和濃濃的敵意!有這時間,我看一本O'Reilly好不好!話不多說,書歸正傳,接演前文…


分割


分割就是把驗證碼切開,分成一個一個的字符,好方便識別的過程。現在的識別技術大多數都是單個字符去訓練識別的,並不是說不可以整張的去訓練識別,可是那樣需要成噸的訓練樣本和時間,並且非常容易出現過擬合現象,so,我們還是老老實實的分割吧!畢竟我們都是初學者!


分割的方法有很多,對於這種字母互相沒有粘連,而且水平位置波動不大的,我推薦大家使用感染分割法!這是一種最基礎的分割方法!其他很多分割方法都是以它爲基礎的,後篇中我們會介紹到一些比較複雜的分割方法。感染分割法概述就是:首先找到水平位置上的一箇中點,畫一條直的橫線,確保這條線可以穿過圖片上的每一個字。然後通過從左到右去遍歷這條線上的每一個點,每找到一個黑色的點,就把和他所有相鄰的黑色點都拿出來,單獨生成一張圖片。很好理解吧!


圖1

如圖1所示,這就是我們遍歷的點的行走軌跡,就這樣一直遍歷下去,就能分割出我們所有的字符啦!附上一段代碼,僅供參考:


運行完畢之後,得到一個裝滿字符像素點的集合,字符我們算是切割出來了,下一步做什麼呢?下面我們要爲識別工作做準備啦!我們需要“歸一化”。這是什麼呢?

字符歸一化是光學字符識別中的一個子步驟,給定一個字符區域,我們要做的就是將該區域內的字符歸一化到一個標準模板大小,然後才能提取特徵,並送給分類器做具體的識別。好的歸一化算法可以儘量提高後續特徵提取在同一類內的一致性。歸一化算法大致分爲四類:

1,歸一化到標準模板大小

2,傾斜校正

3,筆畫寬度歸一化

4,字形歸一化

歸一化在日常工作中,是一個很重要的環節,會直接影響到識別的精度!簡單的說,每一個準備識別的字符的圖片都必須有統一的大小,且最好有統一的比劃粗細、傾斜角度以及字體。圖片大小取決於你訓練樣本的大小,在不丟失特徵細節的基礎上,越小越有利於提升識別的精準度!至於訓練樣本是什麼,後面會講到,開篇這一章,我們識別還沒有用到機器訓練,機器學習,神經網絡之類的東東~對這部分感興趣的同學一定要持續關注我哦!


我們這張驗證碼,歸一化極其簡單,只要保證你輸出的每張圖片的大小一樣就好了!圖片大小要多少合適呢?可不能用眼看啊!教你一個方法,多切一些圖片,通過這些點集合中的最大行,最小行,最大列,最小列就能求出他們的高度和寬度,找一個最大的高度和最大的寬度,那就是這批驗證碼單個字符的寬和高啦!經過上述推算,單個字符大小爲13*25。

先創建一張新的空白圖片:


把我們剛剛得到了那個集合裏面每個字符的點集一個一個的填進去塗黑,就正式切割完成了!填的時候記得放在正中間,給上下、左右都留出一樣的距離就行了!

圖2


識別


經過了那麼多處理工作,終於可以開始識別了!這可是我們工作的重中之重!不過同學們依然不用擔心,在我們初試牛刀這一章中,識別部分的難度那也是相當的簡單親民吶!讓我們來認識一下機器學習界最簡單的算法之一!KNN(K-Nearest Neighbor,“K最近鄰”),先引用當下學習KNN用的最多的一張圖,邊看邊講:

圖3

如圖3,我用小學畢業就可以聽懂的話來解釋一下:假設我們要識別的字符是圖中心的綠色圓形,如果K=3,最近鄰的三個圖形中三角形最多,那它就是三角形。如果K=5,那最近鄰的5個圖形中正方形最多,它就是正方形!當K再次變大,三角形和正方數量相同,那我們就要計算權重了,即距離越近權重分數越高,所以最終它就又被識別成三角形!很好理解吧!只需要把圖中的二維距離替換成空間距離,也就是歐氏距離(歐幾里得距離),這就是KNN的所有精華了。

下面咱們把KNN落實在代碼裏吧!多下載一些驗證碼,對驗證碼進行去噪和分割,儘可能多的得到分割之後的樣本(如圖2),然後挑選一批樣本,儘量保證每一個字符的樣本都可以覆蓋到它的所有形態,我們選擇的這個驗證碼是比較簡單的,只有數字和字母,不會扭曲、旋轉,大小也不會變化,所以並不需要太多的樣本。事實上如果某個驗證碼比較複雜,需要大量樣本去覆蓋字符形態,KNN也就不適用了。經過人工篩選,我們得到一批這樣的樣本:


圖4

仔細觀察一下,會發現一個字符如果有多個樣本,這些樣本都有一些細微的不同。進行過機器學習的同學肯定表示,這點樣本根本不夠看!不過對於KNN來說,這就足夠了!接下來我們對樣本進行手工打標,意思其實就是手動的去修改每個樣本的文件名。把文件名改成圖像上的字符,如圖4,後面還需要一個後綴,用於區別單個字符的多個樣本。這一步是整體工作最簡單也是最枯燥冗長的一個步驟,在後篇中,我們需要成千訓練樣本的時候,也需要一個一個的手工打標,這個步驟是跳不過去的,所以,呼基喚友,一起做吧!

下面上代碼,第一步,先把我們製作的這些樣本load進去:



上面這一步可以放在init裏面去做,下面直接求距離:




通過這一步,我們已經得到了一個排好序的距離集合(distanckList),裏面放着我們的被識別圖片與所有樣本之間的距離,後面要做的就很簡單了吧!我們還需要兩個參數:



k=5表示我們要分析的是集合(distanckList)裏面的前5個數據,拿出前五個距離數據到,到距離權重對照表中卡一下,得到每個距離的權重,很容易就可以預測出這個字符是什麼了吧?

最後再把每一個預測出來的數據拼接在一起,看,完整的驗證碼就識別出來啦!



總結


如果你也順利的識別出整張驗證碼的結果,那恭喜你已經成功的邁入了圖像識別的門檻,成爲了一名初級解碼師!可以去碾壓各種低級的驗證碼了!從此以後圖像識別在諸位心中也不再是不可逾越的高山。雖然我們用到的所有框架、技術、算法都是最最基礎的,但是不管黑貓白貓,能抓老鼠就是好貓。想獲取更多解碼技能嗎?想要進行一次機器訓練?持續關注我吧!下一篇正某人全都滿足你!


 




微信掃一掃
關注該公衆號

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章