如何将扫描版PDF转DOCX并利用layout-parser保留图表表格与格式
用Layout Parser实现扫描PDF转DOCX并保留图表表格格式
整体流程概述
扫描PDF本质是图片集合,要保留格式转DOCX需分三步:PDF转高清图片→Layout Parser版面分析(区分文本/表格/图表)→分区域处理后整合到DOCX。以下是具体实现方案:
1. 准备依赖
先安装所需工具库:
pip install layoutparser pdf2image easyocr python-docx table-transformer opencv-python
2. 扫描PDF转高清图片
用pdf2image将PDF每页转为300DPI的PNG(高DPI是OCR和版面分析准确率的关键):
from pdf2image import convert_from_path # 转换PDF为图片列表 pages = convert_from_path("scanned_document.pdf", dpi=300) # 保存单页图片 for idx, page in enumerate(pages): page.save(f"page_{idx+1}.png", "PNG")
3. Layout Parser版面分析
加载预训练的PubLayNet模型,识别页面中的文本、表格、图表区域,并按阅读顺序排序:
import layoutparser as lp # 加载预训练版面分析模型(支持识别文本、标题、列表、表格、图表) model = lp.Detectron2LayoutModel( config_path="lp://PubLayNet/mask_rcnn_X_101_32x8d_FPN_3x/config", label_map={0: "Text", 1: "Title", 2: "List", 3:"Table", 4:"Figure"}, extra_config=["MODEL.ROI_HEADS.SCORE_THRESH_TEST", 0.8] # 过滤低置信度区域 ) # 处理单页图片示例 image = lp.read_image("page_1.png") layout = model.detect(image) # 按区域类型分类 text_blocks = [block for block in layout if block.type in ["Text", "Title", "List"]] table_blocks = [block for block in layout if block.type == "Table"] figure_blocks = [block for block in layout if block.type == "Figure"] # 按页面阅读顺序排序(从上到下,从左到右) text_blocks = lp.Layout(text_blocks).sort(key=lambda x: (x.coordinates[1], x.coordinates[0])) table_blocks = lp.Layout(table_blocks).sort(key=lambda x: (x.coordinates[1], x.coordinates[0])) figure_blocks = lp.Layout(figure_blocks).sort(key=lambda x: (x.coordinates[1], x.coordinates[0]))
4. 分区域处理内容
文本区域:用EasyOCR替代pytesseract提升识别效果
EasyOCR无需额外配置,多语言支持更好,复杂排版下准确率优于pytesseract:
import easyocr # 初始化OCR阅读器(支持多语言,比如中文+英文:['ch_sim','en']) reader = easyocr.Reader(['en']) text_content = [] for block in text_blocks: # 裁剪文本区域 segment_image = image.crop(block.coordinates) # OCR识别 result = reader.readtext(segment_image) # 拼接文本内容 block_text = "\n".join([text for (bbox, text, score) in result]) text_content.append((block, block_text))
表格区域:用Table Transformer提取结构化表格
专门的表格识别模型,能准确提取行列结构和单元格内容:
from table_transformer import TableStructureRecognizer, TableOCR # 初始化表格识别工具 tsr = TableStructureRecognizer() table_ocr = TableOCR(reader) # 复用之前的EasyOCR实例 table_contents = [] for table_block in table_blocks: table_image = image.crop(table_block.coordinates) # 识别表格行列结构 table_structure = tsr.predict(table_image) # 提取单元格文本 table_data = table_ocr.predict(table_image, table_structure) table_contents.append((table_block, table_data))
图表区域:保留原始图像
直接裁剪图表区域保存为临时文件,后续插入DOCX:
import os if not os.path.exists("temp_figures"): os.mkdir("temp_figures") figure_paths = [] for idx, fig_block in enumerate(figure_blocks): fig_image = image.crop(fig_block.coordinates) fig_path = f"temp_figures/figure_{idx+1}.png" fig_image.save(fig_path) figure_paths.append((fig_block, fig_path))
5. 整合内容到DOCX
用python-docx按页面顺序插入文本、表格、图片,还原原PDF排版:
from docx import Document from docx.shared import Inches doc = Document() # 合并所有区域并按阅读顺序排序 all_blocks = text_content + table_contents + figure_paths all_blocks.sort(key=lambda x: (x[0].coordinates[1], x[0].coordinates[0])) for block in all_blocks: block_obj, content = block if block_obj.type in ["Text", "Title", "List"]: # 标题用Heading样式,普通文本用Paragraph if block_obj.type == "Title": doc.add_heading(content, level=1) else: doc.add_paragraph(content) elif block_obj.type == "Table": # 生成对应行列的表格 table_data = content table = doc.add_table(rows=len(table_data), cols=len(table_data[0])) for i in range(len(table_data)): for j in range(len(table_data[i])): table.cell(i,j).text = table_data[i][j] elif block_obj.type == "Figure": # 插入图片并适配页面宽度 doc.add_picture(content, width=Inches(6)) # 保存最终DOCX doc.save("converted_document.docx")
额外优化建议
- 若OCR效果不佳,可对图片做预处理(灰度化、降噪、二值化):
import cv2 def preprocess_image(image_path): img = cv2.imread(image_path) gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) denoised = cv2.GaussianBlur(gray, (3,3), 0) _, thresh = cv2.threshold(denoised, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU) return thresh
处理图片时替换为image = preprocess_image("page_1.png")即可。
- 超复杂表格可尝试TableNet模型,进一步提升结构识别准确率。
内容的提问来源于stack exchange,提问作者Musaib Ahmed Razzaqui
相关产品推荐
相关产品推荐

