table_recognition.md 81 KB


comments: true

通用表格识别产线使用教程

1. 通用表格识别产线介绍

表格识别是一种自动从文档或图像中识别和提取表格内容及其结构的技术,广泛应用于数据录入、信息检索和文档分析等领域。通过使用计算机视觉和机器学习算法,表格识别能够将复杂的表格信息转换为可编辑的格式,方便用户进一步处理和分析数据。

通用表格识别产线用于解决表格识别任务,对图片中的表格进行识别,并以HTML格式输出。本产线集成了业界知名的 SLANet 和 SLANet_plus 表格结构识别模型。基于本产线,可实现对表格的精准预测,使用场景覆盖通用、制造、金融、交通等各个领域。本产线同时提供了灵活的服务化部署方式,支持在多种硬件上使用多种编程语言调用。不仅如此,本产线也提供了二次开发的能力,您可以基于本产线在您自己的数据集上训练调优,训练后的模型也可以无缝集成。

通用表格识别产线中包含必选的表格结构识别模块、文本检测模块和文本识别模块,以及可选的版面区域检测模块、文档图像方向分类模块和文本图像矫正模块

如果您更注重模型的精度,请选择精度较高的模型;如果您更在意模型的推理速度,请选择推理速度较快的模型;如果您关注模型的存储大小,请选择存储体积较小的模型。

推理耗时仅包含模型推理耗时,不包含前后处理耗时。

👉模型列表详情

表格结构识别模块模型:

模型模型下载链接 精度(%) GPU推理耗时(ms)
[常规模式 / 高性能模式]
CPU推理耗时(ms)
[常规模式 / 高性能模式]
模型存储大小(MB) 介绍
SLANet 推理模型/训练模型 59.52 23.96 / 21.75 - / 43.12 6.9 SLANet 是百度飞桨视觉团队自研的表格结构识别模型。该模型通过采用CPU 友好型轻量级骨干网络PP-LCNet、高低层特征融合模块CSP-PAN、结构与位置信息对齐的特征解码模块SLA Head,大幅提升了表格结构识别的精度和推理速度。
SLANet_plus 推理模型/训练模型 63.69 23.43 / 22.16 - / 41.80 6.9

文本检测模块模型:

模型模型下载链接 检测Hmean(%) GPU推理耗时(ms)
[常规模式 / 高性能模式]
CPU推理耗时(ms)
[常规模式 / 高性能模式]
模型存储大小(MB) 介绍
PP-OCRv5_server_det 推理模型/训练模型 83.8 89.55 / 70.19 383.15 / 383.15 84.3 PP-OCRv5 的服务端文本检测模型,精度更高,适合在性能较好的服务器上部署
PP-OCRv5_mobile_det 推理模型/训练模型 79.0 10.67 / 6.36 57.77 / 28.15 4.7 PP-OCRv5 的移动端文本检测模型,效率更高,适合在端侧设备部署
PP-OCRv4_server_det 推理模型/训练模型 69.2 127.82 / 98.87 585.95 / 489.77 109 PP-OCRv4 的服务端文本检测模型,精度更高,适合在性能较好的服务器上部署
PP-OCRv4_mobile_det 推理模型/训练模型 63.8 9.87 / 4.17 56.60 / 20.79 4.7 PP-OCRv4 的移动端文本检测模型,效率更高,适合在端侧设备部署

文本识别模块模型:

模型模型下载链接 识别 Avg Accuracy(%) GPU推理耗时(ms)
[常规模式 / 高性能模式]
CPU推理耗时(ms)
[常规模式 / 高性能模式]
模型存储大小(MB) 介绍
PP-OCRv4_server_rec_doc 推理模型/训练模型 86.58 8.69 / 2.78 37.93 / 37.93 182 PP-OCRv4_server_rec_doc是在PP-OCRv4_server_rec的基础上,在更多中文文档数据和PP-OCR训练数据的混合数据训练而成,增加了部分繁体字、日文、特殊字符的识别能力,可支持识别的字符为1.5万+,除文档相关的文字识别能力提升外,也同时提升了通用文字的识别能力
PP-OCRv4_mobile_rec 推理模型/训练模型 78.74 5.26 / 1.12 17.48 / 3.61 10.5 PP-OCRv4的轻量级识别模型,推理效率高,可以部署在包含端侧设备的多种硬件设备中
PP-OCRv4_server_rec 推理模型/训练模型 85.19 8.75 / 2.49 36.93 / 36.93 173 PP-OCRv4的服务器端模型,推理精度高,可以部署在多种不同的服务器上
en_PP-OCRv4_mobile_rec 推理模型/训练模型 70.39 4.81 / 1.23 17.20 / 4.18 7.5 基于PP-OCRv4识别模型训练得到的超轻量英文识别模型,支持英文、数字识别
> ❗ 以上列出的是文本识别模块重点支持的4个核心模型,该模块总共支持18个全量模型,包含多个多语言文本识别模型,完整的模型列表如下:
👉模型列表详情 * 中文识别模型
模型模型下载链接 识别 Avg Accuracy(%) GPU推理耗时(ms)
[常规模式 / 高性能模式]
CPU推理耗时(ms)
[常规模式 / 高性能模式]
模型存储大小(MB) 介绍
PP-OCRv4_server_rec_doc 推理模型/训练模型 86.58 8.69 / 2.78 37.93 / 37.93 182 PP-OCRv4_server_rec_doc是在PP-OCRv4_server_rec的基础上,在更多中文文档数据和PP-OCR训练数据的混合数据训练而成,增加了部分繁体字、日文、特殊字符的识别能力,可支持识别的字符为1.5万+,除文档相关的文字识别能力提升外,也同时提升了通用文字的识别能力
PP-OCRv4_mobile_rec 推理模型/训练模型 78.74 5.26 / 1.12 17.48 / 3.61 10.5 PP-OCRv4的轻量级识别模型,推理效率高,可以部署在包含端侧设备的多种硬件设备中
PP-OCRv4_server_rec 推理模型/训练模型 85.19 8.75 / 2.49 36.93 / 36.93 173 PP-OCRv4的服务器端模型,推理精度高,可以部署在多种不同的服务器上
PP-OCRv3_mobile_rec 推理模型/训练模型 72.96 3.89 / 1.16 8.72 / 3.56 10.3 PP-OCRv3的轻量级识别模型,推理效率高,可以部署在包含端侧设备的多种硬件设备中
模型模型下载链接 识别 Avg Accuracy(%) GPU推理耗时(ms)
[常规模式 / 高性能模式]
CPU推理耗时(ms)
[常规模式 / 高性能模式]
模型存储大小(MB) 介绍
ch_SVTRv2_rec 推理模型/训练模型 68.81 10.38 / 8.31 66.52 / 30.83 80.5 SVTRv2 是一种由复旦大学视觉与学习实验室(FVL)的OpenOCR团队研发的服务端文本识别模型,其在PaddleOCR算法模型挑战赛 - 赛题一:OCR端到端识别任务中荣获一等奖,A榜端到端识别精度相比PP-OCRv4提升6%。
模型模型下载链接 识别 Avg Accuracy(%) GPU推理耗时(ms)
[常规模式 / 高性能模式]
CPU推理耗时(ms)
[常规模式 / 高性能模式]
模型存储大小(MB) 介绍
ch_RepSVTR_rec 推理模型/训练模型 65.07 6.29 / 1.57 20.64 / 5.40 48.8 RepSVTR 文本识别模型是一种基于SVTRv2 的移动端文本识别模型,其在PaddleOCR算法模型挑战赛 - 赛题一:OCR端到端识别任务中荣获一等奖,B榜端到端识别精度相比PP-OCRv4提升2.5%,推理速度持平。
* 英文识别模型
模型模型下载链接 识别 Avg Accuracy(%) GPU推理耗时(ms)
[常规模式 / 高性能模式]
CPU推理耗时(ms)
[常规模式 / 高性能模式]
模型存储大小(MB) 介绍
en_PP-OCRv4_mobile_rec 推理模型/训练模型 70.39 4.81 / 1.23 17.20 / 4.18 7.5 基于PP-OCRv4识别模型训练得到的超轻量英文识别模型,支持英文、数字识别
en_PP-OCRv3_mobile_rec 推理模型/训练模型 70.69 3.56 / 0.78 8.44 / 5.78 17.3 基于PP-OCRv3识别模型训练得到的超轻量英文识别模型,支持英文、数字识别
* 多语言识别模型
模型模型下载链接 识别 Avg Accuracy(%) GPU推理耗时(ms)
[常规模式 / 高性能模式]
CPU推理耗时(ms)
[常规模式 / 高性能模式]
模型存储大小(MB) 介绍
korean_PP-OCRv3_mobile_rec 推理模型/训练模型 60.21 3.73 / 0.98 8.76 / 2.91 9.6 基于PP-OCRv3识别模型训练得到的超轻量韩文识别模型,支持韩文、数字识别
japan_PP-OCRv3_mobile_rec 推理模型/训练模型 45.69 3.86 / 1.01 8.62 / 2.92 9.8 基于PP-OCRv3识别模型训练得到的超轻量日文识别模型,支持日文、数字识别
chinese_cht_PP-OCRv3_mobile_rec 推理模型/训练模型 82.06 3.90 / 1.16 9.24 / 3.18 10.8 基于PP-OCRv3识别模型训练得到的超轻量繁体中文识别模型,支持繁体中文、数字识别
te_PP-OCRv3_mobile_rec 推理模型/训练模型 95.88 3.59 / 0.81 8.28 / 6.21 8.7 基于PP-OCRv3识别模型训练得到的超轻量泰卢固文识别模型,支持泰卢固文、数字识别
ka_PP-OCRv3_mobile_rec 推理模型/训练模型 96.96 3.49 / 0.89 8.63 / 2.77 17.4 基于PP-OCRv3识别模型训练得到的超轻量卡纳达文识别模型,支持卡纳达文、数字识别
ta_PP-OCRv3_mobile_rec 推理模型/训练模型 76.83 3.49 / 0.86 8.35 / 3.41 8.7 基于PP-OCRv3识别模型训练得到的超轻量泰米尔文识别模型,支持泰米尔文、数字识别
latin_PP-OCRv3_mobile_rec 推理模型/训练模型 76.93 3.53 / 0.78 8.50 / 6.83 8.7 基于PP-OCRv3识别模型训练得到的超轻量拉丁文识别模型,支持拉丁文、数字识别
arabic_PP-OCRv3_mobile_rec 推理模型/训练模型 73.55 3.60 / 0.83 8.44 / 4.69 17.3 基于PP-OCRv3识别模型训练得到的超轻量阿拉伯字母识别模型,支持阿拉伯字母、数字识别
cyrillic_PP-OCRv3_mobile_rec 推理模型/训练模型 94.28 3.56 / 0.79 8.22 / 2.76 8.7 基于PP-OCRv3识别模型训练得到的超轻量斯拉夫字母识别模型,支持斯拉夫字母、数字识别
devanagari_PP-OCRv3_mobile_rec 推理模型/训练模型 96.44 3.60 / 0.78 6.95 / 2.87 8.7 基于PP-OCRv3识别模型训练得到的超轻量梵文字母识别模型,支持梵文字母、数字识别
模型模型下载链接 mAP(0.5)(%) GPU推理耗时(ms)
[常规模式 / 高性能模式]
CPU推理耗时(ms)
[常规模式 / 高性能模式]
模型存储大小(MB) 介绍
PP-DocLayout-L 推理模型/训练模型 90.4 33.59 / 33.59 503.01 / 251.08 123.76 基于RT-DETR-L在包含中英文论文、杂志、合同、书本、试卷和研报等场景的自建数据集训练的高精度版面区域定位模型
PP-DocLayout-M 推理模型/训练模型 75.2 13.03 / 4.72 43.39 / 24.44 22.578 基于PicoDet-L在包含中英文论文、杂志、合同、书本、试卷和研报等场景的自建数据集训练的精度效率平衡的版面区域定位模型
PP-DocLayout-S 推理模型/训练模型 70.9 11.54 / 3.86 18.53 / 6.29 4.834 基于PicoDet-S在中英文论文、杂志、合同、书本、试卷和研报等场景上自建数据集训练的高效率版面区域定位模型

版面区域检测模块模型(可选):

模型模型下载链接 mAP(0.5)(%) GPU推理耗时(ms)
[常规模式 / 高性能模式]
CPU推理耗时(ms)
[常规模式 / 高性能模式]
模型存储大小(MB) 介绍
PicoDet_layout_1x 推理模型/训练模型 97.8 9.62 / 6.75 26.96 / 12.77 7.4 基于PicoDet-1x在PubLayNet数据集训练的高效率版面区域定位模型,可定位包含文字、标题、表格、图片以及列表这5类区域
PicoDet_layout_1x_table 推理模型/训练模型 97.5 9.57 / 6.63 27.66 / 16.75 7.4 基于PicoDet-1x在自建数据集训练的高效率版面区域定位模型,可定位包含表格这1类区域
PicoDet-S_layout_3cls 推理模型/训练模型 88.2 8.43 / 3.44 17.60 / 6.51 4.8 基于PicoDet-S轻量模型在中英文论文、杂志和研报等场景上自建数据集训练的高效率版面区域定位模型,包含3个类别:表格,图像和印章
PicoDet-S_layout_17cls 推理模型/训练模型 87.4 8.80 / 3.62 17.51 / 6.35 4.8 基于PicoDet-S轻量模型在中英文论文、杂志和研报等场景上自建数据集训练的高效率版面区域定位模型,包含17个版面常见类别,分别是:段落标题、图片、文本、数字、摘要、内容、图表标题、公式、表格、表格标题、参考文献、文档标题、脚注、页眉、算法、页脚、印章
PicoDet-L_layout_3cls 推理模型/训练模型 89.0 12.80 / 9.57 45.04 / 23.86 22.6 基于PicoDet-L在中英文论文、杂志和研报等场景上自建数据集训练的高效率版面区域定位模型,包含3个类别:表格,图像和印章
PicoDet-L_layout_17cls 推理模型/训练模型 89.0 12.60 / 10.27 43.70 / 24.42 22.6 基于PicoDet-L在中英文论文、杂志和研报等场景上自建数据集训练的高效率版面区域定位模型,包含17个版面常见类别,分别是:段落标题、图片、文本、数字、摘要、内容、图表标题、公式、表格、表格标题、参考文献、文档标题、脚注、页眉、算法、页脚、印章
RT-DETR-H_layout_3cls 推理模型/训练模型 95.8 114.80 / 25.65 924.38 / 924.38 470.1 基于RT-DETR-H在中英文论文、杂志和研报等场景上自建数据集训练的高精度版面区域定位模型,包含3个类别:表格,图像和印章
RT-DETR-H_layout_17cls 推理模型/训练模型 98.3 115.29 / 101.18 964.75 / 964.75 470.2 基于RT-DETR-H在中英文论文、杂志和研报等场景上自建数据集训练的高精度版面区域定位模型,包含17个版面常见类别,分别是:段落标题、图片、文本、数字、摘要、内容、图表标题、公式、表格、表格标题、参考文献、文档标题、脚注、页眉、算法、页脚、印章

文本图像矫正模块模型(可选):

模型模型下载链接 CER GPU推理耗时(ms)
[常规模式 / 高性能模式]
CPU推理耗时(ms)
[常规模式 / 高性能模式]
模型存储大小(MB) 介绍
UVDoc 推理模型/训练模型 0.179 19.05 / 19.05 - / 869.82 30.3 高精度文本图像矫正模型

文档图像方向分类模块模型(可选):

模型模型下载链接 Top-1 Acc(%) GPU推理耗时(ms)
[常规模式 / 高性能模式]
CPU推理耗时(ms)
[常规模式 / 高性能模式]
模型存储大小(MB) 介绍
PP-LCNet_x1_0_doc_ori 推理模型/训练模型 99.06 2.62 / 0.59 3.24 / 1.19 7 基于PP-LCNet_x1_0的文档图像分类模型,含有四个类别,即0度,90度,180度,270度

测试环境说明:

      <li><b>性能测试环境</b>
          <ul>
            <li><strong>测试数据集:
             </strong>
                <ul>
                  <li>文档图像方向分类模型:PaddleX 自建的数据集,覆盖证件和文档等多个场景,包含 1000 张图片。</li>
                  <li>文本图像矫正模型:<a href="https://www3.cs.stonybrook.edu/~cvl/docunet.html">DocUNet</a>。</li>
                  <li>版面区域检测模型:PaddleOCR 自建的版面区域分析数据集,包含中英文论文、杂志和研报等常见的 1w 张文档类型图片。</li>
                  <li>表格结构识别模型:PaddleX 内部自建英文表格识别数据集。</li>
                  <li>文本检测模型:PaddleOCR 自建的中文数据集,覆盖街景、网图、文档、手写多个场景,其中检测包含 500 张图片。</li>
                  <li>中文识别模型: PaddleOCR 自建的中文数据集,覆盖街景、网图、文档、手写多个场景,其中文本识别包含 1.1w 张图片。</li>
                  <li>ch_SVTRv2_rec:<a href="https://aistudio.baidu.com/competition/detail/1131/0/introduction">PaddleOCR算法模型挑战赛 - 赛题一:OCR端到端识别任务</a>A榜评估集。</li>
                  <li>ch_RepSVTR_rec:<a href="https://aistudio.baidu.com/competition/detail/1131/0/introduction">PaddleOCR算法模型挑战赛 - 赛题一:OCR端到端识别任务</a>B榜评估集。</li>
                  <li>英文识别模型:PaddleX 自建的英文数据集。</li>
                  <li>多语言识别模型:PaddleX 自建的多语种数据集。</li>
                </ul>
             </li>
              <li><strong>硬件配置:</strong>
                  <ul>
                      <li>GPU:NVIDIA Tesla T4</li>
                      <li>CPU:Intel Xeon Gold 6271C @ 2.60GHz</li>
                      <li>其他环境:Ubuntu 20.04 / cuDNN 8.6 / TensorRT 8.5.2.2</li>
                  </ul>
              </li>
          </ul>
      </li>
      <li><b>推理模式说明</b></li>
    

    模式 GPU配置 CPU配置 加速技术组合
    常规模式 FP32精度 / 无TRT加速 FP32精度 / 8线程 PaddleInference
    高性能模式 选择先验精度类型和加速策略的最优组合 FP32精度 / 8线程 选择先验最优后端(Paddle/OpenVINO/TRT等)

    2. 快速开始

    PaddleX 所提供的预训练的模型产线均可以快速体验效果,你可以在星河社区在线体验通用表格识别产线的效果,也可以在本地使用命令行或 Python 体验通用表格识别产线的效果。

    2.1 在线体验

    您可以在线体验通用表格识别产线的效果,用官方提供的 demo 图片进行识别,例如:

    如果您对产线运行的效果满意,可以直接进行集成部署。您可以选择从云端下载部署包,也可以参考2.2节本地体验中的方法进行本地部署。如果对效果不满意,您可以利用私有数据对产线中的模型进行微调训练。如果您具备本地训练的硬件资源,可以直接在本地开展训练;如果没有,星河零代码平台提供了一键式训练服务,无需编写代码,只需上传数据后,即可一键启动训练任务。

    2.2 本地体验

    在本地使用通用表格识别产线前,请确保您已经按照PaddleX本地安装教程完成了PaddleX的wheel包安装。如果您希望选择性安装依赖,请参考安装教程中的相关说明。该产线对应的依赖分组为 ocr

    2.1 命令行方式体验

    一行命令即可快速体验表格识别产线效果,使用 测试文件,并将 --input 替换为本地路径,进行预测

    paddlex --pipeline table_recognition \
            --use_doc_orientation_classify=False \
            --use_doc_unwarping=False \
            --input table_recognition.jpg \
            --save_path ./output \
            --device gpu:0
    

    注:PaddleX 支持多个模型托管平台,官方模型默认优先从 HuggingFace 下载。PaddleX 也支持通过环境变量 PADDLE_PDX_MODEL_SOURCE 设置优先使用的托管平台,目前支持 huggingfaceaistudiobosmodelscope,如优先使用 bosPADDLE_PDX_MODEL_SOURCE="bos"

    相关的参数说明可以参考2.2 Python脚本方式中的参数说明。支持同时指定多个设备以进行并行推理,详情请参考 产线并行推理

    运行后,会将结果打印到终端上,结果如下:

    👉 运行后,得到的结果为:(点击展开) ```bash {'res': {'input_path': 'table_recognition.jpg', 'page_index': None, 'model_settings': {'use_doc_preprocessor': False, 'use_layout_detection': True, 'use_ocr_model': True}, 'layout_det_res': {'input_path': None, 'page_index': None, 'boxes': [{'cls_id': 0, 'label': 'Table', 'score': 0.9922188520431519, 'coordinate': [3.0127392, 0.14648987, 547.5102, 127.72023]}]}, 'overall_ocr_res': {'input_path': None, 'page_index': None, 'model_settings': {'use_doc_preprocessor': False, 'use_textline_orientation': False}, 'dt_polys': array([[[234, 6], ..., [234, 25]], ..., [[448, 101], ..., [448, 121]]], dtype=int16), 'text_det_params': {'limit_side_len': 960, 'limit_type': 'max', 'thresh': 0.3, 'box_thresh': 0.6, 'unclip_ratio': 2.0}, 'text_type': 'general', 'textline_orientation_angles': array([-1, ..., -1]), 'text_rec_score_thresh': 0, 'rec_texts': ['CRuncover', 'Dres', '连续工作3', '取出来放在网上', '没想', '江、整江等八大', 'Abstr', 'rSrivi', '$709.', 'cludingGiv', '2.72', 'Ingcubic', '$744.78'], 'rec_scores': array([0.99512607, ..., 0.99844509]), 'rec_polys': array([[[234, 6], ..., [234, 25]], ..., [[448, 101], ..., [448, 121]]], dtype=int16), 'rec_boxes': array([[234, ..., 25], ..., [448, ..., 121]], dtype=int16)}, 'table_res_list': [{'cell_box_list': array([[ 5.01273918, ..., 32.14648987], ..., [405.01273918, ..., 124.14648987]]), 'pred_html': '
    CRuncover
    Dres连续工作3取出来放在网上 没想江、整江等八大
    AbstrrSrivi$709.
    cludingGiv2.72Ingcubic$744.78
    ', 'table_ocr_pred': {'rec_polys': array([[[234, 6], ..., [234, 25]], ..., [[448, 101], ..., [448, 121]]], dtype=int16), 'rec_texts': ['CRuncover', 'Dres', '连续工作3', '取出来放在网上', '没想', '江、整江等八大', 'Abstr', 'rSrivi', '$709.', 'cludingGiv', '2.72', 'Ingcubic', '$744.78'], 'rec_scores': array([0.99512607, ..., 0.99844509]), 'rec_boxes': array([[234, ..., 25], ..., [448, ..., 121]], dtype=int16)}}]}} ``` 运行结果参数说明可以参考[2.2 Python脚本方式](#22-python脚本方式集成)中的结果解释。 可视化结果保存在`save_path`下,其中表格识别的可视化结果如下:

    2.2 Python脚本方式集成

    • 上述命令行是为了快速体验查看效果,一般来说,在项目中,往往需要通过代码集成,您可以通过几行代码即可完成产线的快速推理,推理代码如下:

      from paddlex import create_pipeline
      
      pipeline = create_pipeline(pipeline="table_recognition")
      
      output = pipeline.predict(
      input="table_recognition.jpg",
      use_doc_orientation_classify=False,
      use_doc_unwarping=False,
      )
      
      for res in output:
      res.print()
      res.save_to_img("./output/")
      res.save_to_xlsx("./output/")
      res.save_to_html("./output/")
      res.save_to_json("./output/")
      

    在上述 Python 脚本中,执行了如下几个步骤:

    (1)通过 create_pipeline() 实例化通用表格识别产线对象,具体参数说明如下:

    参数 参数说明 参数类型 默认值
    pipeline 产线名称或是产线配置文件路径。如为产线名称,则必须为 PaddleX 所支持的产线。 str None
    config 产线具体的配置信息(如果和pipeline同时设置,优先级高于pipeline,且要求产线名和pipeline一致)。 dict[str, Any] None
    device 产线推理设备。支持指定GPU具体卡号,如“gpu:0”,其他硬件具体卡号,如“npu:0”,CPU如“cpu”。支持同时指定多个设备以进行并行推理,详情请参考产线并行推理文档。 str gpu:0
    use_hpip 是否启用高性能推理插件。如果为 None,则使用配置文件或 config 中的配置。 bool | None None
    hpi_config 高性能推理配置 dict | None None

    (2)调用通用表格识别产线对象的 predict() 方法进行推理预测。该方法将返回一个 generator。以下是 predict() 方法的参数及其说明:

    参数 参数说明 参数类型 可选项 默认值
    input 待预测数据,支持多种输入类型,必填 Python Var|str|list
    • Python Var:如 numpy.ndarray 表示的图像数据
    • str:如图像文件或者PDF文件的本地路径:/root/data/img.jpg如URL链接,如图像文件或PDF文件的网络URL:示例如本地目录,该目录下需包含待预测图像,如本地路径:/root/data/(当前不支持目录中包含PDF文件的预测,PDF文件需要指定到具体文件路径)
    • List:列表元素需为上述类型数据,如[numpy.ndarray, numpy.ndarray][\"/root/data/img1.jpg\", \"/root/data/img2.jpg\"][\"/root/data1\", \"/root/data2\"]
    None
    use_doc_orientation_classify 是否使用文档方向分类模块 bool|None
    • boolTrue 或者 False
    • None:如果设置为None, 将默认使用产线初始化的该参数值,初始化为True
    None
    use_doc_unwarping 是否使用文档扭曲矫正模块 bool|None
    • boolTrue 或者 False
    • None:如果设置为None, 将默认使用产线初始化的该参数值,初始化为True
    None
    use_layout_detection 是否使用版面检测模块 bool|None
    • boolTrue 或者 False
    • None:如果设置为None, 将默认使用产线初始化的该参数值,初始化为True
    None
    text_det_limit_side_len 文本检测的图像边长限制 int|None
    • int:大于 0 的任意整数;
    • None:如果设置为 None, 将默认使用产线初始化的该参数值,初始化为 960
    None
    text_det_limit_type 文本检测的图像边长限制类型 str|None
    • str:支持 minmaxmin 表示保证图像最短边不小于 det_limit_side_lenmax 表示保证图像最长边不大于 limit_side_len
    • None:如果设置为 None, 将默认使用产线初始化的该参数值,初始化为 max
    None text_det_thresh 检测像素阈值,输出的概率图中,得分大于该阈值的像素点才会被认为是文字像素点 float|None
    • float:大于 0 的任意浮点数
    • None:如果设置为 None, 将默认使用产线初始化的该参数值 0.3
    None text_det_box_thresh 检测框阈值,检测结果边框内,所有像素点的平均得分大于该阈值时,该结果会被认为是文字区域 float|None
    • float:大于 0 的任意浮点数
    • None:如果设置为 None, 将默认使用产线初始化的该参数值 0.6
    None text_det_unclip_ratio 文本检测扩张系数,使用该方法对文字区域进行扩张,该值越大,扩张的面积越大 float|None
    • float:大于 0 的任意浮点数
    • None:如果设置为 None, 将默认使用产线初始化的该参数值 2.0
    None text_rec_score_thresh 文本识别阈值,得分大于该阈值的文本结果会被保留 float|None
    • float:大于 0 的任意浮点数
    • None:如果设置为 None, 将默认使用产线初始化的该参数值 0.0。即不设阈值
    None use_table_cells_ocr_results 是否启用单元格OCR模式,不启用时采用全局OCR结果填充至HTML表格,启用时逐个单元格做OCR并填充至HTML表格(会增加耗时)。二者在不同场景下性能不同,请根据实际情况选择。 bool
    • boolTrue 或者 False False

    (3)对预测结果进行处理,每个样本的预测结果均为对应的Result对象,且支持打印、保存为图片、保存为xlsx文件、保存为HTML文件、保存为json文件的操作:

    方法 方法说明 参数 参数类型 参数说明 默认值
    print() 打印结果到终端 format_json bool 是否对输出内容进行使用 JSON 缩进格式化 True
    indent int 指定缩进级别,以美化输出的 JSON 数据,使其更具可读性,仅当 format_jsonTrue 时有效 4
    ensure_ascii bool 控制是否将非 ASCII 字符转义为 Unicode。设置为 True 时,所有非 ASCII 字符将被转义;False 则保留原始字符,仅当format_jsonTrue时有效 False
    save_to_json() 将结果保存为json格式的文件 save_path str 保存的文件路径,当为目录时,保存文件命名与输入文件类型命名一致
    indent int 指定缩进级别,以美化输出的 JSON 数据,使其更具可读性,仅当 format_jsonTrue 时有效 4
    ensure_ascii bool 控制是否将非 ASCII 字符转义为 Unicode。设置为 True 时,所有非 ASCII 字符将被转义;False 则保留原始字符,仅当format_jsonTrue时有效 False
    save_to_img() 将结果保存为图像格式的文件 save_path str 保存的文件路径,支持目录或文件路径
    save_to_xlsx() 将结果保存为xlsx格式的文件 save_path str 保存的文件路径,支持目录或文件路径
    save_to_html() 将结果保存为html格式的文件 save_path str 保存的文件路径,支持目录或文件路径
    • 调用print() 方法会将结果打印到终端,打印到终端的内容解释如下:

      • input_path: (str) 待预测图像的输入路径

      • page_index: (Union[int, None]) 如果输入是PDF文件,则表示当前是PDF的第几页,否则为 None

      • model_settings: (Dict[str, bool]) 配置产线所需的模型参数

        • use_doc_preprocessor: (bool) 控制是否启用文档预处理子产线
      • doc_preprocessor_res: (Dict[str, Union[str, Dict[str, bool], int]]) 文档预处理子产线的输出结果。仅当use_doc_preprocessor=True时存在

        • input_path: (Union[str, None]) 图像预处理子产线接受的图像路径,当输入为numpy.ndarray时,保存为None
        • model_settings: (Dict) 预处理子产线的模型配置参数
          • use_doc_orientation_classify: (bool) 控制是否启用文档方向分类
          • use_doc_unwarping: (bool) 控制是否启用文档扭曲矫正
        • angle: (int) 文档方向分类的预测结果。启用时取值为[0,1,2,3],分别对应[0°,90°,180°,270°];未启用时为-1
      • dt_polys: (List[numpy.ndarray]) 文本检测的多边形框列表。每个检测框由4个顶点坐标构成的numpy数组表示,数组shape为(4, 2),数据类型为int16

      • dt_scores: (List[float]) 文本检测框的置信度列表

      • text_det_params: (Dict[str, Dict[str, int, float]]) 文本检测模块的配置参数

        • limit_side_len: (int) 图像预处理时的边长限制值
        • limit_type: (str) 边长限制的处理方式
        • thresh: (float) 文本像素分类的置信度阈值
        • box_thresh: (float) 文本检测框的置信度阈值
        • unclip_ratio: (float) 文本检测框的膨胀系数
        • text_type: (str) 文本检测的类型,当前固定为"general"
      • text_rec_score_thresh: (float) 文本识别结果的过滤阈值

      • rec_texts: (List[str]) 文本识别结果列表,仅包含置信度超过text_rec_score_thresh的文本

      • rec_scores: (List[float]) 文本识别的置信度列表,已按text_rec_score_thresh过滤

      • rec_polys: (List[numpy.ndarray]) 经过置信度过滤的文本检测框列表,格式同dt_polys

      • rec_boxes: (numpy.ndarray) 检测框的矩形边界框数组,shape为(n, 4),dtype为int16。每一行表示一个矩形框的[x_min, y_min, x_max, y_max]坐标 ,其中(x_min, y_min)为左上角坐标,(x_max, y_max)为右下角坐标

    • 调用save_to_json() 方法会将上述内容保存到指定的save_path中,如果指定为目录,则保存的路径为save_path/{your_img_basename}_res.json,如果指定为文件,则直接保存到该文件中。由于json文件不支持保存numpy数组,因此会将其中的numpy.array类型转换为列表形式。

    • 调用save_to_img() 方法会将可视化结果保存到指定的save_path中,如果指定为目录,则保存的路径为save_path/{your_img_basename}_ocr_res_img.{your_img_extension},如果指定为文件,则直接保存到该文件中。(产线通常包含较多结果图片,不建议直接指定为具体的文件路径,否则多张图会被覆盖,仅保留最后一张图)

    • 调用save_to_html() 方法会将上述内容保存到指定的save_path中,如果指定为目录,则保存的路径为save_path/{your_img_basename}_table_1.html,如果指定为文件,则直接保存到该文件中。在通用表格识别v2产线中,将会把图像中表格的HTML形式写入到指定的html文件中。

    • 调用save_to_xlsx() 方法会将上述内容保存到指定的save_path中,如果指定为目录,则保存的路径为save_path/{your_img_basename}_res.xlsx,如果指定为文件,则直接保存到该文件中。在通用表格识别v2产线中,将会把图像中表格的Excel表格形式写入到指定的xlsx文件中。

    • 此外,也支持通过属性获取带结果的可视化图像和预测结果,具体如下:

    属性 属性说明
    json 获取预测的 json 格式的结果
    img 获取格式为 dict 的可视化图像
    • json 属性获取的预测结果为dict类型的数据,相关内容与调用 save_to_json() 方法保存的内容一致。
    • img 属性返回的预测结果是一个字典类型的数据。其中,键分别为 table_res_imgocr_res_imglayout_res_imgpreprocessed_img,对应的值是四个 Image.Image 对象,按顺序分别为:表格识别结果的可视化图像、OCR 结果的可视化图像、版面区域检测结果的可视化图像、图像预处理的可视化图像。如果没有使用某个子模块,则字典中不包含对应的结果图像。

    此外,您可以获取通用表格识别产线配置文件,并加载配置文件进行预测。可执行如下命令将结果保存在 my_path 中:

    paddlex --get_pipeline_config table_recognition --save_path ./my_path
    

    若您获取了配置文件,即可对通用表格识别产线各项配置进行自定义,只需要修改 create_pipeline 方法中的 pipeline 参数值为产线配置文件路径即可。示例如下:

    from paddlex import create_pipeline
    
    pipeline = create_pipeline(pipeline="./my_path/table_recognition.yaml")
    
    output = pipeline.predict(
        input="table_recognition.jpg",
        use_doc_orientation_classify=False,
        use_doc_unwarping=False,
    )
    
    for res in output:
        res.print()
        res.save_to_img("./output/")
        res.save_to_xlsx("./output/")
        res.save_to_html("./output/")
        res.save_to_json("./output/")
    
    

    注: 配置文件中的参数为产线初始化参数,如果希望更改通用通用表格识别产线初始化参数,可以直接修改配置文件中的参数,并加载配置文件进行预测。同时,CLI 预测也支持传入配置文件,--pipeline 指定配置文件的路径即可。

    3. 开发集成/部署

    如果产线可以达到您对产线推理速度和精度的要求,您可以直接进行开发集成/部署。

    若您需要将产线直接应用在您的Python项目中,可以参考 2.2 Python脚本方式中的示例代码。

    此外,PaddleX 也提供了其他三种部署方式,详细说明如下:

    🚀 高性能推理:在实际生产环境中,许多应用对部署策略的性能指标(尤其是响应速度)有着较严苛的标准,以确保系统的高效运行与用户体验的流畅性。为此,PaddleX 提供高性能推理插件,旨在对模型推理及前后处理进行深度性能优化,实现端到端流程的显著提速,详细的高性能推理流程请参考PaddleX高性能推理指南

    ☁️ 服务化部署:服务化部署是实际生产环境中常见的一种部署形式。通过将推理功能封装为服务,客户端可以通过网络请求来访问这些服务,以获取推理结果。PaddleX 支持多种产线服务化部署方案,详细的产线服务化部署流程请参考PaddleX服务化部署指南

    以下是基础服务化部署的API参考与多语言服务调用示例:

    API参考

    对于服务提供的主要操作:

    • HTTP请求方法为POST。
    • 请求体和响应体均为JSON数据(JSON对象)。
    • 当请求处理成功时,响应状态码为200,响应体的属性如下:
    名称 类型 含义
    logId string 请求的UUID。
    errorCode integer 错误码。固定为0
    errorMsg string 错误说明。固定为"Success"
    result object 操作结果。
    • 当请求处理未成功时,响应体的属性如下:
    名称 类型 含义
    logId string 请求的UUID。
    errorCode integer 错误码。与响应状态码相同。
    errorMsg string 错误说明。

    服务提供的主要操作如下:

    • infer

    定位并识别图中的表格。

    POST /table-recognition

    • 请求体的属性如下:
    名称 类型 含义 是否必填
    file string 服务器可访问的图像文件或PDF文件的URL,或上述类型文件内容的Base64编码结果。默认对于超过10页的PDF文件,只有前10页的内容会被处理。
    要解除页数限制,请在产线配置文件中添加以下配置:
    Serving:
      extra:
        max_num_input_imgs: null
    
    fileType integer | null 文件类型。0表示PDF文件,1表示图像文件。若请求体无此属性,则将根据URL推断文件类型。
    useDocOrientationClassify boolean | null 请参阅产线对象中 predict 方法的 use_doc_orientation_classify 参数相关说明。
    useDocUnwarping boolean | null 请参阅产线对象中 predict 方法的 use_doc_unwarping 参数相关说明。
    useLayoutDetection boolean | null 请参阅产线对象中 predict 方法的 use_layout_detection 参数相关说明。
    useOcrModel boolean | null 请参阅产线对象中 predict 方法的 use_ocr_model 参数相关说明。
    textDetLimitSideLen integer | null 请参阅产线对象中 predict 方法的 text_det_limit_side_len 参数相关说明。
    textDetLimitType string | null 请参阅产线对象中 predict 方法的 text_det_limit_type 参数相关说明。
    textDetThresh number | null 请参阅产线对象中 predict 方法的 text_det_thresh 参数相关说明。
    textDetBoxThresh number | null 请参阅产线对象中 predict 方法的 text_det_box_thresh 参数相关说明。
    textDetUnclipRatio number | null 请参阅产线对象中 predict 方法的 text_det_unclip_ratio 参数相关说明。
    textRecScoreThresh number | null 请参阅产线对象中 predict 方法的 text_rec_score_thresh 参数相关说明。
    useOcrResultsWithTableCells boolean 请参阅产线对象中 predict 方法的 use_ocr_results_with_table_cells 参数相关说明。
    visualize boolean | null 是否返回可视化结果图以及处理过程中的中间图像等。
    • 传入 true:返回图像。
    • 传入 false:不返回图像。
    • 若请求体中未提供该参数或传入 null:遵循产线配置文件Serving.visualize 的设置。

    例如,在产线配置文件中添加如下字段:
    Serving:
      visualize: False
    
    将默认不返回图像,通过请求体中的visualize参数可以覆盖默认行为。如果请求体和配置文件中均未设置(或请求体传入null、配置文件中未设置),则默认返回图像。
    • 请求处理成功时,响应体的result具有如下属性:
    名称 类型 含义
    tableRecResults object 表格识别结果。数组长度为1(对于图像输入)或实际处理的文档页数(对于PDF输入)。对于PDF输入,数组中的每个元素依次表示PDF文件中实际处理的每一页的结果。
    dataInfo object 输入数据信息。

    tableRecResults中的每个元素为一个object,具有如下属性:

    名称 类型 含义
    prunedResult object 产线对象的 predict 方法生成结果的 JSON 表示中 res 字段的简化版本,其中去除了 input_pathpage_index 字段。
    outputImages object | null 参见产线预测结果的 img 属性说明。图像为JPEG格式,使用Base64编码。
    inputImage string | null 输入图像。图像为JPEG格式,使用Base64编码。
    多语言调用服务示例
    Python
    import base64
    import requests
    
    API_URL = "http://localhost:8080/table-recognition"
    file_path = "./demo.jpg"
    
    with open(file_path, "rb") as file:
        file_bytes = file.read()
        file_data = base64.b64encode(file_bytes).decode("ascii")
    
    payload = {"file": file_data, "fileType": 1}
    
    response = requests.post(API_URL, json=payload)
    
    assert response.status_code == 200
    result = response.json()["result"]
    for i, res in enumerate(result["tableRecResults"]):
        print(res["prunedResult"])
        for img_name, img in res["outputImages"].items():
            img_path = f"{img_name}_{i}.jpg"
            with open(img_path, "wb") as f:
                f.write(base64.b64decode(img))
            print(f"Output image saved at {img_path}")
    
    C++
    #include <iostream>
    #include <fstream>
    #include <vector>
    #include <string>
    #include "cpp-httplib/httplib.h" // https://github.com/Huiyicc/cpp-httplib
    #include "nlohmann/json.hpp" // https://github.com/nlohmann/json
    #include "base64.hpp" // https://github.com/tobiaslocker/base64
    
    int main() {
        httplib::Client client("localhost", 8080);
        const std::string filePath = "./demo.jpg";
        std::ifstream file(filePath, std::ios::binary | std::ios::ate);
        if (!file) {
            std::cerr << "Error opening file." << std::endl;
            return 1;
        }
    
        std::streamsize size = file.tellg();
        file.seekg(0, std::ios::beg);
        std::vector buffer(size);
    
        if (!file.read(buffer.data(), size)) {
            std::cerr << "Error reading file." << std::endl;
            return 1;
        }
    
        std::string bufferStr(buffer.data(), static_cast(size));
        std::string encodedFile = base64::to_base64(bufferStr);
    
        nlohmann::json jsonObj;
        jsonObj["file"] = encodedFile;
        jsonObj["fileType"] = 1;
    
        auto response = client.Post("/table-recognition", jsonObj.dump(), "application/json");
    
        if (response && response->status == 200) {
            nlohmann::json jsonResponse = nlohmann::json::parse(response->body);
            auto result = jsonResponse["result"];
    
            if (!result.is_object() || !result["tableRecResults"].is_array()) {
                std::cerr << "Unexpected response structure." << std::endl;
                return 1;
            }
    
            for (size_t i = 0; i < result["tableRecResults"].size(); ++i) {
                auto tableRecResult = result["tableRecResults"][i];
                std::cout << tableRecResult["prunedResult"] << std::endl;
    
                if (tableRecResult["outputImages"].is_object()) {
                    for (auto& img : tableRecResult["outputImages"].items()) {
                        std::string imgName = img.key();
                        std::string encodedImage = img.value();
                        std::string decodedImage = base64::from_base64(encodedImage);
    
                        std::string imgPath = imgName + "_" + std::to_string(i) + ".jpg";
                        std::ofstream outputImage(imgPath, std::ios::binary);
                        if (outputImage.is_open()) {
                            outputImage.write(decodedImage.c_str(), static_cast(decodedImage.size()));
                            outputImage.close();
                            std::cout << "Output image saved at " << imgPath << std::endl;
                        } else {
                            std::cerr << "Unable to open file for writing: " << imgPath << std::endl;
                        }
                    }
                }
            }
        } else {
            std::cerr << "Failed to send HTTP request." << std::endl;
            if (response) {
                std::cerr << "HTTP status code: " << response->status << std::endl;
                std::cerr << "Response body: " << response->body << std::endl;
            }
            return 1;
        }
    
        return 0;
    }
    
    Java
    import okhttp3.*;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import com.fasterxml.jackson.databind.JsonNode;
    import com.fasterxml.jackson.databind.node.ObjectNode;
    
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.util.Base64;
    
    public class Main {
        public static void main(String[] args) throws IOException {
            String API_URL = "http://localhost:8080/table-recognition";
            String imagePath = "./demo.jpg";
    
            File file = new File(imagePath);
            byte[] fileContent = java.nio.file.Files.readAllBytes(file.toPath());
            String base64Image = Base64.getEncoder().encodeToString(fileContent);
    
            ObjectMapper objectMapper = new ObjectMapper();
            ObjectNode payload = objectMapper.createObjectNode();
            payload.put("file", base64Image);
            payload.put("fileType", 1);
    
            OkHttpClient client = new OkHttpClient();
            MediaType JSON = MediaType.get("application/json; charset=utf-8");
            RequestBody body = RequestBody.create(JSON, payload.toString());
    
            Request request = new Request.Builder()
                    .url(API_URL)
                    .post(body)
                    .build();
    
            try (Response response = client.newCall(request).execute()) {
                if (response.isSuccessful()) {
                    String responseBody = response.body().string();
                    JsonNode root = objectMapper.readTree(responseBody);
                    JsonNode result = root.get("result");
    
                    JsonNode tableRecResults = result.get("tableRecResults");
                    for (int i = 0; i < tableRecResults.size(); i++) {
                        JsonNode item = tableRecResults.get(i);
    
                        JsonNode prunedResult = item.get("prunedResult");
                        System.out.println("Pruned Result [" + i + "]: " + prunedResult.toString());
    
                        JsonNode outputImages = item.get("outputImages");
    
                        outputImages.fieldNames().forEachRemaining(imgName -> {
                            String imgBase64 = outputImages.get(imgName).asText();
                            byte[] imgBytes = Base64.getDecoder().decode(imgBase64);
                            String imgPath = "output_" + imgName +  ".jpg";
                            try (FileOutputStream fos = new FileOutputStream(imgPath)) {
                                fos.write(imgBytes);
                                System.out.println("Saved image to: " + imgPath);
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        });
                    }
                } else {
                    System.err.println("Request failed with HTTP code: " + response.code());
                }
            }
        }
    }
    
    Go
    package main
    
    import (
        "bytes"
        "encoding/base64"
        "encoding/json"
        "fmt"
        "io/ioutil"
        "net/http"
    )
    
    func main() {
        API_URL := "http://localhost:8080/table-recognition"
        filePath := "./demo.jpg"
    
        fileBytes, err := ioutil.ReadFile(filePath)
        if err != nil {
            fmt.Printf("Error reading file: %v\n", err)
            return
        }
        fileData := base64.StdEncoding.EncodeToString(fileBytes)
    
        payload := map[string]interface{}{
            "file":     fileData,
            "fileType": 1,
        }
        payloadBytes, err := json.Marshal(payload)
        if err != nil {
            fmt.Printf("Error marshaling payload: %v\n", err)
            return
        }
    
        client := &http.Client{}
        req, err := http.NewRequest("POST", API_URL, bytes.NewBuffer(payloadBytes))
        if err != nil {
            fmt.Printf("Error creating request: %v\n", err)
            return
        }
        req.Header.Set("Content-Type", "application/json")
    
        res, err := client.Do(req)
        if err != nil {
            fmt.Printf("Error sending request: %v\n", err)
            return
        }
        defer res.Body.Close()
    
        if res.StatusCode != http.StatusOK {
            fmt.Printf("Unexpected status code: %d\n", res.StatusCode)
            return
        }
    
        body, err := ioutil.ReadAll(res.Body)
        if err != nil {
            fmt.Printf("Error reading response body: %v\n", err)
            return
        }
    
        type TableRecResult struct {
            PrunedResult  map[string]interface{} `json:"prunedResult"`
            OutputImages  map[string]string      `json:"outputImages"`
            InputImage    *string                `json:"inputImage"`
        }
    
        type Response struct {
            Result struct {
                TableRecResults []TableRecResult `json:"tableRecResults"`
                DataInfo        interface{}      `json:"dataInfo"`
            } `json:"result"`
        }
    
        var respData Response
        if err := json.Unmarshal(body, &respData); err != nil {
            fmt.Printf("Error unmarshaling response: %v\n", err)
            return
        }
    
        for i, res := range respData.Result.TableRecResults {
            fmt.Printf("Result %d - prunedResult: %+v\n", i, res.PrunedResult)
    
            for imgName, imgData := range res.OutputImages {
                imgBytes, err := base64.StdEncoding.DecodeString(imgData)
                if err != nil {
                    fmt.Printf("Error decoding image %s_%d: %v\n", imgName, i, err)
                    continue
                }
    
                filename := fmt.Sprintf("%s_%d.jpg", imgName, i)
                if err := ioutil.WriteFile(filename, imgBytes, 0644); err != nil {
                    fmt.Printf("Error saving image %s: %v\n", filename, err)
                    continue
                }
                fmt.Printf("Saved image to %s\n", filename)
            }
        }
    }
    
    C#
    using System;
    using System.IO;
    using System.Net.Http;
    using System.Text;
    using System.Threading.Tasks;
    using Newtonsoft.Json.Linq;
    
    class Program
    {
        static readonly string API_URL = "http://localhost:8080/table-recognition";
        static readonly string inputFilePath = "./demo.jpg";
    
        static async Task Main(string[] args)
        {
            var httpClient = new HttpClient();
    
            byte[] fileBytes = File.ReadAllBytes(inputFilePath);
            string fileData = Convert.ToBase64String(fileBytes);
    
            var payload = new JObject
            {
                { "file", fileData },
                { "fileType", 1 }
            };
            var content = new StringContent(payload.ToString(), Encoding.UTF8, "application/json");
    
            HttpResponseMessage response = await httpClient.PostAsync(API_URL, content);
            response.EnsureSuccessStatusCode();
    
            string responseBody = await response.Content.ReadAsStringAsync();
            JObject jsonResponse = JObject.Parse(responseBody);
    
            JArray tableRecResults = (JArray)jsonResponse["result"]["tableRecResults"];
            for (int i = 0; i < tableRecResults.Count; i++)
            {
                var res = tableRecResults[i];
                Console.WriteLine($"[{i}] prunedResult:\n{res["prunedResult"]}");
    
                JObject outputImages = res["outputImages"] as JObject;
                if (outputImages != null)
                {
                    foreach (var img in outputImages)
                    {
                        string imgName = img.Key;
                        string base64Img = img.Value?.ToString();
                        if (!string.IsNullOrEmpty(base64Img))
                        {
                            string imgPath = $"{imgName}_{i}.jpg";
                            byte[] imageBytes = Convert.FromBase64String(base64Img);
                            File.WriteAllBytes(imgPath, imageBytes);
                            Console.WriteLine($"Output image saved at {imgPath}");
                        }
                    }
                }
            }
        }
    }
    
    Node.js
    const axios = require('axios');
    const fs = require('fs');
    const path = require('path');
    
    const API_URL = 'http://localhost:8080/table-recognition';
    const inputImagePath = './demo.jpg';
    
    function encodeImageToBase64(filePath) {
      const bitmap = fs.readFileSync(filePath);
      return Buffer.from(bitmap).toString('base64');
    }
    
    async function callTableRecognitionAPI() {
      const payload = {
        file: encodeImageToBase64(inputImagePath),
        fileType: 1
      };
    
      try {
        const response = await axios.post(API_URL, payload, {
          headers: {
            'Content-Type': 'application/json'
          },
          maxBodyLength: Infinity
        });
    
        const results = response.data.result.tableRecResults;
    
        results.forEach((res, index) => {
          console.log(`Result [${index}] prunedResult:\n`, res.prunedResult);
    
          const outputImages = res.outputImages || {};
          Object.entries(outputImages).forEach(([imgName, base64Img]) => {
            const outputPath = `${imgName}_${index}.jpg`;
            fs.writeFileSync(outputPath, Buffer.from(base64Img, 'base64'));
            console.log(`Saved image: ${outputPath}`);
          });
        });
    
      } catch (error) {
        console.error('API request failed:', error.message);
      }
    }
    
    callTableRecognitionAPI();
    
    

    PHP

    <?php

    $API_URL = "http://localhost:8080/table-recognition"; $image_path = "./demo.jpg";

    $image_data = base64_encode(file_get_contents($image_path)); $payload = array(

    "file" => $image_data,
    "fileType" => 1
    

    );

    $ch = curl_init($API_URL); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload)); curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json')); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($ch); curl_close($ch);

    $result_array = json_decode($response, true); $results = $result_array["result"]["tableRecResults"];

    foreach ($results as $i => $item) {

    echo "[$i] prunedResult:\n";
    print_r($item["prunedResult"]);
    
    if (!empty($item["outputImages"])) {
        foreach ($item["outputImages"] as $img_name => $base64_img) {
            $img_path = $img_name . "_" . $i . ".jpg";
            file_put_contents($img_path, base64_decode($base64_img));
            echo "Output image saved at $img_path\n";
        }
    } else {
        echo "No outputImages found for item $i\n";
    }
    

    } ?>


    📱 端侧部署:端侧部署是一种将计算和数据处理功能放在用户设备本身上的方式,设备可以直接处理数据,而不需要依赖远程的服务器。PaddleX 支持将模型部署在 Android 等端侧设备上,详细的端侧部署流程请参考PaddleX端侧部署指南。 您可以根据需要选择合适的方式部署模型产线,进而进行后续的 AI 应用集成。

    4. 二次开发

    如果通用表格识别产线提供的默认模型权重在您的场景中,精度或速度不满意,您可以尝试利用您自己拥有的特定领域或应用场景的数据对现有模型进行进一步的微调,以提升通用表格识别产线的在您的场景中的识别效果。

    4.1 模型微调

    由于通用表格识别产线包含若干模块,模型产线的效果如果不及预期,可能来自于其中任何一个模块。您可以对识别效果差的图片进行分析,进而确定是哪个模块存在问题,并参考以下表格中对应的微调教程链接进行模型微调。

    情形 微调模块 微调参考链接
    表格结构识别错误或单元格定位错误 表格结构识别模块 链接
    未能成功检测到表格所在区域 版面区域检测模块 链接
    文本存在漏检 文本检测模块 链接
    文本内容都不准 文本识别模块 链接
    整图旋转矫正不准 文档图像方向分类模块 链接
    图像扭曲矫正不准 文本图像矫正模块 暂不支持微调

    4.2 模型应用

    当您使用私有数据集完成微调训练后,可获得本地模型权重文件。

    若您需要使用微调后的模型权重,只需对产线配置文件做修改,将微调后模型权重的本地路径替换至产线配置文件中的对应位置即可:

    SubModules:
      LayoutDetection:
        module_name: layout_detection
        model_name: PicoDet_layout_1x_table
        model_dir: null # 替换为微调后的版面区域检测模型权重路径
    
      TableStructureRecognition:
        module_name: table_structure_recognition
        model_name: SLANet_plus
        model_dir: null # 替换为微调后的表格结构识别模型权重路径
    
    SubPipelines:
      DocPreprocessor:
        pipeline_name: doc_preprocessor
        use_doc_orientation_classify: True
        use_doc_unwarping: True
        SubModules:
          DocOrientationClassify:
            module_name: doc_text_orientation
            model_name: PP-LCNet_x1_0_doc_ori
            model_dir: null # 替换为微调后的文档图像方向分类模型权重路径
    
          DocUnwarping:
            module_name: image_unwarping
            model_name: UVDoc
            model_dir: null
    
      GeneralOCR:
        pipeline_name: OCR
        text_type: general
        use_doc_preprocessor: False
        use_textline_orientation: False
        SubModules:
          TextDetection:
            module_name: text_detection
            model_name: PP-OCRv5_server_det
            model_dir: null # 替换为微调后的文本检测模型权重路径
            limit_side_len: 960
            limit_type: max
            max_side_limit: 4000
            thresh: 0.3
            box_thresh: 0.4
            unclip_ratio: 1.5
          TextRecognition:
            module_name: text_recognition
            model_name: PP-OCRv5_server_rec
            model_dir: null # 替换为微调后文本识别的模型权重路径
            batch_size: 1
            score_thresh: 0
    

    随后, 参考2.2 本地体验中的命令行方式或Python脚本方式,加载修改后的产线配置文件即可。

    5. 多硬件支持

    PaddleX 支持英伟达 GPU、昆仑芯 XPU、昇腾 NPU和寒武纪 MLU 等多种主流硬件设备,仅需修改 --device 参数即可完成不同硬件之间的无缝切换。

    例如,您使用昇腾 NPU 进行 OCR 产线的推理,使用的 CLI 命令为:

    paddlex --pipeline table_recognition \
            --use_doc_orientation_classify=False \
            --use_doc_unwarping=False \
            --input table_recognition.jpg \
            --save_path ./output \
            --device npu:0
    

    当然,您也可以在 Python 脚本中 create_pipeline() 时或者 predict() 时指定硬件设备。

    若您想在更多种类的硬件上使用通用表格识别产线,请参考PaddleX多硬件使用指南