跳转至

RapidOCR 集成 PP-LCNet textline 文本行方向分类模型记录

该文章主要记录 RapidOCR 集成 PP-LCNet textline 文本行方向分类模型记录,涉及模型转换,模型精度测试等步骤。

引言

该部分主要是支持 文本行方向分类模块使用教程 中两个文本行方向分类模型:PP-LCNet_x0_25_textline_oriPP-LCNet_x1_0_textline_ori

下面是从上述链接中得到的这两个模型的情况:

模型 模型下载链接 Top-1 Acc(%) GPU 推理耗时(ms) CPU 推理耗时 (ms) 模型存储大小(MB) 介绍
PP-LCNet_x0_25_textline_ori 推理模型 / 训练模型 98.85 2.16 / 0.41 2.37 / 0.73 0.96 基于 PP-LCNet_x0_25 的文本行分类模型,含有两个类别,即 0 度,180 度
PP-LCNet_x1_0_textline_ori 推理模型 / 训练模型 99.42 - / - 2.98 / 2.98 6.5 基于 PP-LCNet_x1_0 的文本行分类模型,含有两个类别,即 0 度,180 度

以下代码运行环境

  • OS: macOs Tahoe 26.3.1 (a)
  • Python: 3.10.0
  • PaddlePaddle: 3.1.0
  • paddle2onnx: 2.1.0
  • paddlex: 3.0.0
  • rapidocr: 2.1.0
  • paddleocr: 3.4.0

1. 模型跑通

测试图:link

from paddleocr import TextLineOrientationClassification

# model: PP-LCNet_x1_0_textline_ori  /  PP-LCNet_x0_25_textline_ori
img_path = "datasets/textline_rot180_demo.jpg"
model = TextLineOrientationClassification(model_name="PP-LCNet_x1_0_textline_ori")
output = model.predict(img_path, batch_size=1)
for res in output:
    res.print(json_format=False)
    res.save_to_img("./output/demo.png")
    res.save_to_json("./output/res.json")

预期结果如下,表明成功运行:

Model files already exist. Using cached files. To redownload, please delete the directory manually: `/Users/xxxx/.paddlex/official_models/PP-LCNet_x1_0_textline_ori`.
{'res': {'input_path': 'datasets/textline_rot180_demo.jpg', 'page_index': None, 'class_ids': array([1], dtype=int32), 'scores': array([0.89868], dtype=float32), 'label_names': ['180_degree']}}

2. 模型转换

转换代码:

1
2
3
4
paddle2onnx --model_dir official_models/PP-LCNet_x0_25_textline_ori \
             --model_filename inference.json \
             --params_filename inference.pdiparams \
             --save_file official_models/onnx/PP-LCNet_x0_25_textline_ori.onnx

输出日志如下,表明转换成功:

[Paddle2ONNX] Start parsing the Paddle model file...
[Paddle2ONNX] Use opset_version = 9 for ONNX export.
[Paddle2ONNX] PaddlePaddle model is exported as ONNX format now.
2026-03-24 11:53:36 [INFO]      Try to perform constant folding on the ONNX model with Polygraphy.
[W] 'colored' module is not installed, will not use colors when logging. To enable colors, please install the 'colored' module: python3 -m pip install colored
[I] Folding Constants | Pass 1
[I]     Total Nodes | Original:   307, After Folding:   143 |   164 Nodes Folded
[I] Folding Constants | Pass 2
[I]     Total Nodes | Original:   143, After Folding:   143 |     0 Nodes Folded
2026-03-24 11:53:37 [INFO]      ONNX model saved in official_models/onnx/PP-LCNet_x0_25_textline_ori.onnx.

3. 模型转换前后精度测试

将上一步中转换得到的 ONNX 模型,在 PaddleOCR 源码模型推理时,插入 ONNX Runtime 推理 ONNX 模型的代码,确保相同输入,来比较输出是否在误差范围内。

/miniconda3/envs/py310/lib/python3.10/site-packages/paddlex/inference/models/image_classification/predictor.py
# 省略上面代码
import numpy as np
import onnxruntime

model_path = "official_models/onnx/PP-LCNet_x0_25_textline_ori.onnx"
ort_session = onnxruntime.InferenceSession(model_path)
ort_inputs = {"x": x[0]}
ort_outputs = ort_session.run(None, ort_inputs)

if self._use_static_model:
    batch_preds = self.infer(x=x)
else:
    with TemporaryDeviceChanger(self.device):
        batch_preds = self.infer(x=x)

# 这里是比较相同输入时,输出结果数值差异有多大。如果这行代码可以执行通过,就说明模型转换前后差异很小。
np.testing.assert_allclose(batch_preds[0], ort_outputs[0], atol=1e-5, rtol=1e-5)

# 省略下面代码

4. 指标评测

Note

以下测评结果来自于有限的评测集,很难做到全面评估一个模型效果好坏。因此,需要大家在使用时,辩证地看待各个模型,都可以在实际场景下多测测,看看效果来使用。

文本行方向分类模型评估一直缺乏一个评测集。我将之前构建的文本识别评测集(text_rec_test_dataset)做了部分旋转 180 度处理,剔掉竖排文字。最终得到文本行方向分类评测集 text_cls_test_dataset

import cv2
import numpy as np
from paddleocr import TextLineOrientationClassification
from tqdm import tqdm

from datasets import load_dataset

model_name = "PP-LCNet_x0_25_textline_ori"

# model_name = "PP-LCNet_x1_0_textline_ori"

model = TextLineOrientationClassification(model_name=model_name)

dataset = load_dataset("SWHL/text_cls_test_dataset")
test_datas = dataset["test"]

nums = 0
for data in tqdm(test_datas):
    image = data["image"]
    gt = data["label"]

    img_np = np.array(image)
    img_np = cv2.cvtColor(img_np, cv2.COLOR_RGB2BGR)
    output = model.predict(img_np, batch_size=1)

    res = output[0]
    pred = res.json["res"]["label_names"][0].split("_")[0]
    if pred == gt:
        nums += 1

print(model_name)
accracy = nums / len(test_datas)
print(f"accracy: {accracy:.4f}")
from datasets import load_dataset
from tqdm import tqdm

from rapidocr import RapidOCR

dataset = load_dataset("SWHL/text_cls_test_dataset")

# model_path = "official_models/onnx/PP-LCNet_x0_25_textline_ori.onnx"
model_path = "official_models/onnx/PP-LCNet_x1_0_textline_ori.onnx"
engine = RapidOCR(
    params={"Cls.model_path": model_path, "Cls.cls_image_shape": [3, 80, 160]}
)

test_datas = dataset["test"]

nums = 0
for data in tqdm(test_datas):
    image = data["image"]
    gt = data["label"]

    result = engine(image, use_det=False, use_rec=False, use_cls=True)
    pred = result.cls_res[0][0]

    if gt == pred:
        nums += 1

accracy = nums / len(test_datas)
print(f"accracy: {accracy:.4f}")
Exp 模型 推理框架 推理引擎 模型格式 Accuracy
0 ch_ppocr_mobile_v2.0_cls_infer RapidOCR ONNX Runtime ONNX 0.9219
1 PP-LCNet_x0_25_textline_ori PaddleOCR PaddlePaddle Paddle 0.8513
2 PP-LCNet_x0_25_textline_ori RapidOCR ONNX Runtime ONNX 0.8922
3 PP-LCNet_x1_0_textline_ori PaddleOCR PaddlePaddle Paddle 0.7918
4 PP-LCNet_x1_0_textline_ori RapidOCR ONNX Runtime ONNX 0.9033

Exp0 是 RapidOCR 一直在使用的 ch_ppocr_mobile_v2.0_cls_infer 模型,该模型源自 PaddleOCR v2 版本。从指标结果来看,在当前评测集上,该模型表现是最优的。

Exp1 和 Exp3 实验都是用的 PaddleOCR 原始代码 + text_rec_test_dataset 得到的指标。

Exp2 和 Exp4 实验用的是 RapidOCR 框架。与 PaddleOCR 的推理异同:

  • 相同之处:输出 shape 都是 [3, 80, 160]
  • 不同之处:前后处理不同。PaddleOCR 前后处理做了修改,与原有 PaddleOCR v2 的不同了。RapidOCR 用的是 PaddleOCR v2 时的前后处理。

本来打算集成 PaddleOCR v3 的前后处理,但是在使用评测集评估后,发现复用现有的前后处理,模型效果更好。因此,我这里打算复用旧有前后处理代码了。唯一的改动是输出 shape 适配一下 [3, 80, 160]

5. 集成到 rapidocr 中

该部分主要包括将托管模型到魔搭、更改 rapidocr 代码适配等。

托管模型到魔搭

该部分主要是涉及模型上传到对应位置,并合理命名。注意上传完成后,需要打 Tag,避免后续 rapidocr whl 包中找不到模型下载路径。

我这里已经上传到了魔搭上,详细链接参见:link

更改 rapidocr 代码适配

该部分主要涉及到更改 default_models.yamlpaddle.py 的代码来适配。

同时,需要添加对应的单元测试,在保证之前单测成功的同时,新的针对性该模型的单测也能通过。

我这里已经做完了,小伙伴们感兴趣可以去看看源码。

写在最后

本文中涉及到的两个文本行方向分类模型,归类到 PP-OCRv5 / cls 下,支持 ONNX Runtime 和 PaddlePaddle 推理,将在 rapidocr >= 3.8.0 中支持。敬请期待。

评论