當前位置:
首頁 > 最新 > 驗證碼識別其實很簡單,python圖像處理識別驗證碼

驗證碼識別其實很簡單,python圖像處理識別驗證碼

基本識別原理概述:

1、每一幅圖像在構成上,都是由一個個像素組成的矩陣,每一個像素為單元格。

2、 彩色圖像的像素的由三原色(紅,綠,藍)構成元組,灰度圖像的像素是一個單值,每個像素的值範圍為(0,255)。

問題來源

某系統門戶登陸界面如下:

現在我們要實現自動的驗證碼識別。

圖像特徵

首先,我們仔細觀察下這個驗證碼圖像,可以發現一些固定特徵:

1、驗證碼中的字元數始終為6,並且是灰度圖像。

2、字元間的間隔看起來每次都一樣。

3、 每個字元都是完全定義的。

4、圖像有許多雜散的黑暗像素,以及穿過圖像的線條作為干擾因素。

圖像分析

所以我最終下載了一個這樣的圖像,並使用一個工具(binary-image)以二進位形式可視化圖像(0表示黑色,1表示白色像素)。

我的觀察沒錯,圖像尺寸為45x180,每個字元分配30個像素的空間來適配,從而使它們間隔比較均勻。

因此,取得了驗證碼識別路上的第一步,結果:

把圖像裁剪成6個不同的部分,每個部分的寬度為30像素。

python圖像裁剪

我們璇兒Python作為原型語言,因為它的庫最容易使用和部署。

經過簡單搜索,我找到了PIL庫。還用到了Image模塊,用來操作圖像進行字元裁剪並將圖像作為載入為數字矩陣。

字元部分裁剪

圖像裁剪的語法是:

from PIL import Image

image = Image.open("filename.png")

cropped_image = image.crop((left, upper, right, lower))

比如要裁剪第一個字元:

from PIL import Image

image = Image.open("captcha.png").convert("L")

cropped_image = image.crop((0, 0, 30, 45))

cropped_image.save("cropped_image.png")

得到的圖像為:

我將他打包到一個循環中,編寫了一個簡單的腳本,從該站點獲取500個驗證碼圖像,並將所有裁剪後的字元保存到一個文件夾中。回顧我們上一部分觀察到的特徵第三點,每個字元都有明確定義。

圖像去雜,清理干擾因子

為了"清理"圖像中的裁剪掉干擾因素(刪除不必要的線和點),我們使用一個很簡單的演算法:

字元中的所有像素都是純黑色(0)。如果它不是完全黑色的,將它當成白色的。因此,對於值大於0的每個像素,將給其重新賦值為255。使用load()函數將圖像轉換為45x180數字矩陣,然後對其進行處理。

pixel_matrix = cropped_image.load()

for col in range(0, cropped_image.height):

for row in range(0, cropped_image.width):

if pixel_matrix[row, col] != 0:

pixel_matrix[row, col] = 255

image.save("thresholded_image.png")

為了清晰起見,我將代碼應用於原始圖像。

原版的:

做過演算法矯正的圖

你可以看得到,並非完全黑暗的所有像素都被刪除了。比如通過圖像的線。上述方法在圖像處理中的專業術語叫做閾值處理,當然還有很多處理方法,閾值處理事最簡單實用的方法。

去除圖像中的黑點

回顧觀察到特徵的第四點,圖像中有許多散雜黑點像素的干擾因子。

循環遍歷圖像矩陣,並且如果相鄰像素是白色的,並且與相鄰像素相對的像素也是白色的,並且中心像素是黑色的,則設定中心像素為白色。

for column in range(1, image.height - 1):

for row in range(1, image.width - 1):

if pixel_matrix[row, column] == 0 and pixel_matrix[row, column - 1] == 255 and pixel_matrix[row, column + 1] == 255 :

pixel_matrix[row, column] = 255

if pixel_matrix[row, column] == 0 and pixel_matrix[row - 1, column] == 255 and pixel_matrix[row + 1, column] == 255:

pixel_matrix[row, column] = 255

結果為:

你可以看到,經過以上步驟的處理,圖像已經只剩下字元框架了。雖然有些字元已經丟失了一些基礎像素,但是每個字元的圖像骨架基本上都完備。當然這個是必須的,我們做這麼多處理的主要原因是為每個可能的字元都截取生成合適字元圖。

構建字元圖庫

我將上述演算法裁剪得到的所有字元圖像都存儲於文件夾下。下一個任務是為屬於"A-Z0-9"的每個字元找到至少一個樣本圖像。這一步就像"訓練"步驟,我手動為每個字元選擇了一個字元圖像並對其更名。

完成這一步後,每個字元都有一幅骨架圖像!

選擇最優的字元圖

我還運行了其他幾個腳本,確保每一個字元的圖像中都有最佳的圖像,例如,如果有20個"A"的字元圖像,暗色(1)數量最少的圖像顯然是雜訊最少的圖像,因此最適合作為骨架圖像。選擇的原則:

一個按照字元排序的相似圖像(約束條件:黑像素數量大小,並且相似度> = 90~95%)。

一個從每個分組字元獲得最佳圖像。

因此,到目前為止,我們生成了一個像素圖像庫。我們將它們轉換為像素矩陣,並將"點陣圖,把字元圖轉為數字點陣SON文件

識別演算法

最後,這就是獲取任何新的驗證碼圖像的演算法:

使用相同的演算法盡量減少新圖像中不必要的干擾因子

對於新驗證碼圖片中的每字元,強制通過生成的JSON文件舉證來匹配,基於相應的黑像素匹配來計算相似度。

如果一個像素是黑的並且在圖像中的位置恰好是破解驗證碼,並且像素在我們的字元庫中的骨架圖像/點陣圖中的相同位置處也是的,則計數會遞增1。

與骨架圖像中黑暗像素的數量做對比,計算匹配百分比,選擇具有最高匹配百分比的字元就是識別結果的字元。

結果演示

最終結果如下:

得到的字元為Z5M3MQ, 驗證碼被成功識別出來了。

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

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


請您繼續閱讀更多來自 蟲蟲搜奇 的精彩文章:

天宮一號太空站完成使命,在南太平洋上墜毀
Facebook否認未經許可從手機收集通話和簡訊數據

TAG:蟲蟲搜奇 |