Python 實現識別弱圖片驗證碼
目前,很多網站為了防止爬蟲肆意模擬瀏覽器登錄,采用增加驗證碼的方式來攔截爬蟲。驗證碼的形式有多種,最常見的就是圖片驗證碼。其他驗證碼的形式有音頻驗證碼,滑動驗證碼等。圖片驗證碼越來越高級,識別難度也大幅提高,就算人為輸入也經常會輸錯。本文主要講解識別弱圖片驗證碼。
1 圖片驗證碼強度
圖片驗證碼主要采用加幹擾線、字符粘連、字符扭曲方式來增強識別難度。
- 加幹擾線
加幹擾線也分為兩種,一種是線條跟字符同等顏色,另一種則線條的顏色是五顏六色。
- 字符粘連
各個字符之間的間隔比較小,互相依靠,能以分割。
- 字符扭曲
字符顯示的位置相對標準旋轉一定角度。
其中最弱的驗證碼為不具備以上的特征,幹擾因素比較小。如下:
2 識別思路
首先對圖片做二值化來降噪處理,去掉圖片中的噪點,幹擾線等。然後將圖片中的單個字符切分出來。最後識別每個字符。
圖片的處理,我采用 Python 標準圖像處理庫 PIL。圖片分割,我暫時采用谷歌開源庫 Tesseract-OCR。字符識別則使用 pytesseract 庫。
3 安裝
- Pillow
我使用的 Python 版本是 3.6, 而標準庫 PIL 不支持 3.x。所以需要使用 Pillow 來替代。Pillow 是專門兼容 3.x 版本的 PIL 的分支。使用 pip 包管理工具安裝 Pillow 是最方便快捷的。
pip install Pillow # 如果出現因下載失敗導致安裝不上的情況,建議使用代理 pip --proxy http://代理ip:端口 install Pillow
- Tesseract-OCR
Tesseract:開源的OCR識別引擎,初期Tesseract引擎由HP實驗室研發,後來貢獻給了開源軟件業,後經由Google進行改進,消除bug,優化,重新發布。這才讓其重煥新生。
我們可以在 GitHub 上找到該庫並下載。我是下載最新的 4.0 版本。
github 的下載地址是:https://github.com/tesseract-ocr/tesseract/wiki/4.0-with-LSTM#400-alpha-for-windows
- pytesseract
pytesseract 是 Tesseract-OCR 對進行包裝,提供 Python 接口的庫。同樣可以使用 pip 方式來安裝。
pip install pytesseract # 如果出現因下載失敗導致安裝不上的情況,建議使用代理 pip --proxy http://代理ip:端口 install pytesseract
4 代碼實現
4.1 獲取並打開圖片
獲取圖片驗證碼,你可以通過使用網絡請求庫下載。我為了方便,將圖片下載到本地並放在項目目錄下。
from PIL import Image ‘‘‘ 獲取圖片 ‘‘‘ def getImage(): fileName = ‘16.jpg‘ img = Image.open() # 打印當前圖片的模式以及格式 print(‘未轉化前的: ‘, img.mode, img.format) # 使用系統默認工具打開圖片 # img.show() return img
4.2 預處理
這一步主要是將圖片進行降噪處理, 把圖片從 "RGB" 模式轉化為 "L" 模式,也就是把彩色圖片變成黑白圖片。再處理掉背景噪點,讓字符和背景形成黑白的反差。
‘‘‘ 1) 將圖片進行降噪處理, 通過二值化去掉後面的背景色並加深文字對比度 ‘‘‘ def convert_Image(img, standard=127.5): ‘‘‘ 【灰度轉換】 ‘‘‘ image = img.convert(‘L‘) ‘‘‘ 【二值化】 根據閾值 standard , 將所有像素都置為 0(黑色) 或 255(白色), 便於接下來的分割 ‘‘‘ pixels = image.load() for x in range(image.width): for y in range(image.height): if pixels[x, y] > standard: pixels[x, y] = 255 else: pixels[x, y] = 0 return image
打開彩色圖片,PIL 會將圖片解碼為三通道的 “RGB” 圖像。調用 convert(‘L‘) 才會把圖片轉化為黑白圖片。其中模式 “L” 為灰色圖像, 它的每個像素用 8 個bit表示, 0 表示黑, 255 表示白, 其他數字表示不同的灰度。
在 PIL 中,從模式 “RGB” 轉換為 “L” 模式是按照下面的公式轉換的:
L = R 的值 x 299/1000 + G 的值 x 587/1000+ B 的值 x 114/1000
圖像的二值化,就是將圖像上的像素點的灰度值兩極分化(設置為 0 或 255,0表示黑,255表示白),也就是將整個圖像呈現出明顯的只有黑和白的視覺效果。目的是加深字符與背景的顏色差,便於 Tesseract 的識別和分割。對於閾值的選取,我采用比較暴力的做法,直接使用 0 和 255 的平均值。
4.3 識別
經過上述處理,圖片驗證碼中的字符已經變成很清晰了。
最後一步是直接用 pytesseract 庫識別。
import pytesseract ‘‘‘ 使用 pytesseract 庫來識別圖片中的字符 ‘‘‘ def change_Image_to_text(img): ‘‘‘ 如果出現找不到訓練庫的位置, 需要我們手動自動 語法: tessdata_dir_config = ‘--tessdata-dir "<replace_with_your_tessdata_dir_path>"‘ ‘‘‘ testdata_dir_config = ‘--tessdata-dir "C:\\Program Files (x86)\\Tesseract-OCR\\tessdata"‘ textCode = pytesseract.image_to_string(img, lang=‘eng‘, config=testdata_dir_config) # 去掉非法字符,只保留字母數字 textCode = re.sub("\W", "", textCode) return textCode
Tesseract-ORC 默認是沒有指定安裝路徑。我們需要手動指定本地 Tesseract 的路徑。不然會報出這樣的錯誤:
FileNotFoundError: [WinError 2] 系統找不到指定的文件
具體解決方案是:
使用文本編輯器打開 pytesseract 庫的 pytesseract.py 文件,一般路徑如下:
C:\Program Files (x86)\Python35-32\Lib\site-packages\pytesseract\pytesseract.py
將 tesseract_cmd 修改成你電腦本地的 Tesseract-OCR 的安裝路徑。
# CHANGE THIS IF TESSERACT IS NOT IN YOUR PATH, OR IS NAMED DIFFERENTLY tesseract_cmd = ‘C:/Program Files (x86)/Tesseract-OCR/tesseract.exe
最後執行字符識別的實例代碼
def main(): img = convert_Image(getImage(fileName)) print(‘識別的結果:‘, change_Image_to_text(img)) if __name__ == ‘__main__‘: main()
運行結果如下:
未轉化前的: RGB JPEG 識別的結果: 9834
5 總結
Tesseract-ORC 對於這種弱驗證碼識別率還是可以,大部分字符能夠正確識別出來。只不過有時候會將數字 8 識別為 0。如果圖片驗證碼稍微變得復雜點,識別率大大降低,會經常識別不出來的情況。我自己也嘗試收集 500 張圖片來訓練 Tesseract-ORC,識別率會有所提升,但識別率還是很低。
如果想要做到識別率較高,那麽需要使用 CNN (卷積神經網絡)或者 RNN (循環神經網絡)訓練出自己的識別庫。正好機器學習很火爆很流行,學習一下也無妨。
轉自:https://cloud.tencent.com/developer/article/1187805
Python學習交流群:548377875
作者:猴哥
Python 實現識別弱圖片驗證碼