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 http://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/Paddle/ -c conda-forge

二、配置PaddleOCR

下載地址:(http://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 http://mirror.baidu.com/pypi/simple

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

python3 -m pip install paddlepaddle -i http://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 http://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 http://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/ http://paddleocr.bj.bcebos.com/pretrained/MobileNetV3_large_x0_5_pretrained.pdparams

或,下載ResNet18_vd的預訓練模型

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

或,下載ResNet50_vd的預訓練模型

wget -P ./pretrain_models/ http://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 http://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文件中進行修改,完整流程參考下一節自定義修改服務模塊。