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

来源:http://www.cnblogs.com/cnduan/archive/2016/01/24/5154419.html
-Advertisement-
Play Games

畢業設計做了一個簡單的研究下驗證碼識別的問題,並沒有深入的研究,設計圖形圖像的東西,水很深,神經網路,機器學習,都很難。這次只是在傳統的方式下分析了一次。今年工作之後再也沒有整理過,前幾天一個家伙要這個demo看下,我把一堆東西收集,打包給他了,他閑太亂了,我就整理記錄下。這也是大學最後的一次...


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

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

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

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

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

 

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

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

 

最終的識別率:

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

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

  1. 最大值法: 該過程就是找到每個像素點RGB三個值中最大的值,然後將該值作為該點的
  2. 平均值法:該方法選灰度值等於每個點RGB值相加去平均
  3. 加權平均值法:人眼對RGB顏色的感知並不相同,所以轉換的時候需要給予三種顏色不同的權重

背景去除

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

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

常用臨界點閾值確定演算法

  1. 雙峰法,這種演算法很簡單,假設該圖片只分為前景和背景兩部分,所以在灰度分佈直方圖上,這兩部分會都會形成高峰,而兩個高峰間的低谷就是圖片的前景背景閾值所在。這個演算法有局限性,如果該圖片的有三種或多種主要顏色,就會形成多個山峰,不好確定目標山谷的所在,尤其是驗證碼,多種顏色,灰度後也會呈現不同層次的灰度圖像。故本程式沒有採用這種演算法。
  2. 迭代法,該演算法是先算出圖片的最大灰度和最小灰度,取其平均值作為開始的閾值,然後用該閾值將圖片分為前景和背景兩部分,在計算這兩部分的平均灰度,取平均值作為第二次的閾值,迭代進行,直到本次求出的閾值和上一次的閾值相等,即得到了目標閾值。
  3. 最大類間方差法,簡稱OTSU,是一種自適應的閾值確定的方法,它是按圖像的灰度特性,將圖像分成背景和目標2部分。背景和目標之間的類間方差越大,說明構成圖像的2部分的差別越大,當部分目標錯分為背景或部分背景錯分為目標都會導致2部分差別變小。因此,使類間方差最大的分割意味著錯分概率最小。而該方法的目標就是找到最符合條件的分割背景和目標的閾值。本程式也是採用的該演算法進行背景分離的。
  4. 灰度拉伸演算法,這是OTSU的一種改進,因為在前景背景差別不大的時候,OTSU的分離效果就會下降,此時需要增加前景背景的差別,這是只要在原來的灰度級上同時乘以一個繫數,從而擴大灰度的級數。

噪點判斷及去除

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

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

 

二值化

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

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

 

圖片分割

圖片分割的主要演算法

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

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

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

  1. 基於閾值的分割,這種分割方式在背景處理中已經用到,通過某種方式找到目標圖片區域和非目標圖片區域間的分界值,進而達到將兩個區域分離的目的,這種方式達不到區分每個字元的效果,所以在分割階段沒有採用。
  2. 投影分割,也叫做基於區域的分割,這種分割演算法也很簡單,就是將二值化後的圖片在X軸方向做一次像素點分佈的投影,在峰谷的變化中就能定位到每個目標區域了,然後對單個區域進行Y軸投影,進而確定區域位置。該方式對輕微粘連有一定的處理效果,但是,對與噪點會也會產生過分的分割,還有對‘7’,‘T’,‘L’等會產生分割誤差,所以,程式中沒有採用這種演算法。

 

                     圖3-7投影法

  1. 邊緣檢測分割,也叫做點掃描法,這種分割方式能一定程度滿足程式的要求,因此,本程式也是採用了這種分割演算法,後面會詳細介紹。
  2. 聚類,聚類法進行圖像分割是將圖像空間中的像素用對應的特征空間點表示,根據它們在特征空間的聚集對特征空間進行分割,然後將它們映射回原圖像空間,得到分割結果。這種方式處理複雜,但是對粘連,變形等複雜圖像處理有良好的效果。由於時間有限,本次課題並沒有對該方式進行深入分析實現。

3.6.2邊緣檢測分割演算法

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

 

圖3-8圖片分割示意圖

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

  1. 從掃描指針從圖片最左邊像素點X軸坐標為0開始,向下掃描,掃描寬度為1px,如果碰到了像素點R值是0的,記下此時X坐標A ,如果掃描到底部都沒有遇到,則從指針向右移動一位,繼續縱向掃描直到得到A。
  2. 掃描指針從A+1開始,縱向掃描每個像素點,遇到R值是255的,變數K(初始值0)自增一,掃描到底部判斷K的值,如果K值等於圖片高度,則停止後續掃描,記下此時X軸坐標B,否則指針向右移動一位,繼續掃描直到得到B。
  3. 在X區間(A,B-1)中,指針從Y坐標是0點橫向掃描,判斷每個點的R值,如果R值等於0,則停止掃描,記下此時Y軸坐標C。否則,指著下移一個單位,繼續橫向掃描
  4. 在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個,意味著切割出來的小圖片也得是四個,針對這種情況,我就做了進一步處理,首先看下切割後可能出現的情況:

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

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

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

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

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

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

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

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

 

字模製作

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

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

驗證碼識別

要想識別驗證碼,必須要有製作好的字模資料庫,然後一次進行下麵過程:

  1. 驗證碼圖片的獲取,該步驟驗證碼的來源可以是從網路流中獲取驗證碼,  也可以從磁碟中載入圖片。
  2. 圖片處理,包括灰度,去噪,去背景,二值化,字元分割,圖片歸一化,圖片特征碼獲取。

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

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

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

字模庫維護

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

  1. 重覆字模數據的過濾剔除。
  2. 對於插入錯誤的字模可以進行修改。
  3. 可以刪除不需要的字模數據

圖片處理類的設計

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

開發人員可以直接調用GetYZMCode()方法進行驗證碼的識別處理,這是一個重載方法,其餘的方法會在下麵具體實現中介紹具體方法的設計,下麵是這個類圖表示了ImageProcess類中主要的處理方法和之間的關係:

 

發票編號識別

這個是基於aforge.net實現的,參考國外一位撲克牌識別的代碼。

過程是先確定發票的位置,然後定位到發票編號,切出發票編號,調用自動識別類庫識別數字,然後再將識別數據寫到屏幕上。當然也要實現訓練字模;

 

完成這個demo過程還是比較有趣,感謝活躍在博客園,csdn,github,開源中國strackoverflow等社區的前輩,他們對開源社區分享,奉獻讓更多的開發者收益,在他們的肩膀上,我們這些菜鳥才能走的更遠。

 

最後附上源碼:

https://github.com/ccccccmd/ReCapcha

具體案例都在源代碼中。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1,使用工具概述 FT232Rl晶元+sscom32+示波器 2,接收數據分析 sscom32發送數據:0xaa[1010 1010] 波特率為:4800bps @5V系統 示波器測試FT232RL 發送引腳 Txd,得到數據如上圖所示。 從上圖中可以得到如下幾點結論: 1.Txd空閑為高電平。 2...
  • 1.修改主機名及hosts文件10.205.22.185 nn1 (主)作用namenode,resourcemanager,datanode,zk,hive,sqoop10.205.22.186 nn2 (備)作用namenode,resourcemanager,datanode,zk10.205...
  • BBB 的板上有五個 LED 燈,一個電源,四個其他指示燈,usr0 至 usr3 。這次學習是控制 usr0 至 3 讓它們亮著,熄滅,閃。算是個 Hello World 實驗。非常簡單。 需要的材料: BBB 一臺 購買BBB 自帶的數據線一條 手提電腦或台式電腦,有 USB 插頭的 首先用數據...
  • 由於Python易學、開源、面向對象、可移植性高、庫豐富的特點,近期開始學習Python。百度瞭解了各款Python IDE後,還是認為Eric比較適合我,所以踏上了安裝Eric坎坷之路,從選定工具到安裝成功一共花費了8天時間,從Windows到Linux再到Mac,挨個折騰了一遍,Windows的...
  • 問題一:什麼是C#?C#是微軟公司在2000年新推出的一款運行在.NET Framework平臺上面的編程語言,這個.NET Framework平臺又怎麼去理解呢?舉個例子來說好了,一個土著族人只會說土著話,他跑到美國去用土著話跟別人交流,別人當然什麼都聽不懂,最後他還是乖乖回到他的土著國。那麼在這...
  • 此文主要分享瞭如何將自己博客園的文章自動導出到 Markdown 文檔進行存儲,以便在本地進行歸檔管理,程式中也對文章的分類、tag、代碼塊以及文章中的圖片進行了保存處理,以便上傳到自己的圖床。
  • 第11章函數函數提供了一個有力代碼復用機制, 並且讓你的代碼保持簡潔和易懂。它們同樣也是EF運行時能利用的資料庫層代碼.函數有幾類: Rowset Functions, 聚合函數, Ranking Functions, 和標量值函數.函數要麼確定,要麼不確定。當用一些指定的值調用函數,而函數返回的結...
  • 主要介紹什麼是.NET反射特性,.NET反射能為我們做些什麼,最後介紹幾種常用的反射的實現方法,通過對反射性特的瞭解,可以設計出非常有用的基於反射的編程模式。
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...