使用darknet識別點選驗證碼詳細過程(附帶原始碼)

Nick本尊發表於2019-04-07

專案原始碼:github.com/nickliqian/…

darknet_captcha

專案基於darknet開發了一系列的快速啟動指令碼,旨在讓影象識別新手或者開發人員能夠快速的啟動一個目標檢測(定位)的專案。 如果有沒有講清楚的地方,歡迎提issue和PR,希望能和大家共同完善!

本專案分為兩個部分:

  1. 提供兩個目標檢測(單分類和多分類點選驗證碼)的例子,你可以通過例子熟悉定位yolo3定位網路的使用方式
  2. 基於darknet提供一系列API,用於使用自己的資料進行目標檢測模型的訓練,並提供web server的程式碼
    在這裡插入圖片描述
    在這裡插入圖片描述
    在這裡插入圖片描述
    在這裡插入圖片描述

目錄

專案結構

專案分為darknet、extent、app三部分

  1. darknet: 這部分是darknet專案原始碼,沒有作任何改動。
  2. extent: 擴充套件部分,包含生成配置生成樣本訓練識別demoapi程式
  3. app: 每一個新的識別需求都以app區分,其中包含配置檔案、樣本和標籤檔案等。

開始一個例子:單型別目標檢測

以點選驗證碼為例 darknet實際上給我們提供了一系列的深度學習演算法,我們要做的就是使用比較簡單的步驟來呼叫darknet訓練我們的識別模型。

  • 推薦使用的作業系統是ubuntu,遇到的坑會少很多。
  • 如果使用windowns系統,需要先安裝cygwin,便於編譯darknet。(參考我的部落格:安裝cygwin

下面的步驟都已經通過ubuntu16.04測試。

1.下載專案

git clone https://github.com/nickliqian/darknet_captcha.git
複製程式碼

2.編譯darknet

進入darknet_captcha目錄,下載darknet專案,覆蓋darknet目錄:

cd darknet_captcha
git clone https://github.com/pjreddie/darknet.git
複製程式碼

進入darknet目錄,修改darknet/Makefile配置檔案

cd darknet
vim Makefile
複製程式碼
  • 如果使用GPU訓練則下面的GPU=1
  • 使用CPU訓練則下面的GPU=0
GPU=1
CUDNN=0
OPENCV=0
OPENMP=0
DEBUG=0
複製程式碼

然後使用make編譯darknet

make
複製程式碼

不建議使用CPU進行訓練,因為使用CPU不管是訓練還是預測,耗時都非常久。
如果你需要租用臨時且價格低的GPU主機進行測試,後面介紹了一些推薦的GPU雲服務。
如果在編譯過程中會出錯,可以在darknet的issue找一下解決辦法,也可以發郵件找我要舊版本的darknet。

3.安裝python3環境

使用pip執行下面的語句,並確保你的系統上已經安裝了tk:

pip install -r requirement.txt
sudo apt-get install python3-tk
複製程式碼

4.建立一個應用

進入根目錄,執行下面的程式生成一個應用的基本配置:

cd darknet_captcha
python3 extend/create_app_config.py my_captcha 1
複製程式碼

這裡的類別預設生成classes_1,你可以修改類別名稱;
開啟app/my_captcha/my_captcha.names修改classes_1為主機想要的名稱即可。

如何檢視create_app_config.py的命令列引數解釋?
直接執行python create_app_config.py便可以在控制檯檢視,下面的程式也是如此。

如果你對darknet相關配置有一定的瞭解,可以直接開啟檔案修改引數的值,這裡我們保持原樣即可。

5.生成樣本

生成樣本使用另外一個專案 nickliqian/generate_click_captcha
這裡我已經整合進去了,執行下面的命令生成樣本和對應標籤到指定應用中yolo規定的目錄:

python3 extend/generate_click_captcha.py my_captcha
複製程式碼

執行python generate_click_captcha.py檢視引數解釋。

6.劃分訓練集和驗證集

執行下面的程式,劃分訓練集和驗證集,同時將標籤的值轉換為yolo認識的格式:

python3 extend/output_label.py my_captcha 1
複製程式碼

這裡填寫的種類需要與上面一致。 執行python output_label.py檢視引數解釋。

7.開始訓練

到這裡,我們要準備的東西還差一樣,我們需要下載darknet提供的預訓練模型放在darknet_captcha目錄下:

wget https://pjreddie.com/media/files/darknet53.conv.74
複製程式碼

darknet_captcha目錄下,執行下面的命令開始訓練:

./darknet/darknet detector train app/my_captcha/my_captcha.data app/my_captcha/my_captcha_train.yolov3.cfg darknet53.conv.74
複製程式碼

訓練過程中模型會每一百次迭代儲存一次,儲存在app/my_captcha/backup/下,可以進行檢視。

8.識別效果

使用GTX 1060訓練大概1.5小時,訓練迭代到1000次,會有比較明顯的效果。

在這裡插入圖片描述
我們找一張驗證集的圖片使用不同進度下的模型進行識別測試,執行下面的語句開始識別:

python3 extend/rec.py my_captcha 100
複製程式碼

這裡的100是選擇app/my_captcha/images_data/JPEGImages目錄下的第一百張圖片進行識別。
執行python rec.py檢視引數解釋。

迭代300次:

在這裡插入圖片描述
迭代800次:
在這裡插入圖片描述
迭代1000次:
在這裡插入圖片描述
迭代1200次:
在這裡插入圖片描述

9.圖片切割

這部分比較簡單,網上有很多示例程式碼,可以呼叫darknet_interface.cut_and_save方法把定位到的字元切割下來。

在這裡插入圖片描述

10.分類器

到分類這一步就比較容易了,可以使用darknet自帶的分類器,也可以使用cnn_captcha一個使用卷積神經網路識別驗證碼的專案。

11.總結

我們識別點選驗證碼的大致流程如下:

  1. 蒐集樣本
  2. 打標籤(標註座標和字元)
  3. 訓練定位器
  4. 檢測位置,切割圖片
  5. 訓練分類器
  6. 使用定位器+分類器識別點選驗證碼上字元的位置和字元類別

第二個例子:多型別目標檢測

步驟和上面基本上一致,直接把命令列出來:

# 生成配置檔案
python3 extend/create_app_config.py dummy_captcha 2
# 生成圖片
python3 extend/generate_click_captcha.py dummy_captcha 500 True
# 輸出標籤到txt
python3 extend/output_label.py dummy_captcha 2
# 開始訓練w
./darknet/darknet detector train app/dummy_captcha/dummy_captcha.data app/dummy_captcha/dummy_captcha_train.yolov3.cfg darknet53.conv.74
# 識別測試
python3 extend/rec.py dummy_captcha 100
複製程式碼

訓練自己的資料

下面的過程教你如何訓練自己資料。
假定我們要建立一個識別路上的車和人的應用,因此類別數量為2。
假定你現在有一些原始圖片,首先你需要給這些圖片打上標籤,推薦使用labelImg進行打標工作。
使用教程可以自行谷歌,軟體介面大致如下:

在這裡插入圖片描述

給圖片中的人和車分別打上person和car的標籤,會生成xml標籤檔案。
接下來,我們建立一個應用,應用名稱是car,類別為2類,同時生成一些配置檔案:

python3 extend/create_app_config.py car 2
複製程式碼

然後把你的原始圖片放到指定的路徑app/car/JPEGImages,把xml標籤檔案放在app/car/Annotations
yolo訓練的時候需要圖片中目標的相對座標,所以這裡需要把xml的座標計算為相對座標的形式。
同時car.data中需要分別定義訓練集和驗證集的樣本路徑,這裡會劃分出訓練集和驗證集,同時生成兩個txt檔案記錄其路徑。

python3 extend/output_label.py car 2
複製程式碼

要提到的是,這裡可以開啟car.names,把裡面的class_1和class_2分別修改為car和person,這裡識別結果就會輸出car和person。 然後就可以開始訓練了:

./darknet/darknet detector train app/car/car.data app/car/car_train.yolov3.cfg darknet53.conv.74
複製程式碼

識別測試和上面也沒有上面區別:

# 識別測試
python3 extend/rec.py car 100
複製程式碼

web服務

啟動web服務:

python3 extend/web_server.py
複製程式碼

啟動前需要按需修改配置引數:

# 生成識別物件,需要配置引數
app_name = "car"  # 應用名稱
config_file = "app/{}/{}_train.yolov3.cfg".format(app_name, app_name)  # 配置檔案路徑
model_file = "app/{}/backup/{}_train.backup".format(app_name, app_name)  # 模型路徑
data_config_file = "app/{}/{}.data".format(app_name, app_name)  # 資料配置檔案路徑
dr = DarknetRecognize(
    config_file=config_file,
    model_file=model_file,
    data_config_file=data_config_file
)
save_path = "api_images"  # 儲存圖片的路徑
複製程式碼

使用下面的指令碼request_api.py進行web服務的識別測試(注意修改圖片路徑):

python3 extend/request_api.py
複製程式碼

返回響應,響應包含目標類別和中心點位置:

介面響應: {
  "speed_time(ms)": 16469, 
  "time": "15472704635706885", 
  "value": [
    [
      "word", 
      0.9995613694190979, 
      [
        214.47508239746094, 
        105.97418212890625, 
        24.86412811279297, 
        33.40662384033203
      ]
    ],
    ...
}
複製程式碼

API文件

暫無

其他問題

使用阿里雲OSS加速下載

如果你使用國外雲主機進行訓練,訓練好的模型的下載速度確實是一個問題。
這裡推薦使用阿里雲oss,在雲主機上把檔案上傳上去,然後使用oss下載下來。
配置祕鑰:

# 從環境變數獲取金鑰
AccessKeyId = os.getenv("AccessKeyId")
AccessKeySecret = os.getenv("AccessKeySecret")
BucketName = os.getenv("BucketName")
複製程式碼

上傳圖片:

python3 extend/upload2oss.py app/my_captcha/images_data/JPEGImages/1_15463317590530567.jpg
python3 extend/upload2oss.py text.jpg
複製程式碼

GPU雲推薦

使用租用 vectordash GPU雲主機,ssh連線整合了Nvidia深度學習環境的ubuntu16.04系統
包含以下工具或框架:

CUDA 9.0, cuDNN, Tensorflow, PyTorch, Caffe, Keras
複製程式碼

vectordash提供了一個客戶端,具備遠端連線、上傳和下載檔案、管理多個雲主機等。
下面是幾種顯示卡的租用價格:

在這裡插入圖片描述
建立例項後,皮膚會提供一個祕鑰,輸入祕鑰後,就可以使用客戶端操作了:

# 安裝客戶端
pip install vectordash --upgrade
# 登入
vectordash login
# 列出主機
vectordash list
# ssh登入
vectordash ssh <instance_id>
# 開啟jupyter
vectordash jupyter <instance_id>
# 上傳檔案
vectordash push <instance_id> <from_path> <to_path>
# 下載檔案
vectordash pull <instance_id> <from_path> <to_path>
複製程式碼

由於vectordash主機在國外,所以上傳和下載都很慢,建議臨時租用一臺阿里雲競價突發型例項(約7分錢一小時)作為中轉使用。

CPU和GPU識別速度對比

GTX 1060, 識別耗時1s

[load model] speed time: 4.691879987716675s
[detect image - i] speed time: 1.002530813217163s
複製程式碼

CPU, 識別耗時13s

[load model] speed time: 3.313053846359253s
[detect image - i] speed time: 13.256595849990845s
複製程式碼

報錯解決辦法

  1. UnicodeEncodeError: 'ascii' codec can't encode character '\U0001f621' in posit
    參考連結
  2. pip install, locale.Error: unsupported locale setting
    參考連結

TODO

  1. 支援多類別檢測的識別和訓練 Done
  2. WebServer API呼叫 Done
  3. 分類器

相關文章