PPv3-OCR自定義資料從訓練到部署

語言: CN / TW / HK

持續創作,加速成長!這是我參與「掘金日新計劃 · 10 月更文挑戰」的第3天,點選檢視活動詳情

最近一段時間使用PaddleOCR做了一個OCR相關的專案,本文記錄一下專案的實現過程。由於資料集是公司的真是資料,不方便公開,我從網上搜集了一些資料集,給大家做演示。PaddleOCR用的最新的PaddleOCR-release-2.5,模型用的v3模型。

一、配置Paddle環境

建立虛擬環境

bash conda create --name pp python=3.7

image-20220412070356738

建立完成後啟用環境

Python conda activate pp

image-20220412070519667

登入飛槳的官網下載最新的paddle,官網地址:飛槳PaddlePaddle-源於產業實踐的開源深度學習平臺

選擇合適的CUDA版本,然後會在下面生成對應的命令。

image-20220412070703940

然後,複製命令即可

bash conda install paddlepaddle-gpu==2.2.2 cudatoolkit=11.2 -c https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/Paddle/ -c conda-forge

二、配置PaddleOCR

下載地址:(https://gitee.com/paddlepaddle/PaddleOCR

將其下載到本地,然後解壓配置環境。

1、安裝python包

1、yaml

pip install pyyaml

2、imgaug

pip install imgaug

3、pyclipper

pip install pyclipper

4、lmdb

pip install lmdb

5、Levenshtein

pip install Levenshtein

6、tqdm

pip install tqdm

2、測試環境

| 模型簡介 | 模型名稱 | 推薦場景 | 檢測模型 | 方向分類器 | 識別模型 | | ------------------------------------- | ----------------------- | --------------- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | | 中英文超輕量PP-OCRv3模型(16.2M) | ch_PP-OCRv3_xx | 移動端&伺服器端 | 推理模型 / 訓練模型 | 推理模型 / 訓練模型 | 推理模型 / 訓練模型 | | 英文超輕量PP-OCRv3模型(13.4M) | en_PP-OCRv3_xx | 移動端&伺服器端 | 推理模型 / 訓練模型 | 推理模型 / 訓練模型 | 推理模型 / 訓練模型 | | 中英文超輕量PP-OCRv2模型(13.0M) | ch_PP-OCRv2_xx | 移動端&伺服器端 | 推理模型 / 訓練模型 | 推理模型 / 預訓練模型 | 推理模型 / 訓練模型 | | 中英文超輕量PP-OCR mobile模型(9.4M) | ch_ppocr_mobile_v2.0_xx | 移動端&伺服器端 | 推理模型 / 預訓練模型 | 推理模型 / 預訓練模型 | 推理模型 / 預訓練模型 | | 中英文通用PP-OCR server模型(143.4M) | ch_ppocr_server_v2.0_xx | 伺服器端 | 推理模型 / 預訓練模型 | 推理模型 / 預訓練模型 | 推理模型 / 預訓練模型 |

選擇上面的一組模型放入到inference資料夾中,注意:是一組,包括:監測模型、方向分類器、識別模型。如下:

```Python PaddleOCR-release-2.5 └─inference ├─ch_PP-OCRv3_det_infer #檢測模型 │ ├─inference.pdiparams │ ├─inference.pdiparams.info │ └─inference.pdmodel ├─ch_PP-OCRv3_rec_infer #識別模型 │ ├─inference.pdiparams │ ├─inference.pdiparams.info │ └─inference.pdmodel └─cls #方向分類器 ├─inference.pdiparams ├─inference.pdiparams.info └─inference.pdmodel

```

在這裡插入圖片描述

將待檢測的圖片放在./doc/imgs/資料夾下面,然後執行命令:

bash python tools/infer/predict_system.py --image_dir="./doc/imgs/0.jpg" --det_model_dir="./inference/ch_PP-OCRv3_det_infer/" --cls_model_dir="./inference/cls/" --rec_model_dir="./inference/ch_PP-OCRv3_rec_infer/" --use_angle_cls=true

然後在inference_results資料夾中檢視結果,例如:

image-20220413103556318

如果能看到結果就說明環境是ok的。

更多的命令,如下:

```python

使用方向分類器

python3 tools/infer/predict_system.py --image_dir="./doc/imgs/00018069.jpg" --det_model_dir="./ch_PP-OCRv3_det_infer/" --cls_model_dir="./cls/" --rec_model_dir="./ch_PP-OCRv3_rec_infer/" --use_angle_cls=true --rec_image_shape=3,48,320

不使用方向分類器

python3 tools/infer/predict_system.py --image_dir="./doc/imgs/00018069.jpg" --det_model_dir="./ch_PP-OCRv3_det_infer/" --rec_model_dir="./ch_PP-OCRv3_rec_infer/" --use_angle_cls=false --rec_image_shape=3,48,320

使用多程序

python3 tools/infer/predict_system.py --image_dir="./doc/imgs/00018069.jpg" --det_model_dir="./ch_PP-OCRv3_det_infer/" --rec_model_dir="./ch_PP-OCRv3_rec_infer/" --use_angle_cls=false --use_mp=True --total_process_num=6 --rec_image_shape=3,48,320

``` 也可以新建test.py指令碼進行測試,系統會自動下載預訓練模型,程式碼如下:

```python import cv2

from paddleocr import PaddleOCR, draw_ocr

Paddleocr目前支援的多語言語種可以通過修改lang引數進行切換

例如ch, en, fr, german, korean, japan

ocr = PaddleOCR(use_angle_cls=True, lang="ch") # need to run only once to download and load model into memory img_path = './doc/imgs_en/img_10.jpg' result = ocr.ocr(img_path, cls=True) for line in result: print(line)

顯示結果

from PIL import Image image = Image.open(img_path).convert('RGB') boxes = [line[0] for line in result] txts = [line[1][0] for line in result] scores = [line[1][1] for line in result] im_show = draw_ocr(image, boxes, txts, scores, font_path='./fonts/simfang.ttf') im_show = Image.fromarray(im_show) im_show.save('result.jpg') ``` 開始執行: 在這裡插入圖片描述 紅框的位置顯示了詳細的配置資訊。 檢視結果: 在這裡插入圖片描述 ocr.ocr(img_path, cls=True)這個方法不僅支援傳入圖片的路徑,還支援ndarray和list型別。比如傳入ndarray

```python import cv2

from paddleocr import PaddleOCR, draw_ocr

Paddleocr目前支援的多語言語種可以通過修改lang引數進行切換

例如ch, en, fr, german, korean, japan

ocr = PaddleOCR(use_angle_cls=True, lang="ch") # need to run only once to download and load model into memory img_path = './doc/imgs_en/img_10.jpg'

第一種使用讀入圖片轉為ndarray

from PIL import Image import numpy as np img = Image.open(img_path) img = np.array(img) result = ocr.ocr(img, cls=True)

第二種使用cv2讀入圖片。

img=cv2.imread(img_path) img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) result = ocr.ocr(img, cls=True) ``` 上面這兩種方式都是可以的,大家自行嘗試。

三 模型列表及其對應的配置檔案

1. 文字檢測模型

1.1 中文檢測模型

| 模型名稱 | 模型簡介 | 配置檔案 | 推理模型大小 | 下載地址 | | ----------------------------- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------ | ------------------------------------------------------------ | | ch_PP-OCRv3_det_slim | 【最新】slim量化+蒸餾版超輕量模型,支援中英文、多語種文字檢測 | ch_PP-OCRv3_det_cml.yml | 1.1M | 推理模型 / 訓練模型 / nb模型 | | ch_PP-OCRv3_det | 【最新】原始超輕量模型,支援中英文、多語種文字檢測 | ch_PP-OCRv3_det_cml.yml | 3.8M | 推理模型 / 訓練模型 | | ch_PP-OCRv2_det_slim | slim量化+蒸餾版超輕量模型,支援中英文、多語種文字檢測 | ch_PP-OCRv2_det_cml.yml | 3M | 推理模型 | | ch_PP-OCRv2_det | 原始超輕量模型,支援中英文、多語種文字檢測 | ch_PP-OCRv2_det_cml.yml | 3M | 推理模型 / 訓練模型 | | ch_ppocr_mobile_slim_v2.0_det | slim裁剪版超輕量模型,支援中英文、多語種文字檢測 | ch_det_mv3_db_v2.0.yml | 2.6M | 推理模型 | | ch_ppocr_mobile_v2.0_det | 原始超輕量模型,支援中英文、多語種文字檢測 | ch_det_mv3_db_v2.0.yml | 3M | 推理模型 / 訓練模型 | | ch_ppocr_server_v2.0_det | 通用模型,支援中英文、多語種文字檢測,比超輕量模型更大,但效果更好 | ch_det_res18_db_v2.0.yml | 47M | 推理模型 / 訓練模型 |

1.2 英文檢測模型

| 模型名稱 | 模型簡介 | 配置檔案 | 推理模型大小 | 下載地址 | | -------------------- | ------------------------------------------------ | ------------------------------------------------------------ | ------------ | ------------------------------------------------------------ | | en_PP-OCRv3_det_slim | 【最新】slim量化版超輕量模型,支援英文、數字檢測 | ch_PP-OCRv3_det_cml.yml | 1.1M | 推理模型 / 訓練模型 / nb模型 | | en_PP-OCRv3_det | 【最新】原始超輕量模型,支援英文、數字檢測 | ch_PP-OCRv3_det_cml.yml | 3.8M | 推理模型 / 訓練模型 |

  • 注:英文檢測模型與中文檢測模型結構完全相同,只有訓練資料不同,在此僅提供相同的配置檔案。

1.3 多語言檢測模型

| 模型名稱 | 模型簡介 | 配置檔案 | 推理模型大小 | 下載地址 | | -------------------- | -------------------------------------------- | ------------------------------------------------------------ | ------------ | ------------------------------------------------------------ | | ml_PP-OCRv3_det_slim | 【最新】slim量化版超輕量模型,支援多語言檢測 | ch_PP-OCRv3_det_cml.yml | 1.1M | 推理模型 / 訓練模型 / nb模型 | | ml_PP-OCRv3_det | 【最新】原始超輕量模型,支援多語言檢測 | ch_PP-OCRv3_det_cml.yml | 3.8M | 推理模型 / 訓練模型 |

  • 注:多語言檢測模型與中文檢測模型結構完全相同,只有訓練資料不同,在此僅提供相同的配置檔案。

2. 文字識別模型

2.1 中文識別模型

| 模型名稱 | 模型簡介 | 配置檔案 | 推理模型大小 | 下載地址 | | ----------------------------- | -------------------------------------------------- | ------------------------------------------------------------ | ------------ | ------------------------------------------------------------ | | ch_PP-OCRv3_rec_slim | 【最新】slim量化版超輕量模型,支援中英文、數字識別 | ch_PP-OCRv3_rec_distillation.yml | 4.9M | 推理模型 / 訓練模型 / nb模型 | | ch_PP-OCRv3_rec | 【最新】原始超輕量模型,支援中英文、數字識別 | ch_PP-OCRv3_rec_distillation.yml | 12.4M | 推理模型 / 訓練模型 | | ch_PP-OCRv2_rec_slim | slim量化版超輕量模型,支援中英文、數字識別 | ch_PP-OCRv2_rec.yml | 9M | 推理模型 / 訓練模型 | | ch_PP-OCRv2_rec | 原始超輕量模型,支援中英文、數字識別 | ch_PP-OCRv2_rec_distillation.yml | 8.5M | 推理模型 / 訓練模型 | | ch_ppocr_mobile_slim_v2.0_rec | slim裁剪量化版超輕量模型,支援中英文、數字識別 | rec_chinese_lite_train_v2.0.yml | 6M | 推理模型 / 訓練模型 | | ch_ppocr_mobile_v2.0_rec | 原始超輕量模型,支援中英文、數字識別 | rec_chinese_lite_train_v2.0.yml | 5.2M | 推理模型 / 訓練模型 / 預訓練模型 | | ch_ppocr_server_v2.0_rec | 通用模型,支援中英文、數字識別 | rec_chinese_common_train_v2.0.yml | 94.8M | 推理模型 / 訓練模型 / 預訓練模型 |

說明: 訓練模型是基於預訓練模型在真實資料與豎排合成文字資料上finetune得到的模型,在真實應用場景中有著更好的表現,預訓練模型則是直接基於全量真實資料與合成數據訓練得到,更適合用於在自己的資料集上finetune。

2.2 英文識別模型

| 模型名稱 | 模型簡介 | 配置檔案 | 推理模型大小 | 下載地址 | | ------------------------------ | ------------------------------------------------ | ------------------------------------------------------------ | ------------ | ------------------------------------------------------------ | | en_PP-OCRv3_rec_slim | 【最新】slim量化版超輕量模型,支援英文、數字識別 | en_PP-OCRv3_rec.yml | 3.2M | 推理模型 / 訓練模型 / nb模型 | | en_PP-OCRv3_rec | 【最新】原始超輕量模型,支援英文、數字識別 | en_PP-OCRv3_rec.yml | 9.6M | 推理模型 / 訓練模型 | | en_number_mobile_slim_v2.0_rec | slim裁剪量化版超輕量模型,支援英文、數字識別 | rec_en_number_lite_train.yml | 2.7M | 推理模型 / 訓練模型 | | en_number_mobile_v2.0_rec | 原始超輕量模型,支援英文、數字識別 | rec_en_number_lite_train.yml | 2.6M | 推理模型 / 訓練模型 |

2.3 多語言識別模型(更多語言持續更新中...)

| 模型名稱 | 字典檔案 | 模型簡介 | 配置檔案 | 推理模型大小 | 下載地址 | | ------------------------ | ------------------------------------- | ------------ | ------------------------------------------------------------ | ------------ | ------------------------------------------------------------ | | korean_PP-OCRv3_rec | ppocr/utils/dict/korean_dict.txt | 韓文識別 | korean_PP-OCRv3_rec.yml | 11M | 推理模型 / 訓練模型 | | japan_PP-OCRv3_rec | ppocr/utils/dict/japan_dict.txt | 日文識別 | japan_PP-OCRv3_rec.yml | 11M | 推理模型 / 訓練模型 | | chinese_cht_PP-OCRv3_rec | ppocr/utils/dict/chinese_cht_dict.txt | 中文繁體識別 | chinese_cht_PP-OCRv3_rec.yml | 12M | 推理模型 / 訓練模型 | | te_PP-OCRv3_rec | ppocr/utils/dict/te_dict.txt | 泰盧固文識別 | te_PP-OCRv3_rec.yml | 9.6M | 推理模型 / 訓練模型 | | ka_PP-OCRv3_rec | ppocr/utils/dict/ka_dict.txt | 卡納達文識別 | ka_PP-OCRv3_rec.yml | 9.9M | 推理模型 / 訓練模型 | | ta_PP-OCRv3_rec | ppocr/utils/dict/ta_dict.txt | 泰米爾文識別 | ta_PP-OCRv3_rec.yml | 9.6M | 推理模型 / 訓練模型 | | latin_PP-OCRv3_rec | ppocr/utils/dict/latin_dict.txt | 拉丁文識別 | latin_PP-OCRv3_rec.yml | 9.7M | 推理模型 / 訓練模型 | | arabic_PP-OCRv3_rec | ppocr/utils/dict/arabic_dict.txt | 阿拉伯字母 | arabic_PP-OCRv3_rec.yml | 9.6M | 推理模型 / 訓練模型 | | cyrillic_PP-OCRv3_rec | ppocr/utils/dict/cyrillic_dict.txt | 斯拉夫字母 | cyrillic_PP-OCRv3_rec.yml | 9.6M | 推理模型 / 訓練模型 | | devanagari_PP-OCRv3_rec | ppocr/utils/dict/devanagari_dict.txt | 梵文字母 | devanagari_PP-OCRv3_rec.yml | 9.9M | 推理模型 / 訓練模型 |

檢視完整語種列表與使用教程請參考: 多語言模型

3. 文字方向分類模型

| 模型名稱 | 模型簡介 | 配置檔案 | 推理模型大小 | 下載地址 | | ----------------------------- | -------------------------------------------- | ------------------------------------------------------------ | ------------ | ------------------------------------------------------------ | | ch_ppocr_mobile_slim_v2.0_cls | slim量化版模型,對檢測到的文字行文字角度分類 | cls_mv3.yml | 2.1M | 推理模型 / 訓練模型 / nb模型 | | ch_ppocr_mobile_v2.0_cls | 原始分類器模型,對檢測到的文字行文字角度分類 | | | |

四、標註工具PPOCRLabel

PPOCRLabel是一款適用於OCR領域的半自動化圖形標註工具,內建PP-OCR模型對資料自動標註和重新識別。使用Python3和PyQT5編寫,支援矩形框標註和四點標註模式,匯出格式可直接用於PaddleOCR檢測和識別模型的訓練。

由於PaddleOCR已經包含PPOCRLabel,可以直接執行,命令如下:

cd ./PPOCRLabel # 切換到PPOCRLabel目錄 python PPOCRLabel.py --lang ch

image-20220413104711288

點選自動標註後就能看到自動標註的結果,使用者根據自己的需求微調和修改,非常簡單。 如果標註的結果和自己預想的差別比較大,可以在標註一定量的資料集後,使用標註的資料集訓練出來一個模型,用來替換官方的模型。模型位置: 在這裡插入圖片描述 上圖是我的模型的位置,大家可以試著找找自己模型的位置。 更多的方式和注意事項,詳見下面

1. 安裝與執行

1.1 安裝PaddlePaddle

```bash pip3 install --upgrade pip

如果您的機器安裝的是CUDA9或CUDA10,請執行以下命令安裝

python3 -m pip install paddlepaddle-gpu -i https://mirror.baidu.com/pypi/simple

如果您的機器是CPU,請執行以下命令安裝

python3 -m pip install paddlepaddle -i https://mirror.baidu.com/pypi/simple ```

更多的版本需求,請參照安裝文件中的說明進行操作。

1.2 安裝與執行PPOCRLabel

PPOCRLabel可通過whl包與Python指令碼兩種方式啟動,whl包形式啟動更加方便,python指令碼啟動便於二次開發

1.2.1 通過whl包安裝與執行

Windows

bash pip install PPOCRLabel # 安裝 PPOCRLabel --lang ch # 執行

注意:通過whl包安裝PPOCRLabel會自動下載 paddleocr whl包,其中shapely依賴可能會出現 [winRrror 126] 找不到指定模組的問題。 的錯誤,建議從這裡下載並安裝

Ubuntu Linux

bash pip3 install PPOCRLabel pip3 install trash-cli PPOCRLabel --lang ch

MacOS

bash pip3 install PPOCRLabel pip3 install opencv-contrib-python-headless==4.2.0.32 # 如果下載過慢請新增"-i https://mirror.baidu.com/pypi/simple" PPOCRLabel --lang ch # 啟動

如果上述安裝出現問題,可以參考3.6節 錯誤提示

1.2.2 本地構建whl包並安裝

bash cd PaddleOCR/PPOCRLabel python3 setup.py bdist_wheel pip3 install dist/PPOCRLabel-1.0.2-py2.py3-none-any.whl -i https://mirror.baidu.com/pypi/simple

1.2.3 通過Python指令碼執行PPOCRLabel

如果您對PPOCRLabel檔案有所更改,通過Python指令碼執行會更加方面的看到更改的結果

bash cd ./PPOCRLabel # 切換到PPOCRLabel目錄 python PPOCRLabel.py --lang ch

2. 使用

2.1 操作步驟

  1. 安裝與執行:使用上述命令安裝與執行程式。
  2. 開啟資料夾:在選單欄點選 “檔案” - "開啟目錄" 選擇待標記圖片的資料夾[1].
  3. 自動標註:點選 ”自動標註“,使用PPOCR超輕量模型對圖片檔名前圖片狀態[2]為 “X” 的圖片進行自動標註。
  4. 手動標註:點選 “矩形標註”(推薦直接在英文模式下點選鍵盤中的 “W”),使用者可對當前圖片中模型未檢出的部分進行手動繪製標記框。點選鍵盤Q,則使用四點標註模式(或點選“編輯” - “四點標註”),使用者依次點選4個點後,雙擊左鍵表示標註完成。
  5. 標記框繪製完成後,使用者點選 “確認”,檢測框會先被預分配一個 “待識別” 標籤。
  6. 重新識別:將圖片中的所有檢測畫繪製/調整完成後,點選 “重新識別”,PPOCR模型會對當前圖片中的所有檢測框重新識別[3]。
  7. 內容更改:雙擊識別結果,對不準確的識別結果進行手動更改。
  8. 確認標記:點選 “確認”,圖片狀態切換為 “√”,跳轉至下一張。
  9. 刪除:點選 “刪除影象”,圖片將會被刪除至回收站。
  10. 匯出結果:使用者可以通過選單中“檔案-匯出標記結果”手動匯出,同時也可以點選“檔案 - 自動匯出標記結果”開啟自動匯出。手動確認過的標記將會被存放在所開啟圖片資料夾下的Label.txt中。在選單欄點選 “檔案” - "匯出識別結果"後,會將此類圖片的識別訓練資料儲存在crop_img資料夾下,識別標籤儲存在rec_gt.txt中[4]。

2.2 注意

[1] PPOCRLabel以資料夾為基本標記單位,開啟待標記的圖片資料夾後,不會在視窗欄中顯示圖片,而是在點選 "選擇資料夾" 之後直接將資料夾下的圖片匯入到程式中。

[2] 圖片狀態表示本張圖片使用者是否手動儲存過,未手動儲存過即為 “X”,手動儲存過為 “√”。點選 “自動標註”按鈕後,PPOCRLabel不會對狀態為 “√” 的圖片重新標註。

[3] 點選“重新識別”後,模型會對圖片中的識別結果進行覆蓋。因此如果在此之前手動更改過識別結果,有可能在重新識別後產生變動。

[4] PPOCRLabel產生的檔案放置於標記圖片資料夾下,包括一下幾種,請勿手動更改其中內容,否則會引起程式出現異常。

| 檔名 | 說明 | | ------------- | ------------------------------------------------------------ | | Label.txt | 檢測標籤,可直接用於PPOCR檢測模型訓練。使用者每確認5張檢測結果後,程式會進行自動寫入。當用戶關閉應用程式或切換檔案路徑後同樣會進行寫入。 | | fileState.txt | 圖片狀態標記檔案,儲存當前資料夾下已經被使用者手動確認過的圖片名稱。 | | Cache.cach | 快取檔案,儲存模型自動識別的結果。 | | rec_gt.txt | 識別標籤。可直接用於PPOCR識別模型訓練。需使用者手動點選選單欄“檔案” - "匯出識別結果"後產生。 | | crop_img | 識別資料。按照檢測框切割後的圖片。與rec_gt.txt同時產生。 |

3. 說明

3.1 快捷鍵

| 快捷鍵 | 說明 | | ---------------- | ---------------------------- | | Ctrl + shift + R | 對當前圖片的所有標記重新識別 | | W | 新建矩形框 | | Q | 新建四點框 | | Ctrl + E | 編輯所選框標籤 | | Ctrl + R | 重新識別所選標記 | | Ctrl + C | 複製並貼上選中的標記框 | | Ctrl + 滑鼠左鍵 | 多選標記框 | | Backspace | 刪除所選框 | | Ctrl + V | 確認本張圖片標記 | | Ctrl + Shift + d | 刪除本張圖片 | | D | 下一張圖片 | | A | 上一張圖片 | | Ctrl++ | 縮小 | | Ctrl-- | 放大 | | ↑→↓← | 移動標記框 |

3.2 內建模型

  • 預設模型:PPOCRLabel預設使用PaddleOCR中的中英文超輕量OCR模型,支援中英文與數字識別,多種語言檢測。
  • 模型語言切換:使用者可通過選單欄中 "PaddleOCR" - "選擇模型" 切換內建模型語言,目前支援的語言包括法文、德文、韓文、日文。具體模型下載連結可參考PaddleOCR模型列表.
  • 自定義模型:如果使用者想將內建模型更換為自己的推理模型,可根據自定義模型程式碼使用,通過修改PPOCRLabel.py中針對PaddleOCR類的例項化,通過修改PPOCRLabel.py中針對PaddleOCR類的例項化) 實現,例如指定檢測模型:self.ocr = PaddleOCR(det=True, cls=True, use_gpu=gpu, lang=lang),在 det_model_dir 中傳入 自己的模型即可。

3.3 匯出標記結果

PPOCRLabel支援三種匯出方式:

  • 自動匯出:點選“檔案 - 自動匯出標記結果”後,使用者每確認過一張圖片,程式自動將標記結果寫入Label.txt中。若未開啟此選項,則檢測到使用者手動確認過5張圖片後進行自動匯出。

預設情況下自動匯出功能為關閉狀態

  • 手動匯出:點選“檔案 - 匯出標記結果”手動匯出標記。

  • 關閉應用程式匯出

3.4 匯出部分識別結果

針對部分難以識別的資料,通過在識別結果的複選框中取消勾選相應的標記,其識別結果不會被匯出。被取消勾選的識別結果在標記檔案 label.txt 中的 difficult 變數儲存為 True

注意:識別結果中的複選框狀態仍需使用者手動點選確認後才能保留

3.5 資料集劃分

在終端中輸入以下命令執行資料集劃分指令碼:

cd ./PPOCRLabel # 將目錄切換到PPOCRLabel資料夾下 python gen_ocr_train_val_test.py --trainValTestRatio 6:2:2 --datasetRootPath ../train_data

引數說明:

  • trainValTestRatio 是訓練集、驗證集、測試集的影象數量劃分比例,根據實際情況設定,預設是6:2:2

  • datasetRootPath 是PPOCRLabel標註的完整資料集存放路徑。預設路徑是 PaddleOCR/train_data 分割資料集前應有如下結構:

|-train_data |-crop_img |- word_001_crop_0.png |- word_002_crop_0.jpg |- word_003_crop_0.jpg | ... | Label.txt | rec_gt.txt |- word_001.png |- word_002.jpg |- word_003.jpg | ...

3.6 錯誤提示

  • 如果同時使用whl包安裝了paddleocr,其優先順序大於通過paddleocr.py呼叫PaddleOCR類,whl包未更新時會導致程式異常。

  • PPOCRLabel不支援對中文檔名的圖片進行自動標註。

  • 針對Linux使用者:如果您在開啟軟體過程中出現objc[XXXXX]開頭的錯誤,證明您的opencv版本太高,建議安裝4.2版本:

pip install opencv-python==4.2.0.32

  • 如果出現 Missing string id 開頭的錯誤,需要重新編譯資源:

pyrcc5 -o libs/resources.py resources.qrc

  • 如果出現module 'cv2' has no attribute 'INTER_NEAREST'錯誤,需要首先刪除所有opencv相關包,然後重新安裝4.2.0.32版本的headless opencv

pip install opencv-contrib-python-headless==4.2.0.32

五、訓練檢測器

1、製作資料集

完成資料的標註就可以看是訓練檢測器了。找到Lable.txt,將其中一部分放到train_label.txt ,將一部分放到test_label.txt,將圖片放到ppocr(這個資料夾的名字和標註時的圖片資料夾的名字一致),如下:

image-20220413105738547

PaddleOCR-release-2.5/train_data/icdar2015/text_localization/ └─ ppocr/ 圖片存放的位置 └─ train_label.txt icdar資料集的訓練標註 └─ test_label.txt icdar資料集的測試標註 在這裡插入圖片描述

自定義切分資料集程式碼。我在這裡沒有使用官方給的切分方式,是自定義的切分方式。

```python import os import shutil from sklearn.model_selection import train_test_split

label_txt='./ppocr/Label.txt' #標註資料的路徑 if not os.path.exists('tmp'): os.makedirs('tmp') with open(label_txt, 'r') as f: txt_List=f.readlines() trainval_files, val_files = train_test_split(txt_List, test_size=0.1, random_state=42) print(trainval_files) f = open("train_label.txt", "w") f.writelines(trainval_files) f.close() f = open("test_label.txt", "w") f.writelines(val_files) f.close() for txt in txt_List: image_name=txt.split('\t')[0] new_path="./tmp/"+image_name.split('/')[1] shutil.move(image_name, new_path) print(image_name) ```

如果路徑不存在,請手動建立。執行完成後將tmp資料夾裡面的圖片放到PaddleOCR-release-2.5/train_data/icdar2015/text_localization/ppocr/資料夾下面。如果不存在則自己建立。

2、下載預訓練模型

然後下載預訓練模型,將其放到pretrain_models資料夾中,命令如下:

```Python

根據backbone的不同選擇下載對應的預訓練模型

下載MobileNetV3的預訓練模型

wget -P ./pretrain_models/ https://paddleocr.bj.bcebos.com/pretrained/MobileNetV3_large_x0_5_pretrained.pdparams

或,下載ResNet18_vd的預訓練模型

wget -P ./pretrain_models/ https://paddleocr.bj.bcebos.com/pretrained/ResNet18_vd_pretrained.pdparams

或,下載ResNet50_vd的預訓練模型

wget -P ./pretrain_models/ https://paddleocr.bj.bcebos.com/pretrained/ResNet50_vd_ssld_pretrained.pdparams ``` 不同的預訓練模型對應不同的配置檔案,詳見第3節。 這次我選用如下圖的配置: 在這裡插入圖片描述

3、修改配置檔案

然後修改該config檔案,路徑: configs/det/ch_PP-OCRv3/ch_PP-OCRv3_det_cml.yml,開啟檔案對裡面的引數進行修改該。

image-20220413111032194

按照自己定義的路徑,修改訓練集的路徑。

image-20220413111551032

按照自己定義的路徑,修改驗證集的路徑。

image-20220413111820352 對BatchSize的修改。 如果訓練出來的檢測框偏小,可以修改引數unclip_ratio,將其調大即可。 在這裡插入圖片描述

4、開啟訓練

完成上面的工作就可以啟動訓練了,在pycharm的Terminal中輸入命令:

注意:在PaddleOCR的根目錄執行命令。

```

單機單卡訓練

python tools/train.py -c configs/det/ch_PP-OCRv3/ch_PP-OCRv3_det_cml.yml -o Global.pretrained_model=./pretrain_models/

``` 在這裡插入圖片描述

更多的訓練方式如下:

```shell

單機單卡訓練 mv3_db 模型

python3 tools/train.py -c configs/det/det_mv3_db.yml \ -o Global.pretrained_model=./pretrain_models/MobileNetV3_large_x0_5_pretrained

單機多卡訓練,通過 --gpus 引數設定使用的GPU ID

python3 -m paddle.distributed.launch --gpus '0,1,2,3' tools/train.py -c configs/det/det_mv3_db.yml \ -o Global.pretrained_model=./pretrain_models/MobileNetV3_large_x0_5_pretrained

多機多卡訓練,通過 --ips 引數設定使用的機器IP地址,通過 --gpus 引數設定使用的GPU ID

python3 -m paddle.distributed.launch --ips="xx.xx.xx.xx,xx.xx.xx.xx" --gpus '0,1,2,3' tools/train.py -c configs/det/det_mv3_db.yml \ -o Global.pretrained_model=./pretrain_models/MobileNetV3_large_x0_5_pretrained ```

4.1、 斷點訓練

如果訓練程式中斷,如果希望載入訓練中斷的模型從而恢復訓練,可以通過指定Global.checkpoints指定要載入的模型路徑:

shell python3 tools/train.py -c configs/det/det_mv3_db.yml -o Global.checkpoints=./your/trained/model

注意Global.checkpoints的優先順序高於Global.pretrained_model的優先順序,即同時指定兩個引數時,優先載入Global.checkpoints指定的模型,如果Global.checkpoints指定的模型路徑有誤,會載入Global.pretrained_model指定的模型。

4.2 混合精度訓練

如果您想進一步加快訓練速度,可以使用自動混合精度訓練, 以單機單卡為例,命令如下:

shell python3 tools/train.py -c configs/det/det_mv3_db.yml -o Global.pretrained_model=./pretrain_models/MobileNetV3_large_x0_5_pretrained Global.use_amp=True Global.scale_loss=1024.0 Global.use_dynamic_loss_scaling=True

4.3 分散式訓練

多機多卡訓練時,通過 --ips 引數設定使用的機器IP地址,通過 --gpus 引數設定使用的GPU ID:

bash python3 -m paddle.distributed.launch --ips="xx.xx.xx.xx,xx.xx.xx.xx" --gpus '0,1,2,3' tools/train.py -c configs/det/det_mv3_db.yml -o Global.pretrained_model=./pretrain_models/MobileNetV3_large_x0_5_pretrained

注意: 採用多機多卡訓練時,需要替換上面命令中的ips值為您機器的地址,機器之間需要能夠相互ping通。另外,訓練時需要在多個機器上分別啟動命令。檢視機器ip地址的命令為ifconfig。 分散式訓練,我沒有試過,主要是沒有鈔能力。

5、 模型評估與預測

5.1 指標評估

PaddleOCR計算三個OCR檢測相關的指標,分別是:Precision、Recall、Hmean(F-Score)。

訓練中模型引數預設儲存在Global.save_model_dir目錄下。在評估指標時,需要設定Global.checkpoints指向儲存的引數檔案。

shell python tools/eval.py -c configs/det/det_mv3_db.yml -o Global.checkpoints="{path/to/weights}/best_accuracy"

5.2 測試檢測效果

測試單張影象的檢測效果:

shell python3 tools/infer_det.py -c configs/det/det_mv3_db.yml -o Global.infer_img="./doc/imgs_en/img_10.jpg" Global.pretrained_model="./output/det_db/best_accuracy"

測試DB模型時,調整後處理閾值:

shell python3 tools/infer_det.py -c configs/det/det_mv3_db.yml -o Global.infer_img="./doc/imgs_en/img_10.jpg" Global.pretrained_model="./output/det_db/best_accuracy" PostProcess.box_thresh=0.6 PostProcess.unclip_ratio=2.0 - 注:box_threshunclip_ratio是DB後處理引數,其他檢測模型不支援。

測試資料夾下所有影象的檢測效果: shell python3 tools/infer_det.py -c configs/det/det_mv3_db.yml -o Global.infer_img="./doc/imgs_en/" Global.pretrained_model="./output/det_db/best_accuracy"

6. 模型匯出與預測

inference 模型(paddle.jit.save儲存的模型) 一般是模型訓練,把模型結構和模型引數儲存在檔案中的固化模型,多用於預測部署場景。 訓練過程中儲存的模型是checkpoints模型,儲存的只有模型的引數,多用於恢復訓練等。 與checkpoints模型相比,inference 模型會額外儲存模型的結構資訊,在預測部署、加速推理上效能優越,靈活方便,適合於實際系統整合。

檢測模型轉inference 模型方式: 官方的例子: ```shell

載入配置檔案det_mv3_db.yml,從output/det_db目錄下載入best_accuracy模型,inference模型儲存在./output/det_db_inference目錄下

python3 tools/export_model.py -c configs/det/det_mv3_db.yml -o Global.pretrained_model="./output/det_db/best_accuracy" Global.save_inference_dir="./output/det_db_inference/" ``` 自己用的命令:

python python tools/export_model.py -c output/db_mv3/config.yml -o Global.pretrained_model="./output/db_mv3/best_accuracy" Global.save_inference_dir="./output/det_db_inference/"

DB檢測模型inference 模型預測:

shell python3 tools/infer/predict_det.py --det_algorithm="DB" --det_model_dir="./output/det_db_inference/" --image_dir="./doc/imgs/" --use_gpu=True

五、訓練識別器

1、圖片裁剪與資料集生成

在訓練識別器之間,我們還有一步要做,就是將標註的資料裁剪出來。裁剪程式碼如下:

```python import json import os import numpy as np import cv2

def get_rotate_crop_image(img, points): ''' img_height, img_width = img.shape[0:2] left = int(np.min(points[:, 0])) right = int(np.max(points[:, 0])) top = int(np.min(points[:, 1])) bottom = int(np.max(points[:, 1])) img_crop = img[top:bottom, left:right, :].copy() points[:, 0] = points[:, 0] - left points[:, 1] = points[:, 1] - top ''' assert len(points) == 4, "shape of points must be 4*2" # 求範數,得到寬度 img_crop_width = int( max( np.linalg.norm(points[0] - points[1]), np.linalg.norm(points[2] - points[3]))) # # 求範數,得到高度
img_crop_height = int( max( np.linalg.norm(points[0] - points[3]), np.linalg.norm(points[1] - points[2]))) pts_std = np.float32([[0, 0], [img_crop_width, 0], [img_crop_width, img_crop_height], [0, img_crop_height]]) #計算得到轉換矩陣
M = cv2.getPerspectiveTransform(points, pts_std) #實現透視變換 dst_img = cv2.warpPerspective( img, M, (img_crop_width, img_crop_height), borderMode=cv2.BORDER_REPLICATE, flags=cv2.INTER_CUBIC) dst_img_height, dst_img_width = dst_img.shape[0:2] if dst_img_height * 1.0 / dst_img_width >= 1.5: dst_img = np.rot90(dst_img) return dst_img def write_txt_img(src_path,label_txt): with open(src_path, 'r', encoding='utf-8') as f: for line in f.readlines(): print(line) content = line.split('\t') print(content[0]) imag_name = content[0].split('/')[1] image_path = './train_data/icdar2015/text_localization/' + content[0] img = cv2.imread(image_path) list_dict = json.loads(content[1]) nsize = len(list_dict) print(nsize) num = 0 for i in range(nsize): print(list_dict[i]) lin = list_dict[i] info = lin['transcription'] info=info.replace(" ","") points = lin['points'] points = [list(x) for x in points] points = np.float32([list(map(float, item)) for item in points]) imag_name=str(num)+"_"+imag_name save_path = './train_data/rec/train/' + imag_name dst_img = get_rotate_crop_image(img, points) cv2.imwrite(save_path, dst_img) label_txt.write('train/'+imag_name+'\t'+info+'\n') num=num+1 if not os.path.exists('train_data/rec/train/'): os.makedirs('train_data/rec/train/') src_path = r"./train_data/icdar2015/text_localization/train_icdar2015_label.txt" label_txt=r"./train_data/rec/rec_gt_train.txt" src_test_path = r"./train_data/icdar2015/text_localization/test_icdar2015_label.txt" label_test_txt=r"./train_data/rec/rec_gt_test.txt" with open(label_txt, 'w') as w_label: write_txt_img(src_path,w_label) with open(label_test_txt, 'w') as w_label: write_txt_img(src_test_path, w_label) ```

獲取標註區域的影象主要用到了getPerspectiveTransform計算轉換的矩陣和warpPerspective函式透視轉換的組合。

獲取到影象和標註的內容,生成文字識別通用資料集(SimpleDataSet)。

資料集的格式:

注意: txt檔案中預設請將圖片路徑和圖片標籤用 \t 分割,如用其他方式分割將造成訓練報錯。

``` " 影象檔名 影象標註資訊 "

train/word_001.jpg 簡單可依賴 train/word_002.jpg 用科技讓複雜的世界更簡單 ```

生成資料集的路徑如下:

image-20220413125927409

2、修改配置檔案

修改配置檔案,在configs/rec/中,用rec_icdar15_train.yml 舉例: image-20220413130338566

設定訓練集的路徑。

image-20220413130421569

設定驗證集的路徑。

image-20220413130450210

調整訓練集和驗證集的圖片尺寸

image-20220413130528283

設定訓練和驗證的batchsize。 在這裡插入圖片描述

設定字典,根據任務不同設定的字典也不同。 內建字典如下:

PaddleOCR內建了一部分字典,可以按需使用。 ppocr/utils/ppocr_keys_v1.txt 是一個包含6623個字元的中文字典 ppocr/utils/ic15_dict.txt 是一個包含36個字元的英文字典 ppocr/utils/dict/french_dict.txt 是一個包含118個字元的法文字典 ppocr/utils/dict/japan_dict.txt 是一個包含4399個字元的日文字典 ppocr/utils/dict/korean_dict.txt 是一個包含3636個字元的韓文字典 ppocr/utils/dict/german_dict.txt 是一個包含131個字元的德文字典 ppocr/utils/en_dict.txt 是一個包含96個字元的英文字典

3、開啟訓練

完成上面的引數的設定,然後開始訓練,命令如下:

shell python tools/train.py -c configs/rec/rec_icdar15_train.yml image-20220413130724004 更多的訓練方式:

```python

單卡訓練(訓練週期長,不建議)

python3 tools/train.py -c configs/rec/PP-OCRv3/en_PP-OCRv3_rec.yml -o Global.pretrained_model=./pretrain_models/en_PP-OCRv3_rec_train/best_accuracy

多卡訓練,通過--gpus引數指定卡號

python3 -m paddle.distributed.launch --gpus '0,1,2,3' tools/train.py -c configs/rec/PP-OCRv3/en_PP-OCRv3_rec.yml -o Global.pretrained_model=./pretrain_models/en_PP-OCRv3_rec_train/best_accuracy ```

3.1、 斷點訓練

如果訓練程式中斷,如果希望載入訓練中斷的模型從而恢復訓練,可以通過指定Global.checkpoints指定要載入的模型路徑:

shell python tools/train.py -c configs/rec/PP-OCRv3/en_PP-OCRv3_rec.yml -o Global.checkpoints=./your/trained/model 例如:

python tools/train.py -c configs/rec/ch_ppocr_v2.0/rec_chinese_common_train_v2.0.yml -o Global.checkpoints=./output/rec_chinese_common_v2.0/best_accuracy best_accuracy指的是紅框中的三個模型。 在這裡插入圖片描述

注意Global.checkpoints的優先順序高於Global.pretrained_model的優先順序,即同時指定兩個引數時,優先載入Global.checkpoints指定的模型,如果Global.checkpoints指定的模型路徑有誤,會載入Global.pretrained_model指定的模型。

3.2、 混合精度訓練

如果您想進一步加快訓練速度,可以使用自動混合精度訓練, 以單機單卡為例,命令如下:

shell python3 tools/train.py -c configs/rec/PP-OCRv3/en_PP-OCRv3_rec.yml \ -o Global.pretrained_model=./pretrain_models/en_PP-OCRv3_rec_train/best_accuracy \ Global.use_amp=True Global.scale_loss=1024.0 Global.use_dynamic_loss_scaling=True

3.3、 分散式訓練

多機多卡訓練時,通過 --ips 引數設定使用的機器IP地址,通過 --gpus 引數設定使用的GPU ID:

bash python3 -m paddle.distributed.launch --ips="xx.xx.xx.xx,xx.xx.xx.xx" --gpus '0,1,2,3' tools/train.py -c configs/rec/PP-OCRv3/en_PP-OCRv3_rec.yml \ -o Global.pretrained_model=./pretrain_models/en_PP-OCRv3_rec_train/best_accuracy

注意: 採用多機多卡訓練時,需要替換上面命令中的ips值為您機器的地址,機器之間需要能夠相互ping通。另外,訓練時需要在多個機器上分別啟動命令。檢視機器ip地址的命令為ifconfig

4 模型評估與預測

4.1、指標評估

訓練中模型引數預設儲存在Global.save_model_dir目錄下。在評估指標時,需要設定Global.checkpoints指向儲存的引數檔案。評估資料集可以通過 configs/rec/PP-OCRv3/en_PP-OCRv3_rec.yml 修改Eval中的 label_file_path 設定。

```

GPU 評估, Global.checkpoints 為待測權重

python -m paddle.distributed.launch --gpus '0' tools/eval.py -c configs/rec/PP-OCRv3/en_PP-OCRv3_rec.yml -o Global.checkpoints={path/to/weights}/best_accuracy ```

4.2、測試識別效果

使用 PaddleOCR 訓練好的模型,可以通過以下指令碼進行快速預測。

預設預測圖片儲存在 infer_img 裡,通過 -o Global.checkpoints 載入訓練好的引數檔案:

根據配置檔案中設定的 save_model_dirsave_epoch_step 欄位,會有以下幾種引數被儲存下來:

output/rec/ ├── best_accuracy.pdopt ├── best_accuracy.pdparams ├── best_accuracy.states ├── config.yml ├── iter_epoch_3.pdopt ├── iter_epoch_3.pdparams ├── iter_epoch_3.states ├── latest.pdopt ├── latest.pdparams ├── latest.states └── train.log

其中 best_accuracy.* 是評估集上的最優模型;iter_epoch_3.* 是以 save_epoch_step 為間隔儲存下來的模型;latest.* 是最後一個epoch的模型。

```shell

預測英文結果

python tools/infer_rec.py -c configs/rec/PP-OCRv3/en_PP-OCRv3_rec.yml -o Global.pretrained_model={path/to/weights}/best_accuracy Global.infer_img=doc/imgs_words/en/word_1.png `` 預測使用的配置檔案必須與訓練一致,如您通過python tools/train.py -c configs/rec/ch_ppocr_v2.0/rec_chinese_lite_train_v2.0.yml` 完成了中文模型的訓練, 您可以使用如下命令進行中文模型預測。

```

預測中文結果

python tools/infer_rec.py -c configs/rec/ch_ppocr_v2.0/rec_chinese_lite_train_v2.0.yml -o Global.pretrained_model={path/to/weights}/best_accuracy Global.infer_img=doc/imgs_words/ch/word_1.jpg ```

4. 模型匯出與預測

inference 模型(paddle.jit.save儲存的模型) 一般是模型訓練,把模型結構和模型引數儲存在檔案中的固化模型,多用於預測部署場景。 訓練過程中儲存的模型是checkpoints模型,儲存的只有模型的引數,多用於恢復訓練等。 與checkpoints模型相比,inference 模型會額外儲存模型的結構資訊,在預測部署、加速推理上效能優越,靈活方便,適合於實際系統整合。

識別模型轉inference模型與檢測的方式相同,如下: 官方的例子: ```

-c 後面設定訓練演算法的yml配置檔案

-o 配置可選引數

Global.pretrained_model 引數設定待轉換的訓練模型地址,不用新增檔案字尾 .pdmodel,.pdopt或.pdparams。

Global.save_inference_dir引數設定轉換的模型將儲存的地址。

python tools/export_model.py -c configs/rec/PP-OCRv3/en_PP-OCRv3_rec.yml -o Global.pretrained_model=./pretrain_models/en_PP-OCRv3_rec_train/best_accuracy Global.save_inference_dir=./inference/en_PP-OCRv3_rec/ ```

注意:如果您是在自己的資料集上訓練的模型,並且調整了中文字元的字典檔案,請注意修改配置檔案中的character_dict_path為自定義字典檔案。 自己執行的命令:

python python tools/export_model.py -c configs/rec/PP-OCRv3/en_PP-OCRv3_rec.yml -o Global.pretrained_model=./output/v3_en_mobile/best_accuracy Global.save_inference_dir=./inference/en_PP-OCRv3_rec/

轉換成功後,在目錄下有三個檔案:

inference/en_PP-OCRv3_rec/ ├── inference.pdiparams # 識別inference模型的引數檔案 ├── inference.pdiparams.info # 識別inference模型的引數資訊,可忽略 └── inference.pdmodel # 識別inference模型的program檔案

  • 自定義模型推理

如果訓練時修改了文字的字典,在使用inference模型預測時,需要通過--rec_char_dict_path指定使用的字典路徑

python3 tools/infer/predict_rec.py --image_dir="./doc/imgs_words_en/word_336.png" --rec_model_dir="./your inference model" --rec_image_shape="3, 48, 320" --rec_char_dict_path="your text dict path"

六、hubserving部署

hubserving服務部署目錄下包括文字檢測、文字方向分類,文字識別、文字檢測+文字方向分類+文字識別3階段串聯,表格識別和PP-Structure六種服務包,請根據需求選擇相應的服務包進行安裝和啟動。目錄結構如下:

deploy/hubserving/ └─ ocr_cls 文字方向分類模組服務包 └─ ocr_det 文字檢測模組服務包 └─ ocr_rec 文字識別模組服務包 └─ ocr_system 文字檢測+文字方向分類+文字識別串聯服務包 └─ structure_table 表格識別服務包 └─ structure_system PP-Structure服務包

每個服務包下包含3個檔案。以2階段串聯服務包為例,目錄如下:

deploy/hubserving/ocr_system/ └─ __init__.py 空檔案,必選 └─ config.json 配置檔案,可選,使用配置啟動服務時作為引數傳入 └─ module.py 主模組,必選,包含服務的完整邏輯 └─ params.py 引數檔案,必選,包含模型路徑、前後處理引數等引數

1、準備環境

```shell

安裝paddlehub

paddlehub 需要 python>3.6.2

pip install paddlehub==2.1.0 --upgrade -i https://mirror.baidu.com/pypi/simple ```

2、安裝服務模組

PaddleOCR提供5種服務模組,根據需要安裝所需模組。

  • 在Linux環境下,安裝示例如下:

```shell

安裝檢測服務模組:

hub install deploy/hubserving/ocr_det/

或,安裝分類服務模組:

hub install deploy/hubserving/ocr_cls/

或,安裝識別服務模組:

hub install deploy/hubserving/ocr_rec/

或,安裝檢測+識別串聯服務模組:

hub install deploy/hubserving/ocr_system/

或,安裝表格識別服務模組:

hub install deploy/hubserving/structure_table/

或,安裝PP-Structure服務模組:

hub install deploy/hubserving/structure_system/ ```

  • 在Windows環境下(資料夾的分隔符為``),安裝示例如下:

```shell

安裝檢測服務模組:

hub install deploy\hubserving\ocr_det\

或,安裝分類服務模組:

hub install deploy\hubserving\ocr_cls\

或,安裝識別服務模組:

hub install deploy\hubserving\ocr_rec\

或,安裝檢測+識別串聯服務模組:

hub install deploy\hubserving\ocr_system\

或,安裝表格識別服務模組:

hub install deploy\hubserving\structure_table\

或,安裝PP-Structure服務模組:

hub install deploy\hubserving\structure_system\ ``` 我使用了檢測+方向+識別,所以只需要安裝

python hub install deploy/hubserving/ocr_system/ 注意:在PaddleOCR-release-2.5目錄下執行

3、啟動服務

3.1. 命令列命令啟動(僅支援CPU,不推薦)

啟動命令:

shell $ hub serving start --modules [Module1==Version1, Module2==Version2, ...] \ --port XXXX \ --use_multiprocess \ --workers \

引數:

| 引數 | 用途 | | ------------------ | ------------------------------------------------------------ | | --modules/-m | PaddleHub Serving預安裝模型,以多個Module==Version鍵值對的形式列出 當不指定Version時,預設選擇最新版本 | | --port/-p | 服務埠,預設為8866 | | --use_multiprocess | 是否啟用併發方式,預設為單程序方式,推薦多核CPU機器使用此方式 Windows作業系統只支援單程序方式 | | --workers | 在併發方式下指定的併發任務數,預設為2*cpu_count-1,其中cpu_count為CPU核數 |

如啟動串聯服務: hub serving start -m ocr_system

這樣就完成了一個服務化API的部署,使用預設埠號8866。

3.2、 配置檔案啟動(支援CPU、GPU)

啟動命令: hub serving start -c config.json

其中,config.json格式如下:

python { "modules_info": { "ocr_system": { "init_args": { "version": "1.0.0", "use_gpu": true }, "predict_args": { } } }, "port": 8868, "use_multiprocess": false, "workers": 2 }

  • init_args中的可配引數與module.py中的_initialize函式介面一致。其中,use_gputrue時,表示使用GPU啟動服務
  • predict_args中的可配引數與module.py中的predict函式介面一致。

注意:

  • 使用配置檔案啟動服務時,其他引數會被忽略。
  • 如果使用GPU預測(即,use_gpu置為true),則需要在啟動服務之前,設定CUDA_VISIBLE_DEVICES環境變數,如:export CUDA_VISIBLE_DEVICES=0,否則不用設定。
  • use_gpu不可與use_multiprocess同時為true

如,使用GPU 3號卡啟動串聯服務:

shell export CUDA_VISIBLE_DEVICES=3 hub serving start -c deploy/hubserving/ocr_system/config.json

4、 傳送預測請求

配置好服務端,可使用以下命令傳送預測請求,獲取預測結果:

python tools/test_hubserving.py server_url image_path test_hubserving.py程式碼:

```python

Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");

you may not use this file except in compliance with the License.

You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software

distributed under the License is distributed on an "AS IS" BASIS,

WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

See the License for the specific language governing permissions and

limitations under the License.

import os import sys dir = os.path.dirname(os.path.abspath(file)) sys.path.append(dir) sys.path.append(os.path.abspath(os.path.join(dir, '..')))

from ppocr.utils.logging import get_logger logger = get_logger()

import cv2 import numpy as np import time from PIL import Image from ppocr.utils.utility import get_image_file_list from tools.infer.utility import draw_ocr, draw_boxes, str2bool from ppstructure.utility import draw_structure_result from ppstructure.predict_system import to_excel

import requests import json import base64

def cv2_to_base64(image): return base64.b64encode(image).decode('utf8')

def draw_server_result(image_file, res): img = cv2.imread(image_file) image = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB)) if len(res) == 0: return np.array(image) keys = res[0].keys() if 'text_region' not in keys: # for ocr_rec, draw function is invalid logger.info("draw function is invalid for ocr_rec!") return None elif 'text' not in keys: # for ocr_det logger.info("draw text boxes only!") boxes = [] for dno in range(len(res)): boxes.append(res[dno]['text_region']) boxes = np.array(boxes) draw_img = draw_boxes(image, boxes) return draw_img else: # for ocr_system logger.info("draw boxes and texts!") boxes = [] texts = [] scores = [] for dno in range(len(res)): boxes.append(res[dno]['text_region']) texts.append(res[dno]['text']) scores.append(res[dno]['confidence']) boxes = np.array(boxes) scores = np.array(scores) draw_img = draw_ocr( image, boxes, texts, scores, draw_txt=True, drop_score=0.5) return draw_img

def save_structure_res(res, save_folder, image_file): img = cv2.imread(image_file) excel_save_folder = os.path.join(save_folder, os.path.basename(image_file)) os.makedirs(excel_save_folder, exist_ok=True) # save res with open( os.path.join(excel_save_folder, 'res.txt'), 'w', encoding='utf8') as f: for region in res: if region['type'] == 'Table': excel_path = os.path.join(excel_save_folder, '{}.xlsx'.format(region['bbox'])) to_excel(region['res'], excel_path) elif region['type'] == 'Figure': x1, y1, x2, y2 = region['bbox'] print(region['bbox']) roi_img = img[y1:y2, x1:x2, :] img_path = os.path.join(excel_save_folder, '{}.jpg'.format(region['bbox'])) cv2.imwrite(img_path, roi_img) else: for text_result in region['res']: f.write('{}\n'.format(json.dumps(text_result)))

def main(args): image_file_list = get_image_file_list(args.image_dir) is_visualize = False headers = {"Content-type": "application/json"} cnt = 0 total_time = 0 for image_file in image_file_list: img = open(image_file, 'rb').read() if img is None: logger.info("error in loading image:{}".format(image_file)) continue img_name = os.path.basename(image_file) # seed http request starttime = time.time() data = {'images': [cv2_to_base64(img)]} r = requests.post( url=args.server_url, headers=headers, data=json.dumps(data)) elapse = time.time() - starttime total_time += elapse logger.info("Predict time of %s: %.3fs" % (image_file, elapse)) res = r.json()["results"][0] logger.info(res)

    if args.visualize:
        draw_img = None
        if 'structure_table' in args.server_url:
            to_excel(res['html'], './{}.xlsx'.format(img_name))
        elif 'structure_system' in args.server_url:
            save_structure_res(res['regions'], args.output, image_file)
        else:
            draw_img = draw_server_result(image_file, res)
        if draw_img is not None:
            if not os.path.exists(args.output):
                os.makedirs(args.output)
            cv2.imwrite(
                os.path.join(args.output, os.path.basename(image_file)),
                draw_img[:, :, ::-1])
            logger.info("The visualized image saved in {}".format(
                os.path.join(args.output, os.path.basename(image_file))))
    cnt += 1
    if cnt % 100 == 0:
        logger.info("{} processed".format(cnt))
logger.info("avg time cost: {}".format(float(total_time) / cnt))

def parse_args(): import argparse parser = argparse.ArgumentParser(description="args for hub serving") parser.add_argument("--server_url", type=str, required=True) parser.add_argument("--image_dir", type=str, required=True) parser.add_argument("--visualize", type=str2bool, default=False) parser.add_argument("--output", type=str, default='./hubserving_result') args = parser.parse_args() return args

if name == 'main': args = parse_args() main(args)

```

需要給指令碼傳遞2個引數:

  • server_url:服務地址,格式為 http://[ip_address]:[port]/predict/[module_name] 例如,如果使用配置檔案啟動分類,檢測、識別,檢測+分類+識別3階段,表格識別和PP-Structure服務,那麼傳送請求的url將分別是: http://127.0.0.1:8865/predict/ocr_det http://127.0.0.1:8866/predict/ocr_cls http://127.0.0.1:8867/predict/ocr_rec http://127.0.0.1:8868/predict/ocr_system http://127.0.0.1:8869/predict/structure_table http://127.0.0.1:8870/predict/structure_system
  • image_dir:測試影象路徑,可以是單張圖片路徑,也可以是影象集合目錄路徑
  • visualize:是否視覺化結果,預設為False
  • output:視覺化結果儲存路徑,預設為./hubserving_result

訪問示例: python tools/test_hubserving.py --server_url=http://127.0.0.1:8868/predict/ocr_system --image_dir=./doc/imgs/ --visualize=false

執行結果: 在這裡插入圖片描述

5、 返回結果格式說明

返回結果為列表(list),列表中的每一項為詞典(dict),詞典一共可能包含3種欄位,資訊如下:

| 欄位名稱 | 資料型別 | 意義 | | ----------- | -------- | ------------------------------------------------------------ | | angle | str | 文字角度 | | text | str | 文字內容 | | confidence | float | 文字識別置信度或文字角度分類置信度 | | text_region | list | 文字位置座標 | | html | str | 表格的html字串 | | regions | list | 版面分析+表格識別+OCR的結果,每一項為一個list,包含表示區域座標的bbox,區域型別的type和區域結果的res三個欄位 |

不同模組返回的欄位不同,如,文字識別服務模組返回結果不含text_region欄位,具體資訊如下:

| 欄位名/模組名 | ocr_det | ocr_cls | ocr_rec | ocr_system | structure_table | structure_system | | ------------- | ------- | ------- | ------- | ---------- | --------------- | ---------------- | | angle | | ✔ | | ✔ | | | | text | | | ✔ | ✔ | | ✔ | | confidence | | ✔ | ✔ | | | ✔ | | text_region | ✔ | | | ✔ | | ✔ | | html | | | | | ✔ | ✔ | | regions | | | | | ✔ | ✔ |

說明: 如果需要增加、刪除、修改返回欄位,可在相應模組的module.py檔案中進行修改,完整流程參考下一節自定義修改服務模組。