向AI轉型的程序員都關注了這個號👇👇👇html
機器學習AI算法工程 公衆號: datayxpython
這個demo的初衷不是去識別驗證碼,是把驗證的圖像處理方式用到其餘方面,車票,票據等。程序員
本文完整源碼 獲取方式:web
關注微信公衆號 datayx 而後回覆 圖像識別 便可獲取。面試
這裏最後作了一個發票編號識別的的案例:算法
地址:http://v.youku.com/v_show/id_XMTI1MzUxNDY3Ng==.html數據庫
demo中包含一個驗證碼識別處理過程的演示程序,一個自動識別工具類庫,還有一個發票識別的演示程序flask
用了7個網站的圖形驗證碼作爲案例,固然仍是有針對性的,避開了粘連,扭曲太厲害的:數組
最終的識別率:微信
在驗證碼圖像的處理過程當中,涉及驗證碼生成,灰度處理,背景色去除,噪點處理,二值化過程,圖片字符分割,圖片歸一化,圖片特徵碼生成等步驟;
灰度處理方式主要有三種:
最大值法: 該過程就是找到每一個像素點RGB三個值中最大的值,而後將該值做爲該點的
平均值法:該方法選灰度值等於每一個點RGB值相加去平均
加權平均值法:人眼對RGB顏色的感知並不相同,因此轉換的時候須要給予三種顏色不一樣的權重
背景去除
該過程就是將背景變成純白色,也就是儘量的將目標字符以外的顏色變成白色。該階段最難的就是肯定圖片的背景和前景的分割點,就是那個臨界值。由於要將這張圖片中每一個像素點R值(灰度處理後的圖片RGB的值是相同的)大於臨界值的點RGB值都改爲255(白色)。而這個臨界點在整個處理過程當中是不變的。
能區分前景和背景,說明在該分割點下,前景和背景的分別最明顯,就像一層玻璃,將河水分紅上下兩部分,下面沉澱,相對渾濁,上面清澈,這樣,兩部分區別至關明顯。這個片玻璃的所在位置就是關鍵。
經常使用臨界點閾值肯定算法
雙峯法,這種算法很簡單,假設該圖片只分爲前景和背景兩部分,因此在灰度分佈直方圖上,這兩部分會都會造成高峯,而兩個高峯間的低谷就是圖片的前景背景閾值所在。這個算法有侷限性,若是該圖片的有三種或多種主要顏色,就會造成多個山峯,很差肯定目標山谷的所在,尤爲是驗證碼,多種顏色,灰度後也會呈現不一樣層次的灰度圖像。故本程序沒有采用這種算法。
迭代法,該算法是先算出圖片的最大灰度和最小灰度,取其平均值做爲開始的閾值,而後用該閾值將圖片分爲前景和背景兩部分,在計算這兩部分的平均灰度,取平均值做爲第二次的閾值,迭代進行,直到本次求出的閾值和上一次的閾值相等,即獲得了目標閾值。
最大類間方差法,簡稱OTSU,是一種自適應的閾值肯定的方法,它是按圖像的灰度特性,將圖像分紅背景和目標2部分。背景和目標之間的類間方差越大,說明構成圖像的2部分的差異越大,當部分目標錯分爲背景或部分背景錯分爲目標都會致使2部分差異變小。所以,使類間方差最大的分割意味着錯分機率最小。而該方法的目標就是找到最符合條件的分割背景和目標的閾值。本程序也是採用的該算法進行背景分離的。
灰度拉伸算法,這是OTSU的一種改進,由於在前景背景差異不大的時候,OTSU的分離效果就會降低,此時須要增長前景背景的差異,這是隻要在原來的灰度級上同時乘以一個係數,從而擴大灰度的級數。
噪點判斷及去除
首先是去除邊框,有的驗證碼在圖片邊界畫了一個黑色邊框,根據去背景的原理這個邊框是沒有被去掉的。去除這個邊框很簡單,對加載到二維數組中每一個像素點進行判斷,若是該點的橫座標等於0或者圖片寬度減一,或者總座標等於0或者縱座標等於圖片高度減一,它的位置就是邊框位置。直接RGB置0去除邊框。
對於非邊框點,判斷該目標像素點是否是噪點不是直接最目標點進行判斷的,是觀察它周圍的點。以這個點爲中心的九宮格,即目標點周圍有8個像素點,計算這8個點中不是背景點(即白色)點的個數,若是大於給定的界定值(該值和沒中驗證碼圖片噪點數目,噪點粘連都有關,不能動態獲取,只能根據處理結果對比找到效果好的值),則說明目標點是字符內某個像素點的概率大些,古改點不能做爲噪點,不然做爲噪點處理掉。假設這次的界定值是2,則:
二值化
二值化區別於灰度化,灰度化處理過的圖片,每一個像素點的RGB值是同樣的,在0-255之間,可是二值化要求每一個像素點的RGB值不是0就是255.將圖片完全的黑白化。
二值化過程就是對去噪後的驗證碼圖片的每一個像素點進行處理,若是該點的R值不是255,那麼就將該點的RGB值都改爲0(純黑色),這樣整個過程下來,這正圖片就變成真正意義上的黑白圖片了。
圖片分割
圖片分割的主要算法
圖片分割技術在圖形圖像的處理中佔有很是重要的地位,圖片是一個複雜的信息傳遞媒介,相應的,不是每一個圖片上的全部信息都是預期想要的,因次,在圖片上」篩選「出目標區域圖像就顯得很重要,這就用到了圖片分割技術。
圖片字符的分割是驗證碼識別過程當中最難的一步,也是決定識別結果的一步。無論多麼複雜的驗證碼只要能準確的切割出來,就都能被識別出來。分割的方式有多種多樣,對分割後的精細處理也複雜多樣。
下面介紹幾種成熟的分割算法:
基於閾值的分割,這種分割方式在背景處理中已經用到,經過某種方式找到目標圖片區域和非目標圖片區域間的分界值,進而達到將兩個區域分離的目的,這種方式達不到區分每一個字符的效果,因此在分割階段沒有采用。
投影分割,也叫作基於區域的分割,這種分割算法也很簡單,就是將二值化後的圖片在X軸方向作一次像素點分佈的投影,在峯谷的變化中就能定位到每一個目標區域了,而後對單個區域進行Y軸投影,進而肯定區域位置。該方式對輕微粘連有必定的處理效果,可是,對與噪點會也會產生過度的分割,還有對‘7’,‘T’,‘L’等會產生分割偏差,因此,程序中沒有采用這種算法。
邊緣檢測分割,也叫作點掃描法,這種分割方式能必定程度知足程序的要求,所以,本程序也是採用了這種分割算法,後面會詳細介紹。
聚類,聚類法進行圖像分割是將圖像空間中的像素用對應的特徵空間點表示,根據它們在特徵空間的彙集對特徵空間進行分割,而後將它們映射回原圖像空間,獲得分割結果。這種方式處理複雜,可是對粘連,變形等複雜圖像處理有良好的效果。因爲時間有限,本次課題並無對該方式進行深刻分析實現。
3.6.2邊緣檢測分割算法
程序採用的是邊緣檢測的方式肯定每一個字符邊界的。該算法的步驟以下:
圖片分割示意圖
從圖中能夠看到,當程序判斷」6「這個字符的邊界時:
從掃描指針從圖片最左邊像素點X軸座標爲0開始,向下掃描,掃描寬度爲1px,若是碰到了像素點R值是0的,記下此時X座標A ,若是掃描到底部都沒有遇到,則從指針向右移動一位,繼續縱向掃描直到獲得A。
掃描指針從A+1開始,縱向掃描每一個像素點,遇到R值是255的,變量K(初始值0)自增一,掃描到底部判斷K的值,若是K值等於圖片高度,則中止後續掃描,記下此時X軸座標B,不然指針向右移動一位,繼續掃描直到獲得B。
在X區間(A,B-1)中,指針從Y座標是0點橫向掃描,判斷每一個點的R值,若是R值等於0,則中止掃描,記下此時Y軸座標C。不然,指着下移一個單位,繼續橫向掃描
在X區間(A,B-1),指針從C+1處開始橫向掃描,判斷每一個像素點的R值,若是R值等於255,使N(初始值0)自增一,這行掃描結束後判斷N的值,若是該值等於B-A,則中止掃描記下此時的Y軸座標D,不然指針向下移動覺得,繼續橫向掃描,知道獲得D。
「4「這個字符邊界的獲取也是同樣的,只是步驟一中掃描開始的位置X座標0變成了B+1.
每次判斷一下B-A,若是他的值小於你驗證碼字符中寬度最小的那個,(假設這裏定的是4),則中止找邊界把座標加到集合中就能夠了。
如學校的驗證碼字符中,寬度最窄的是1,但它的寬度是大於4的因此該設定沒有問題,根據狀況來定,通常寬度小於4的,驗證碼就很小了,不利於人看。
上述過程走完以後,就獲得了左右,上下四個邊界點的橫座標,縱座標,即(A,B-1,C ,D-1);把這四個點肯定的區域對應的原驗證碼所在的區域畫到一張小圖片上。而後把這張小圖片按照設定的高寬進行歸一化處理,把處理好的圖片放入集合中返回。等待下一步處理。
這也不是咱們理想的狀況,也是一樣的道理,把兩部分中中間剁開,獲得4個小圖片。
還有這種狀況,第一次切割徹底是一張的:
咱們只需把它均分4分就能夠了。
固然上述處理會形成相應的偏差,可是隻要後面字模數量足夠大,這樣切割處理效果仍是能夠的。
這次只對4個字符的狀況作了特殊的處理,其餘個數的沒有作,具體作法會在總結中介紹。
字模製做
這個過程是將切割好的圖片轉化成特徵矩陣,把圖片切割過程當中返回的小圖片集合進行特徵值獲取。在圖片切割過程,程序已經將切割好的小圖片進行了歸一化處理,即長寬都相同,遍歷每個像素,若是該點R值是255,則就記錄一個0,若是該點的R值是255,則記錄一個1,這樣按着順序,記錄好的0,1拼成字符串,這個字符串就是該圖片的特徵碼。而後前面拼上該圖片對應的字符,用‘--’鏈接。這樣,一個圖片就有一個特徵值字符串對應了,把這個特徵值字符串寫入文本或數據庫中,基本的字模庫就創建好了。因爲圖片歸一化的時候小圖規格是20*30,因此,每一個字模數據就是20*30+3+2(回車換行)=605個字符。
字模庫的量越大,後面的識別正確率也就越高,可是,並非越大越好,字模數據越多,比對消耗的時間就越多,相比來講效率就會降低。下面是一張字模庫的部分圖樣:
驗證碼識別
要想識別驗證碼,必需要有製做好的字模數據庫,而後一次進行下面過程:
驗證碼圖片的獲取,該步驟驗證碼的來源能夠是從網絡流中獲取驗證碼, 也能夠從磁盤中加載圖片。
圖片處理,包括灰度,去噪,去背景,二值化,字符分割,圖片歸一化,圖片特徵碼獲取。
3.計算類似度,讀取字模數據庫中的字模數據,用歸一化後的小圖的特徵碼和字模數據進行對比,並計算類似度,記錄類似度最高的字模數據項所對應的字符C。
4.識別結果,依次將所獲得的字符C拼接起來,獲得的字符串就是該驗證碼的識別結果。
下面是驗證碼識別的具體流程:
字模庫維護
驗證碼的識別過程已經詳細的分析,識別關鍵點一個在切割,一個在字模庫的質量。字模庫涉及兩個問題,一個就是重複的問題,一個就是字模數據。這個階段主要實現:
重複字模數據的過濾剔除。
對於插入錯誤的字模能夠進行修改。
能夠刪除不須要的字模數據
圖片處理類的設計
圖像處理類是遵循面向對象的思想設計的,將圖像處理過程當中用到的方法進行封裝,對經常使用參數值進行參數默認值和可變參數設置,方法重載。該類是靜態類,方便開發人員調用,其中Boundry是存儲小圖片邊界信息的類,裏面有四個邊界值屬性。
開發人員能夠直接調用GetYZMCode()方法進行驗證碼的識別處理,這是一個重載方法,其他的方法會在下面具體實現中介紹具體方法的設計,下面是這個類圖表示了ImageProcess類中主要的處理方法和之間的關係:
發票編號識別
這個是基於aforge.net實現的,參考國外一位撲克牌識別的代碼。
過程是先肯定發票的位置,而後定位到發票編號,切出發票編號,調用自動識別類庫識別數字,而後再將識別數據寫到屏幕上。固然也要實現訓練字模;
https://www.cnblogs.com/cnduan/p/5154419.html
閱讀過本文的人還看了如下:
《21個項目玩轉深度學習:基於TensorFlow的實踐詳解》完整版PDF+附書代碼
【Keras】完整實現‘交通標誌’分類、‘票據’分類兩個項目,讓你掌握深度學習圖像分類
如何利用全新的決策樹集成級聯結構gcForest作特徵工程並打分?
Machine Learning Yearning 中文翻譯稿
斯坦福CS230官方指南:CNN、RNN及使用技巧速查(打印收藏)
中科院Kaggle全球文本匹配競賽華人第1名團隊-深度學習與特徵工程
不斷更新資源
深度學習、機器學習、數據分析、python
搜索公衆號添加: datayx
長按圖片,識別二維碼,點關注
本文分享自微信公衆號 - 機器學習AI算法工程(datayx)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。