如何在mindee docTR中保留文档结构,便于Java正则提取数据?
解决docTR提取PDF文本结构混乱的问题
针对你用docTR提取结构化PDF时输出错位、导致Java正则提取困难的问题,可通过以下方案解决:
1. 启用docTR的布局分析模式
docTR默认的纯文本提取会忽略文档的区块结构,开启布局分析后,模型会先识别文档中的逻辑区块(如标题、标签、内容行),再按区块顺序输出,能最大程度保留原文档的行对应关系。
示例Python代码:
from doctr.io import DocumentFile from doctr.models import ocr_predictor # 加载带布局分析的OCR模型 predictor = ocr_predictor(det_arch='db_resnet50', reco_arch='crnn_vgg16_bn', pretrained=True, layout_analysis=True) doc = DocumentFile.from_pdf("target_receipt.pdf") result = predictor(doc) # 按区块层级输出文本,区块间用空行分隔 for page in result.pages: for block in page.blocks: for line in block.lines: print(" ".join([word.value for word in line.words])) print("\n")
2. 自定义键值对对齐逻辑
如果布局分析后仍有少量错位,可通过预设的标签列表,强制将内容与对应标签绑定,避免正则匹配的复杂性。
Java伪代码实现:
import java.util.*; public class ReceiptParser { public static void main(String[] args) { String extractedText = "你的docTR输出文本"; List<String> lines = Arrays.asList(extractedText.split("\n")); Map<String, String> receiptData = new HashMap<>(); // 预设PDF中的标签集合 Set<String> keys = new HashSet<>(Arrays.asList( "ABC Receipt", "Nature of request", "Request Code", "status of application", "observation" )); String currentKey = null; StringBuilder currentValue = new StringBuilder(); for (String line : lines) { line = line.trim(); if (keys.contains(line)) { // 保存上一组键值对 if (currentKey != null) { receiptData.put(currentKey, currentValue.toString().trim()); currentValue.setLength(0); } currentKey = line; } else if (currentKey != null && !line.isEmpty()) { currentValue.append(line).append(" "); } } // 处理最后一组键值对 if (currentKey != null) { receiptData.put(currentKey, currentValue.toString().trim()); } // 输出整理后的结构化数据 receiptData.forEach((k, v) -> System.out.println(k + ": " + v)); } }
3. 优化PDF预处理参数
若PDF存在扫描模糊、字体异常等问题,可调整预处理参数提升识别精度,减少行错位:
- 开启
preserve_aspect_ratio=True避免缩放扭曲行结构; - 手动二值化增强文本对比度,降低识别错误率。
示例代码片段:
from doctr.io import DocumentFile from doctr.utils import binarize # 保留PDF原始比例加载 doc = DocumentFile.from_pdf("target_receipt.pdf", preserve_aspect_ratio=True) # 手动二值化预处理 processed_pages = [binarize(page) for page in doc] # 再传入模型进行识别 result = predictor(processed_pages)
内容的提问来源于stack exchange,提问作者Rex
相关产品推荐
相关产品推荐

