採用開源框架captcha_trainer自動識別不定長驗證碼

由於經常需要登錄某系統進行測試,但系統裏有驗證碼每次都要進行輸入感覺稍微有點繁瑣。爲此打算採用驗證碼自動識別的技術來實現。據我所知,目前識別驗證碼主要可以有以下方式進行解決:

  1. 打碼平臺人工識別
  2. ocr框架自動識別
  3. 機器學習自動識別

其中速度上ocr和機器學習去識別驗證碼的速度是最快的,但ocr需要驗證碼的字符很規範才能進行識別,否則也是識別不了的。而我目前想識別類似這樣的驗證碼,那麼ocr的方式去識別則準確率會非常低的

        

由此,遍萌生了採用機器學習的方式來處理此驗證碼,並決定採用tensorflow框架來進行識別

在寫了自己的訓練模型後發現其識別率並不高,於是在網上搜了下大佬們是怎麼處理的,於是發現了此框架https://github.com/kerlomz/captcha_trainer

於是自己嘗試了一下後,識別上面的驗證碼的準確率達到了1.0,以下爲主要的操作步驟,特此進行記錄

驗證碼生成

爲了訓練驗證碼,那麼得要先將驗證碼生成出來。

先分析上面的驗證碼可能的字符:0123456789+-x÷?=

爲了訓練的方便先進行一次轉碼:0123456789abcdef

即數字不變,特殊符號+-x÷?=依次修改爲abcdef

然後再自己寫個腳本進行生成,我這裏一次生成10萬張驗證碼進行訓練。(生成驗證碼的代碼在這裏就貼出來了,不同的情況不同的寫法)

其文件名遵循如下法則即可:真實值_UUID.jpeg, 如此處的:1a7fe_0779a021f919422cbe603de6bc4ce590.jpeg

將其生成到某個目錄即可,如此處的:D:/temp/obj

訓練

訓練的步驟參考https://github.com/kerlomz/captcha_trainer的readme.md就可以了

其主要步驟主要分3步:

  1. 寫好model.yaml
  2. 用make_dataset.py生成訓練和測試文件
  3. 調用trains.py進行訓練

由於上面的步驟比較簡單,這裏就不貼出來了,其github上面也有比較詳細的說明,具體的可以參考此項目的readme.md

通過我的個人實踐強烈建議訓練時採用tensorflow-gpu來進行訓練,因爲我也用cpu來進行訓練測試過,實在是太慢了而且還很費電!用cpu訓練6萬張用了一下午的時間才訓練好,而gpu只用了3分鐘就訓練完畢了。

另外在安裝CUDA與cuDNN時注意版本的選擇,版本太高的話,可能會導致與tensorflow-gpu的版本不兼容

還有就是,請使用python3.6版本,目前的tensorflow還不支持3.7版本的python。如果本地已經安裝了python的其他版本了的話,可以通過安裝anocada進行處理,如果沒有科學上網的話,爲了提高下載速度,需要將anocada配成國內的anocada源,具體的自行百度即可,其用法與Virtual Environment類似

部署

部署時採用https://github.com/kerlomz/captcha_platform項目

當上面的訓練完畢後,會在out目錄生成兩個文件,按照官方的操作步驟將生成的文件copy到captcha_platform對應的目錄即可。

然後就是安裝依賴和啓動項目了。安裝依賴時此項目直接安裝tensorflow即可,沒有必要安裝tensorflow-gpu版本。

如果在windows上安裝依賴,需要安裝 vc++ 4.0,否則可能會報錯。

當依賴安裝一切就緒後,選擇platform項目中的一個server進行啓動就可以了。如我這裏的:

執行

python tornado_server.py

然後就可以啦

測試

對於測試其captcha_platform的readme.md中也有比較具體的描述,如果是用http服務啓動的,調用http接口即可。

先將打算解析的圖片轉爲base64,然後再傳入到接口中就好了

爲了測試方便,可以直接在百度上搜一個在線base64圖片編碼的工具進行轉碼也可以自己編碼進行操作

也可以像我這樣寫一個python腳本進行測試,對某個目錄下的所有文件進行一次測試:

import base64
import json
import os
import re
import hashlib
import time
import requests
import io

from PIL import Image

path = "D:\\temp\\obj007"
url = "http://localhost:19952/captcha/v1"

def img_test():
    error_count = 0
    for i in os.listdir(path):
        right_str = i.split("_")[0]
        print(i + "->" + right_str)
        with open("D:\\temp\obj\\" + i, 'rb') as f:
            base64_data = base64.b64encode(f.read())
            s = base64_data.decode()
            print('%s' % s)
            data = {
                'image': s,
            }
            r = requests.post(url, headers=headers, data=data)
            res_json = json.dumps(r.json())
            print(res_json + " ->" + r.json()['message'])
            if (right_str == r.json()['message']):
                print("ok!")
            else:
                error_count = error_count + 1
                print("!!!!!!!!!!!" + str(error_count))

當然,最快的還是直接在postman裏測試,不管用哪個,只要自己開心就好,哈哈

我這裏就直接這樣操作了,在線轉:

然後將轉碼後的base64複製過來,發送到接口中就可以啦

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

如在postman中這樣測一下:

其中返回的message就是自動識別後的值啦。如這裏的:

{
    "message": "54d6fe",
    "code": 0,
    "success": true
}

54d6fe再按照之前定義的規則轉一下就變成了:54÷6=?

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章