程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> 驗證碼識別,發票編號識別,驗證碼識別發票編號

驗證碼識別,發票編號識別,驗證碼識別發票編號

編輯:C#入門知識

驗證碼識別,發票編號識別,驗證碼識別發票編號


      畢業設計做了一個簡單的研究下驗證碼識別的問題,並沒有深入的研究,設計圖形圖像的東西,水很深,神經網絡,機器學習,都很難。這次只是在傳統的方式下分析了一次。

今年工作之後再也沒有整理過,前幾天一個家伙要這個demo看下,我把一堆東西收集,打包給他了,他閒太亂了,我就整理記錄下。這也是大學最後的一次作業,裡面有很多記憶和懷念。

這個demo的初衷不是去識別驗證碼,是把驗證的圖像處理方式用到其他方面,車票,票據等。

這裡最後做了一個發票編號識別的的案例:

地址:http://v.youku.com/v_show/id_XMTI1MzUxNDY3Ng==.html

 

demo中包含一個驗證碼識別處理過程的演示程序,一個自動識別工具類庫,還有一個發票識別的演示程序

用了7個網站的圖形驗證碼做為案例,當然還是有針對性的,避開了粘連,扭曲太厲害的:

 

最終的識別率:

  •  在驗證碼圖像的處理過程中,涉及驗證碼生成,灰度處理,背景色去除,噪點處理,二值化過程,圖片字符分割,圖片歸一化,圖片特征碼生成等步驟;

     灰度處理方式主要有三種:

背景去除

該過程就是將背景變成純白色,也就是盡可能的將目標字符之外的顏色變成白色。該階段最難的就是確定圖片的背景和前景的分割點,就是那個臨界值。因為要將這張圖片中每個像素點R值(灰度處理後的圖片RGB的值是相同的)大於臨界值的點RGB值都改成255(白色)。而這個臨界點在整個處理過程中是不變的。

能區分前景和背景,說明在該分割點下,前景和背景的分別最明顯,就像一層玻璃,將河水分成上下兩部分,下面沉澱,相對渾濁,上面清澈,這樣,兩部分區別相當明顯。這個片玻璃的所在位置就是關鍵。

常用臨界點阈值確定算法

噪點判斷及去除

首先是去除邊框,有的驗證碼在圖片邊界畫了一個黑色邊框,根據去背景的原理這個邊框是沒有被去掉的。去除這個邊框很簡單,對加載到二維數組中每個像素點進行判斷,如果該點的橫坐標等於0或者圖片寬度減一,或者總坐標等於0或者縱坐標等於圖片高度減一,它的位置就是邊框位置。直接RGB置0去除邊框。

對於非邊框點,判斷該目標像素點是不是噪點不是直接最目標點進行判斷的,是觀察它周圍的點。以這個點為中心的九宮格,即目標點周圍有8個像素點,計算這8個點中不是背景點(即白色)點的個數,如果大於給定的界定值(該值和沒中驗證碼圖片噪點數目,噪點粘連都有關,不能動態獲取,只能根據處理結果對比找到效果好的值),則說明目標點是字符內某個像素點的幾率大些,古改點不能作為噪點,否則作為噪點處理掉。假設此次的界定值是2,則:

 

二值化

二值化區別於灰度化,灰度化處理過的圖片,每個像素點的RGB值是一樣的,在0-255之間,但是二值化要求每個像素點的RGB值不是0就是255.將圖片徹底的黑白化。

二值化過程就是對去噪後的驗證碼圖片的每個像素點進行處理,如果該點的R值不是255,那麼就將該點的RGB值都改成0(純黑色),這樣整個過程下來,這正圖片就變成真正意義上的黑白圖片了。

 

圖片分割

圖片分割的主要算法

圖片分割技術在圖形圖像的處理中占有非常重要的地位,圖片是一個復雜的信息傳遞媒介,相應的,不是每個圖片上的所有信息都是預期想要的,因次,在圖片上”篩選“出目標區域圖像就顯得很重要,這就用到了圖片分割技術。

圖片字符的分割是驗證碼識別過程中最難的一步,也是決定識別結果的一步。不管多麼復雜的驗證碼只要能准確的切割出來,就都能被識別出來。分割的方式有多種多樣,對分割後的精細處理也復雜多樣。

下面介紹幾種成熟的分割算法:

 

                     圖3-7投影法

3.6.2邊緣檢測分割算法

程序采用的是邊緣檢測的方式確定每個字符邊界的。該算法的步驟如下:

 

圖3-8圖片分割示意圖

從圖中可以看到,當程序判斷”6“這個字符的邊界時:

“4“這個字符邊界的獲取也是一樣的,只是步驟一中掃描開始的位置X坐標0變成了B+1.

每次判斷一下B-A,如果他的值小於你驗證碼字符中寬度最小的那個,(假設這裡定的是4),則停止找邊界把坐標加到集合中就可以了。

如學校的驗證碼字符中,寬度最窄的是1,但它的寬度是大於4的所以該設定沒有問題,根據情況來定,一般寬度小於4的,驗證碼就很小了,不利於人看。

上述過程走完之後,就得到了左右,上下四個邊界點的橫坐標,縱坐標,即(A,B-1,C ,D-1);把這四個點確定的區域對應的原驗證碼所在的區域畫到一張小圖片上。然後把這張小圖片按照設定的高寬進行歸一化處理,把處理好的圖片放入集合中返回。等待下一步處理。

分割前: 分割後的四張效果:

分割後的特殊處理

在這一過程中,由於圖像的部分粘連,往往分割的結果都不會達到預期的效果,分割出的小圖片也是千奇百怪。但是,考慮到現在大多數網站的驗證碼字符都是4個,意味著切割出來的小圖片也得是四個,針對這種情況,我就做了進一步處理,首先看下切割後可能出現的情況:

這張驗證碼是二值化處理過的驗證碼,很明顯,第一個和第二個字符是相互粘連的,利用程序的切割方式切出來的圖片應該是3個小圖片,類似這樣:

顯然,①不是程序想要的情況,對於這種情況,即第一次切完是3部分的,就找到最寬的一個,然後從中間剁開。得到4部分圖片。

相應的,還有2部分的時候:

這也不是我們理想的情況,也是同樣的道理,把兩部分中中間剁開,得到4個小圖片。

還有這種情況,第一次切割完全是一張的:

我們只需把它均分4分就可以了。

當然上述處理會造成相應的誤差,但是只要後面字模數量足夠大,這樣切割處理效果還是可以的。

此次只對4個字符的情況做了特殊的處理,其他個數的沒有做,具體做法會在總結中介紹。

 

字模制作

這個過程是將切割好的圖片轉化成特征矩陣,把圖片切割過程中返回的小圖片集合進行特征值獲取。在圖片切割過程,程序已經將切割好的小圖片進行了歸一化處理,即長寬都相同,遍歷每一個像素,如果該點R值是255,則就記錄一個0,如果該點的R值是255,則記錄一個1,這樣按著順序,記錄好的0,1拼成字符串,這個字符串就是該圖片的特征碼。然後前面拼上該圖片對應的字符,用‘--’連接。這樣,一個圖片就有一個特征值字符串對應了,把這個特征值字符串寫入文本或數據庫中,基本的字模庫就建立好了。由於圖片歸一化的時候小圖規格是20*30,所以,每個字模數據就是20*30+3+2(回車換行)=605個字符。

字模庫的量越大,後面的識別正確率也就越高,但是,並不是越大越好,字模數據越多,比對消耗的時間就越多,相比來說效率就會下降。下面是一張字模庫的部分圖樣:

驗證碼識別

要想識別驗證碼,必須要有制作好的字模數據庫,然後一次進行下面過程:

3.計算相似度,讀取字模數據庫中的字模數據,用歸一化後的小圖的特征碼和字模數據進行對比,並計算相似度,記錄相似度最高的字模數據項所對應的字符C。

4.識別結果,依次將所得到的字符C拼接起來,得到的字符串就是該驗證碼的識別結果。

下面是驗證碼識別的具體流程:

字模庫維護

驗證碼的識別過程已經詳細的分析,識別關鍵點一個在切割,一個在字模庫的質量。字模庫涉及兩個問題,一個就是重復的問題,一個就是字模數據。這個階段主要實現:

圖片處理類的設計

圖像處理類是遵循面向對象的思想設計的,將圖像處理過程中用到的方法進行封裝,對常用參數值進行參數默認值和可變參數設置,方法重載。該類是靜態類,方便開發人員調用,其中Boundry是存儲小圖片邊界信息的類,裡面有四個邊界值屬性。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved