摘要:需要識別的驗證碼圖像,其中包含個字符數(shù)字字母驗證碼圖片來源思路灰度化將圖像轉(zhuǎn)為灰度圖像,即一個像素只有一種色階有種不同灰度,值為表示像素最黑,值為表示像素最白。
需要識別的驗證碼圖像,其中包含 4 個字符(數(shù)字字母)
驗證碼圖片來源:http://my.cnki.net/elibregist...
思路灰度化:將圖像轉(zhuǎn)為灰度圖像,即一個像素只有一種色階(有 256 種不同灰度),值為 0 表示像素最黑,值為 255 表示像素最白。
二值化:將圖像轉(zhuǎn)為黑白圖像,即一個像素只有黑白兩種狀態(tài),不是黑就是白,沒有灰色,值為 0 表示像素最黑,值為 1 表示像素最白.
圖像轉(zhuǎn)字符串:利用工具將圖像中的字符串識別出來
前面兩步都是對圖像進(jìn)行識別前處理,目的是提高計算機(jī)識別的準(zhǔn)確度,畢竟計算機(jī)本身不能理解圖像,一個像素值的微小變化都有可能導(dǎo)致錯誤識別
代碼import tesserocr from PIL import Image image = Image.open("87FW.jpg") # 灰度化 image = image.convert("L") # 二值化,傳入的是數(shù)字 1,默認(rèn)閾值是 127。一般不推薦使用,因為不夠靈活 # image = image.convert("1") # 另一種二值化。自定義灰度,將灰度值在 115 以上的設(shè)置 1(白色),其它設(shè)為 0(黑色),相當(dāng)于將閾值設(shè)置成了 115 table = [1] * 256 for i in range(256): table[i] = 0 if i > 115: break image = image.point(table, "1") print(tesserocr.image_to_text(image))
打?。?/p>
87FW
所謂的閾(yu)值是指將不同的像素值分開的那個臨界值
上面的代碼沒有保存圖片,為了直觀得看到經(jīng)過不同的處理后圖像的區(qū)別,下面展示的是兩張圖像分別是灰度處理和二值化(閾值 115)后的圖像
下面將每種不同閾值的圖像保存至本地,主要代碼如下:
... image = Image.open("87FW.jpg") image = image.convert("L") table = [1] * 256 for i in range(256): table[i] = 0 image.point(table, "1").save(f"87FW_{i}.jpg")
閾值為 0 代表將所有像素處理成白色(沒有黑色);閾值為 255 代表將所有像素處理成黑色。
可以發(fā)現(xiàn)閾值設(shè)置得越低,白色越多,能看得到的驗證碼(黑色)就少了,因為大部分灰度都處理成白色;反之,若閾值設(shè)置越大,黑色越多,更多的干擾像素處理成和驗證碼一樣的黑色。
以下是將上面不同閾值的圖片制作成的一個 gif 動態(tài)圖像,可以看到如果閾值設(shè)定在 0 至 255 這個過程中,驗證碼會呈現(xiàn)出不同效果
閾值是一個很難把控的關(guān)鍵,閾值設(shè)置大或小都會影響識別的準(zhǔn)確性,以下是遍歷所有閾值,測試閾值在哪個區(qū)間可以識別出正確的驗證碼。注:由于沒有做優(yōu)化,整個過程會比較慢
>>> for i in range(256): ... if tesserocr.image_to_text(Image.open(f"87FW_{i}.jpg")).strip()=="87FW": ... print(i, end=" ") ... 109 110 112 113 114 115 116 117 118 119 120 122 123 124 169 170 171 172 173
在 256 個閾值中只有 19 個(不足 7.42%)閾值可以正確識別出驗證碼,仔細(xì)察覺可以發(fā)現(xiàn)閾值區(qū)間被分成了多個,分別是 109~110、112~120、122~124、169~173,說明閾值區(qū)間不一定具有連續(xù)性。更糟糕的是,不同的驗證碼圖片,能準(zhǔn)確識別出其中驗證碼的閾值的數(shù)量、區(qū)間范圍、區(qū)間數(shù)等都很可能不同。當(dāng)然還有很多問題,比如選擇一個“不恰當(dāng)”的閾值導(dǎo)致圖像處理過度,只識別出其中 3 個字符,不要試圖隨機(jī)添加一個字母或數(shù)字,因為需要考慮具體是哪個位置的字符沒識別出來,這樣瞎猜幾乎是很難一次就命中的,好點(diǎn)的做法是:當(dāng)識別出來的字符不足時可以嘗試換一個閾值處理圖像,所以能識別出驗證碼是概率事件。畢竟在正常的人機(jī)識別中,識別一個驗證碼通常只有一次機(jī)會,識別錯了就會出現(xiàn)新的驗證碼,沒有換閾值再重新試一次的機(jī)會,不過好在通常閾值的范圍都是可以縮小的,比如可以忽略小于 70 和大于 200 的這些圖像處理過度的閾值(正常人都很難識別是什么數(shù)字、字母),這樣能命中的概率就會大大提高。
image.convert("1") 的默認(rèn)閾值是 127,在上面 19 個可以準(zhǔn)確識別驗證碼的閾值中沒有 127,這也就是為什么直接使用 image.convert("1") 方法二值化的圖像無法被準(zhǔn)確識別出其中的驗證碼
上面的驗證碼還算容易處理的,如果干擾像素的灰度值與驗證碼灰度差別比較大,可用上面的方法;但如果遇到干擾線條的灰度與驗證碼差不多、驗證碼重疊等情況,上面對圖像僅做簡單處理的方法就很難奏效了。這時就需要用到機(jī)器學(xué)習(xí)技術(shù)對識別器進(jìn)行訓(xùn)練,聽說識別率幾乎 100%!
參考資料:《Python3網(wǎng)絡(luò)爬蟲開發(fā)實(shí)戰(zhàn)》——8.1 圖形驗證碼的識別
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.hztianpu.com/yun/42253.html
摘要:神經(jīng)網(wǎng)絡(luò)以上驗證碼識別都依賴于字符切分,切分的好壞幾乎直接決定識別的準(zhǔn)確程度。目前驗證碼識別最先進(jìn)的是谷歌在識別街景圖像中門牌號碼中使用的一套的算法。 最近在一個爬蟲項目中遇到了驗證碼,需要機(jī)器自動識別繞過。剛好與題主的問題類似,在這里做一些分享。 在網(wǎng)上調(diào)研了資料和文獻(xiàn)后,分別采用OCR識別和模板庫匹配方法對不同類型驗證碼進(jìn)行了識別。主要過程可以分解為三個步驟:1.圖片清理,2.字符...
摘要:圖片驗證碼是目前最常用的一種。神經(jīng)網(wǎng)絡(luò)以上驗證碼識別都依賴于字符切分,切分的好壞幾乎直接決定識別的準(zhǔn)確程度。目前驗證碼識別最先進(jìn)的是谷歌在識別街景圖像中門牌號碼中使用的一套的算法。 全自動區(qū)分計算機(jī)和人類的圖靈測試(Completely Automated Public Turing test to tell Computers and Humans Apart,簡稱CAPTCHA),...
摘要:在上一篇博客圖像處理之圖片文字識別中我們介紹了在中如何利用軟件來識別圖片中的英文與中文,本文將具體介紹如何在中利用軟件來識別驗證碼數(shù)字加字母。 ??在上一篇博客Python圖像處理之圖片文字識別(OCR)中我們介紹了在Python中如何利用Tesseract軟件來識別圖片中的英文與中文,本文將具體介紹如何在Python中利用Tesseract軟件來識別驗證碼(數(shù)字加字母)。??我們在網(wǎng)...
摘要:了別人代碼的你最近忽然對圖像識別有了興趣,作為一個前端,當(dāng)然是想用來深入研究。先從簡單的入手,識別圖片驗證碼。圖片驗證碼對開發(fā)來說一點(diǎn)也不陌生,它是對服務(wù)器保護(hù)的一道屏障,避免了諸如暴力破解密碼之類的攻擊。 copy了別人代碼的你 showImg(https://segmentfault.com/img/bVN5FL?w=396&h=210); 最近忽然對圖像識別有了興趣,作為一個前...
閱讀 3750·2021-11-25 09:43
閱讀 2752·2021-11-25 09:43
閱讀 3937·2021-11-24 09:38
閱讀 760·2021-11-18 10:02
閱讀 2321·2021-09-22 15:53
閱讀 3073·2019-08-30 15:44
閱讀 2824·2019-08-30 14:01
閱讀 2852·2019-08-29 15:15