PaddleOCR 版面恢复(Layout Recovery)实战:将 PDF 与文档图像一键还原为可编辑 Word / Markdown
【免费下载链接】PaddleOCR飞桨多语言OCR工具包(实用超轻量OCR系统,支持80+种语言识别,提供数据标注与合成工具,支持服务器、移动端、嵌入式及IoT设备端的训练与部署) Awesome multilingual OCR toolkits based on PaddlePaddle (practical ultra lightweight OCR system, support 80+ languages recognition, provide data annotation and synthesis tools, support training and deployment among server, mobile, embedded and IoT devices)项目地址: https://gitcode.com/paddlepaddle/PaddleOCR
本篇技术指南系统讲解 PaddleOCR 版面恢复(Layout Recovery)模块的完整使用方法:它可以把扫描 PDF、图像格式 PDF 与普通文档图片恢复成与原始版面一致的可编辑 Word 文档,并支持输出 Markdown。你将掌握两种恢复方案的原理与选型、环境安装、模型下载、命令行参数配置,以及从源码层面理解单栏/双栏识别、表格 HTML 转 docx、段落合并等核心实现细节,可直接用于论文扫描件、合同、报表等文档的数字化整理。
1. 什么是版面恢复:两种方案与适用场景
版面恢复模块(位于 ppstructure/recovery/)用于将图像或 PDF 恢复成与原图版面一致的、可编辑的 Word 文件。PaddleOCR 提供了两种恢复方法,可以根据 PDF 的类型来选择:
- 标准 PDF 解析(Standard PDF parse,输入为标准 PDF):基于 Python 的 PDF 转 Word 库 pdf2docx 优化而来。该方法使用 PyMuPDF 从 PDF 中提取数据,再用规则解析版面,最后用 python-docx 生成 docx 文件。
- 图像格式 PDF 解析(Image format PDF parse,输入可以是标准 PDF 或图像格式 PDF):版面恢复结合版面分析、表格识别两个子模块,对图片、表格、标题等元素做更好的恢复,支持中英文的 PDF 与文档图像输入。
两种方法的输入格式与应用场景对比如下(继承自官方文档):
| 方法 | 输入格式 | 应用场景 / 优缺点 |
|---|---|---|
| 标准 PDF 解析 | 优点:对非纸质文档恢复效果更好,恢复后每页仍保持在同一页; 缺点:部分中文文档中的英文字符会乱码,部分内容仍会超出当前页面,整页内容被恢复成表格格式,部分图片恢复效果不佳 | |
| 图像格式 PDF 解析 | pdf、图片 | 优点:更适合纸质文档内容恢复,OCR 识别效果更好; 缺点:目前基于规则恢复,内容排版(间距、字体等)效果有待进一步提升,且版面恢复效果依赖版面分析 |
从源码结构看,两种方案在 ppstructure/predict_system.py 中通过use_pdf2docx_api参数分流:置为True时走 pdf2docx 路线,置为False(默认)时走基于 OCR 与版面分析的完整恢复链路。
2. 环境安装
2.1 安装 PaddlePaddle
python3 -m pip install --upgrade pip # 机器上装有 cuda9 或 cuda10 时,运行下面命令安装 GPU 版本 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更详细的安装要求可参考 PaddlePaddle 官方安装文档(根据自身 CUDA 版本选择对应指令)。
2.2 安装 PaddleOCR
(1)下载源码
git clone https://github.com/PaddlePaddle/PaddleOCR(2)安装版面恢复的requirements
版面恢复最终导出为 docx 文件,因此需要安装 python-docx API;同时需要安装 PyMuPDF API 来处理 PDF 格式的输入文件(PyMuPDF 要求 Python >= 3.7)。运行下面的命令安装全部依赖库:
python3 -m pip install -r ppstructure/recovery/requirements.txt查看 ppstructure/recovery/requirements.txt 可以看到恢复模块的核心依赖为:
python-docx # 生成 docx 文档 beautifulsoup4 # 表格 HTML 解析 fonttools>=4.43.0 # 字体处理 fire>=0.3.0 # CLI 工具库如果使用标准 PDF 解析方法,还需要额外安装 pdf2docx 库:
wget https://paddleocr.bj.bcebos.com/whl/pdf2docx-0.0.0-py3-none-any.whl pip3 install pdf2docx-0.0.0-py3-none-any.whl3. 方案一:标准 PDF 解析(pdf2docx 路线)
use_pdf2docx_api参数用于启用基于 PDF 解析的版面恢复。该方案直接读取 PDF 内部已有的文字与矢量信息,不做 OCR,因此对非扫描件的数字原生 PDF 恢复效果更好,且恢复后每一页内容仍保持在同一页。
whl 包提供了快速使用方式(安装paddleocr>=2.6后):
pip3 install "paddleocr>=2.6" paddleocr --image_dir=ppstructure/docs/recovery/UnrealText.pdf --type=structure --recovery=true --use_pdf2docx_api=true命令行方式(在 PaddleOCR 仓库根目录执行):
python3 predict_system.py \ --image_dir=ppstructure/docs/recovery/UnrealText.pdf \ --recovery=True \ --use_pdf2docx_api=True \ --output=../output/源码调用链:在 ppstructure/predict_system.py 的main()中,当args.recovery and args.use_pdf2docx_api and flag_pdf同时成立时,直接调用pdf2docx.converter.Converter完成转换,并跳过后续的 OCR/版面分析流程:
try_import("pdf2docx") from pdf2docx.converter import Converter os.makedirs(args.output, exist_ok=True) docx_file = os.path.join(args.output, "{}_api.docx".format(img_name)) cv = Converter(image_file) cv.convert(docx_file) cv.close()可以看到生成的 docx 以_api.docx后缀命名,与基于 OCR 的方案(_ocr.docx)区分。注意ppstructure/docs/目录在当前仓库中已随文档结构调整,运行时请将--image_dir替换为实际存在的 PDF 文件路径。
4. 方案二:基于 OCR 的图像格式 PDF 解析
4.1 原理与流程
通过版面分析,将图像/PDF 文档划分为若干区域,定位出文本、表格、图片等关键区域,并记录每个区域的位置、类别和区域像素值信息。不同区域被分开处理:
- 文本区域:执行 OCR 检测与识别,在原有信息基础上补充 OCR 检测框坐标和文本内容信息;
- 表格区域:识别表格,记录表格的 html 与文本信息;
- 图片区域:直接保存图片。
最后通过版面信息、OCR 检测识别结果、表格信息和保存的图片,即可还原出测试图片对应的文档。
whl 包快速使用方式:
paddleocr --image_dir=ppstructure/docs/table/1.png --type=structure --recovery=true --lang='en'4.2 下载模型
输入为英文文档时,下载英文模型:
cd PaddleOCR/ppstructure # 下载模型 mkdir inference && cd inference # 下载超轻量英文 PP-OCRv3 检测模型并解压 wget https://paddleocr.bj.bcebos.com/PP-OCRv3/english/en_PP-OCRv3_det_infer.tar && tar xf en_PP-OCRv3_det_infer.tar # 下载超轻量英文 PP-OCRv3 识别模型并解压 wget https://paddleocr.bj.bcebos.com/PP-OCRv3/english/en_PP-OCRv3_rec_infer.tar && tar xf en_PP-OCRv3_rec_infer.tar # 下载超轻量英文表格识别模型并解压 wget https://paddleocr.bj.bcebos.com/ppstructure/models/slanet/paddle3.0b2/en_ppstructure_mobile_v2.0_SLANet_infer.tar tar xf en_ppstructure_mobile_v2.0_SLANet_infer.tar # 下载 publaynet 数据集版面分析模型并解压 wget https://paddleocr.bj.bcebos.com/ppstructure/models/layout/picodet_lcnet_x1_0_fgd_layout_infer.tar tar xf picodet_lcnet_x1_0_fgd_layout_infer.tar cd ..输入为中文文档时,下载中文模型:中英文超轻量 PP-OCRv3 模型、表格识别模型与版面分析模型,具体下载地址可参考 docs/version3.x/model_list.md 中的 PP-OCR 系列模型列表(PP-OCRv3 检测/识别)、表格识别模型与版面分析模型小节。中文场景下,识别字典、版面分析字典也需要同步切换到中文版本(见 4.3 参数说明)。
4.3 版面恢复命令与参数详解
python3 predict_system.py \ --image_dir=./docs/table/1.png \ --det_model_dir=inference/en_PP-OCRv3_det_infer \ --rec_model_dir=inference/en_PP-OCRv3_rec_infer \ --rec_char_dict_path=../ppocr/utils/en_dict.txt \ --table_model_dir=inference/en_ppstructure_mobile_v2.0_SLANet_infer \ --table_char_dict_path=../ppocr/utils/dict/table_structure_dict.txt \ --layout_model_dir=inference/picodet_lcnet_x1_0_fgd_layout_infer \ --layout_dict_path=../ppocr/utils/dict/layout_dict/layout_publaynet_dict.txt \ --vis_font_path=../doc/fonts/simfang.ttf \ --recovery=True \ --output=../output/运行结束后,每张图片对应的 docx 会保存在output字段指定的目录中。官方文档字段说明及对应源码默认值整理如下(默认值来自 ppstructure/utility.py 的参数定义):
| 参数 | 说明 | 默认值 / 注意事项 |
|---|---|---|
image_dir | 测试文件,可以是图片、图片目录、PDF 文件、PDF 文件目录 | 必填 |
det_model_dir | OCR 检测模型路径 | 必填(英文场景为en_PP-OCRv3_det_infer) |
rec_model_dir | OCR 识别模型路径 | 必填 |
rec_char_dict_path | OCR 识别字典路径 | 使用中文模型时改为../ppocr/utils/ppocr_keys_v1.txt;使用自己数据集训练的模型时改为训练字典 |
table_model_dir | 表格识别模型路径 | 必填 |
table_char_dict_path | 表格识别字典路径 | 使用中文模型时无需修改(源码默认../ppocr/utils/dict/table_structure_dict_ch.txt) |
layout_model_dir | 版面分析模型路径 | 必填 |
layout_dict_path | 版面分析字典路径 | 使用中文模型时改为../ppocr/utils/dict/layout_dict/layout_cdla_dict.txt(源码默认layout_publaynet_dict.txt) |
recovery | 是否开启版面恢复 | 默认False |
output | 保存恢复结果的路径 | 默认./output(源码定义) |
vis_font_path | 可视化与 docx 排版使用的字体 | 中文推荐doc/fonts/simfang.ttf(仓库已提供) |
除上述字段外,ppstructure/utility.py 还定义了一批影响恢复质量的进阶参数,可按需调整:
recovery_to_markdown(默认False):是否同时把恢复结果导出为 Markdown 文件;use_pdf2docx_api(默认False):是否启用标准 PDF 解析方案;layout_score_threshold(默认0.5):版面分析区域的分数阈值;layout_nms_threshold(默认0.5):版面分析区域的 NMS 阈值;table_max_len(默认488):表格识别输入最大边长;table_algorithm(默认TableAttn):表格结构识别算法;merge_no_span_structure(默认True):是否合并无跨行跨列的表格结构;mode(默认structure):支持structure(版面结构化)与kie(关键信息抽取)两种模式。
5. 源码剖析:版面恢复如何生成 docx 与 Markdown
理解恢复模块的输出管线,需要先了解 ppstructure/predict_system.py 中StructureSystem的产出结构:__call__返回res_list,每个元素是一个区域 dict,包含type(如 text / title / table / figure / equation)、bbox(区域坐标)、res(区域内容)与img_idx等字段。在main()中,恢复逻辑在拿到这些区域结果后依次执行:
if args.recovery and res != []: from ppstructure.recovery.recovery_to_doc import ( sorted_layout_boxes, convert_info_docx, ) from ppstructure.recovery.recovery_to_markdown import ( convert_info_markdown, ) h, w, _ = img.shape res = sorted_layout_boxes(res, w) all_res += res ... if args.recovery and all_res != []: convert_info_docx(img, all_res, save_folder, img_name) if args.recovery_to_markdown: convert_info_markdown(all_res, save_folder, img_name)即:先对整页区域按阅读顺序排序(sorted_layout_boxes),再调用 recovery_to_doc.py 的convert_info_docx生成 Word,若开启recovery_to_markdown,还会调用 recovery_to_markdown.py 的convert_info_markdown生成 Markdown。下面逐个剖析。
5.1 单栏 / 双栏版面排序:sorted_layout_boxes
convert_info_docx使用WD_SECTION.CONTINUOUS分节来模拟原文档的单栏/双栏混排。判断依据来自 recovery_to_doc.py 中的sorted_layout_boxes(res, w)函数:
- 以页面宽度
w为基准,把区域按"上到下、左到右"排序(sorted(res, key=lambda x: (x["bbox"][1], x["bbox"][0]))); - 当区域框横跨中轴(
x0 < w/2且x2 > w/2)或占据大部分宽度时,标记为single(单栏); - 当区域框落在左半区(
x0 < w/4且x2 < 3*w/4)或右半区(x0 > w/4且x2 > w/2)时,标记为double(双栏),并分别归入res_left/res_right列表,最终合并输出。
convert_info_docx中根据region["layout"]动态切换节的列数:检测到double时把w:cols设为2,检测回single时设回1,从而在 docx 中还原原始论文/书籍的双栏排布。
5.2 docx 生成细节:convert_info_docx
recovery_to_doc.py 的convert_info_docx(img, res, save_folder, img_name)负责把区域结果写入 python-docx 文档,默认样式为:正文字体Times New Roman+ 中文宋体、字号 6.5pt。各类型区域的处理策略:
- figure(图片):读取预处理阶段保存到
save_folder/img_name/{bbox}_{img_idx}.jpg的图片,居中插入;单栏下宽 5 英寸,双栏下宽 2 英寸; - title(标题):通过
doc.add_heading(region["res"][0]["text"])生成标题段落; - table(表格):实例化
HtmlToDocx解析器,用TableGrid样式把表格 HTML 还原为 Word 表格; - equation(公式):
latex结果在 docx 管线中暂不渲染(直接跳过); - text / 其他:逐行写入普通段落,首行缩进 0.25 英寸,字号 10pt。
最终文件保存为{img_name}_ocr.docx,并输出日志docx save to ...。
5.3 表格 HTML 转 Word:HtmlToDocx
ppstructure/recovery/table_process.py 实现了一个基于HTMLParser与 BeautifulSoup 的 HTML→docx 转换器(代码参考自开源 html2docx 项目)。核心能力包括:
- 通过 CSS 选择器
table > tr、table > thead > tr等解析表格行列结构,并累加colspan得到总列数; - 支持
colspan/rowspan合并单元格(docx_cell.merge(...)),并跳过已合并占用的单元格; - 支持嵌套表格(
ignore_nested_tables只保留最外层表格); - 支持
b、strong、em、i、u、s、sup、sub等内联样式与code/pre的等宽字体映射,th表头自动加粗; - 自动清理多余空白与换行,保证单元格内容整洁。
正是这套转换器,让表格识别模型输出的<table><tr><td>...HTML 结构能够无损还原为可编辑的 Word 表格。
5.4 Markdown 输出与段落合并:convert_info_markdown
开启--recovery_to_markdown=True后,恢复结果会额外保存为{img_name}_ocr.md。 recovery_to_markdown.py 中的convert_info_markdown按区域类型输出:
- figure:输出居中的
<img src="...">引用; - title:输出
# 标题一级标题行; - table:直接写入表格 HTML 原文;
- equation:以
$$latex$$形式输出公式; - header / footer:跳过页眉页脚;
- text:调用段落合并函数还原自然段落,并转义
*、`、~、$等 Markdown 特殊字符。
其中段落合并是该模块最有意思的规则:check_merge_method依据"文本区域 bbox 左边界与第一行文字左边界之间的距离x1_distance是否大于首行行高"来选择合并策略:
convert_text_space_head(段首缩进判据):当两行文字起始x坐标之差小于行高h时视为同一段落,否则插入\n\n分段;convert_text_space_tail(段末空白判据):计算每行宽度是否接近整行宽(row_width >= width - row_height),满行视为本段继续,未满行则说明段落到此为止。
这种"基于排版几何特征"的启发式合并,正是文档中提到的"目前基于规则恢复、排版效果待提升"的对应实现。
6. 常见问题与进阶建议
- 英文乱码 / 内容超出页面:这是标准 PDF 解析方案对中文文档的已知短板,此时建议改用方案二(图像格式 PDF 解析 + OCR),对纸质或混排文档效果更好;
- 恢复效果依赖版面分析:方案二的文本区域合并、表格抽取都建立在版面分析区域划分之上,可通过调整
layout_score_threshold/layout_nms_threshold(默认均为 0.5)或替换更优的版面分析模型来改善; - 中文字体:docx 中文字体依赖
--vis_font_path指定的字体,仓库内置 doc/fonts/simfang.ttf(仿宋),可直接使用; - 批量处理:
image_dir支持传入图片/PDF 目录,配合--process_id、--total_process_num(多进程参数,见 ppstructure/predict_system.py 的use_mp分支)即可并行处理大批量文档。
7. 更多资源
- 版面分析模块的训练、评估与推理教程:ppstructure/layout/README.md
- 表格识别模块的训练、评估与推理教程:ppstructure/table/README.md
- 版面恢复相关 Python 实现:ppstructure/recovery/recovery_to_doc.py、ppstructure/recovery/recovery_to_markdown.py、ppstructure/recovery/table_process.py
- 结构识别主流程与参数解析:ppstructure/predict_system.py、ppstructure/utility.py
- 快速上手文档:docs/quick_start.en.md(中文版见 docs/quick_start.md)
- 模型列表与下载:docs/version3.x/model_list.md
【免费下载链接】PaddleOCR飞桨多语言OCR工具包(实用超轻量OCR系统,支持80+种语言识别,提供数据标注与合成工具,支持服务器、移动端、嵌入式及IoT设备端的训练与部署) Awesome multilingual OCR toolkits based on PaddlePaddle (practical ultra lightweight OCR system, support 80+ languages recognition, provide data annotation and synthesis tools, support training and deployment among server, mobile, embedded and IoT devices)项目地址: https://gitcode.com/paddlepaddle/PaddleOCR
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考