# OCR识别差异分析与改进方案 ## 📊 问题描述 对比两个OCR识别结果: - **PPStructureV3**:准确率高,文本识别完整 - **统一OCR框架(MinerU封装)**:很多文本未识别,部分文本块检测错误 ### 典型错误示例 从 `bank_statement_yusys_v2/2023年度报告母公司_page_003.json` 中发现的错误: | 正确文本 | 识别结果 | 匹配分数 | 问题 | |---------|---------|---------|------| | 合同资产 | 货资产 | 80.0% | 检测框不完整 | | 其他应付款 | 税款 | 66.67% | 检测框错误 | | 长期待摊费用 | 效用 | 66.67% | 检测框错误 | | 其他非流动资产 | 非其非产动产 | 61.54% | 检测框合并错误 | | 资本公积 | 资公存股 | 66.67% | 检测框合并错误 | ## 🔍 根本原因分析 ### 1. **检测参数差异** | 参数 | PPStructureV3 | MinerU默认 | 影响 | |-----|--------------|-----------|------| | `box_thresh` | **0.6** | **0.3** | 阈值过低导致检测到大量噪声框 | | `unclip_ratio` | **1.5** | **1.8** | 扩展比例过高,框不够精确 | | `thresh` | 0.3 | 0.3 | 相同 | **问题**: - `box_thresh=0.3` 太低,会检测到很多低置信度的噪声框 - 这些噪声框可能被错误地合并到正确的文本框中 - 导致最终识别结果不准确 ### 2. **检测框合并策略** | 特性 | PPStructureV3 | MinerU | 影响 | |-----|--------------|--------|------| | 框合并 | 无(或更保守) | `enable_merge_det_boxes=True` | 可能错误合并相邻文本块 | **问题**: - `enable_merge_det_boxes=True` 会合并相邻的检测框 - 对于表格等密集文本,可能将不同单元格的文本错误合并 - 例如:"其他非流动资产" 被合并成 "非其非产动产" ### 3. **识别置信度过滤** | 参数 | PPStructureV3 | MinerU | 影响 | |-----|--------------|--------|------| | `score_thresh` | **0.0** | **0.5** | 丢弃低置信度结果 | **问题**: - `drop_score=0.5` 会丢弃置信度 < 0.5 的识别结果 - 某些正确但置信度较低的文本可能被丢弃 - PPStructureV3 使用 `score_thresh=0.0`,保留所有结果 ### 4. **文本行方向识别** | 特性 | PPStructureV3 | MinerU | 影响 | |-----|--------------|--------|------| | 文本行方向识别 | ✅ `use_textline_orientation: True` | ❌ 无 | 倾斜文本识别错误 | **问题**: - PPStructureV3 有专门的文本行方向识别模块 - 可以处理倾斜的文本行,提高识别准确率 - MinerU 缺少此功能 ### 5. **模型版本差异** | 组件 | PPStructureV3 | MinerU | 影响 | |-----|--------------|--------|------| | 检测模型 | PP-OCRv5_server_det | ch/ch_lite | 可能使用较旧版本 | | 识别模型 | PP-OCRv5_server_rec | ch/ch_lite | 可能使用较旧版本 | **问题**: - PP-OCRv5_server 是较新的模型,准确率更高 - MinerU 可能使用较旧版本的模型 ## 💡 改进方案 ### 方案1:调整OCR参数(推荐,快速改进) 修改 `MinerUOCRRecognizer` 的初始化参数,使其更接近 PPStructureV3: ```python # 在 mineru_adapter.py 中修改 self.ocr_model = self.atom_model_manager.get_atom_model( atom_model_name=AtomicModel.OCR, det_db_box_thresh=0.6, # 从 0.3 提高到 0.6 lang=self.config.get('language', 'ch'), det_db_unclip_ratio=1.5, # 从 1.8 降低到 1.5 enable_merge_det_boxes=False, # 从 True 改为 False(表格场景) ) ``` **优点**: - ✅ 快速实施,无需修改核心代码 - ✅ 可以显著提高检测准确率 - ✅ 减少错误合并 **缺点**: - ⚠️ 可能漏检一些低置信度的文本(但通常这些是噪声) - ⚠️ 对于非表格场景,可能需要 `enable_merge_det_boxes=True` ### 方案2:降低识别置信度阈值 修改 `drop_score` 参数,保留更多识别结果: ```python # 需要修改 PytorchPaddleOCR 的初始化 kwargs['drop_score'] = 0.3 # 从默认 0.5 降低到 0.3 ``` **优点**: - ✅ 保留更多识别结果 - ✅ 减少误丢弃 **缺点**: - ⚠️ 可能引入更多噪声结果 - ⚠️ 需要修改 MinerU 核心代码 ### 方案3:根据场景动态调整参数(最佳方案) 根据文档类型(表格/文本)和PDF类型(扫描件/数字PDF)动态调整参数: ```python def get_ocr_config(pdf_type: str, has_tables: bool) -> Dict[str, Any]: """根据场景返回OCR配置""" if has_tables: # 表格场景:更严格的检测,不合并框 return { 'det_db_box_thresh': 0.6, 'det_db_unclip_ratio': 1.5, 'enable_merge_det_boxes': False, 'drop_score': 0.3, } elif pdf_type == 'txt': # 数字PDF:可以合并框,提高检测阈值 return { 'det_db_box_thresh': 0.5, 'det_db_unclip_ratio': 1.6, 'enable_merge_det_boxes': True, 'drop_score': 0.3, } else: # 扫描件:平衡检测和合并 return { 'det_db_box_thresh': 0.4, 'det_db_unclip_ratio': 1.6, 'enable_merge_det_boxes': True, 'drop_score': 0.3, } ``` **优点**: - ✅ 针对不同场景优化 - ✅ 兼顾准确率和召回率 **缺点**: - ⚠️ 实现复杂度较高 - ⚠️ 需要场景判断逻辑 ### 方案4:集成文本行方向识别(长期改进) 参考 PPStructureV3,添加文本行方向识别模块: 1. 在 OCR 识别前,先进行文本行方向识别 2. 根据识别结果旋转文本行 3. 再进行 OCR 识别 **优点**: - ✅ 显著提高倾斜文本识别准确率 - ✅ 与 PPStructureV3 能力对齐 **缺点**: - ⚠️ 需要额外的模型和计算资源 - ⚠️ 实现复杂度高 ## 🎯 推荐实施步骤 ### 阶段1:快速改进(立即实施) 1. **调整检测参数**: - `det_db_box_thresh`: 0.3 → **0.6** - `det_db_unclip_ratio`: 1.8 → **1.5** - `enable_merge_det_boxes`: True → **False**(表格场景) 2. **降低识别阈值**: - `drop_score`: 0.5 → **0.3** ### 阶段2:场景优化(短期) 3. **实现动态参数调整**: - 根据文档类型和PDF类型选择参数 - 表格场景:严格检测,不合并 - 文本场景:平衡检测和合并 ### 阶段3:能力增强(长期) 4. **集成文本行方向识别**: - 添加文本行方向识别模块 - 提高倾斜文本识别准确率 ## 📝 配置建议 ### 表格场景(当前问题场景) ```yaml ocr: det_db_box_thresh: 0.6 # 提高检测阈值 det_db_unclip_ratio: 1.5 # 降低扩展比例 enable_merge_det_boxes: false # 不合并框 drop_score: 0.3 # 降低识别阈值 ``` ### 文本场景 ```yaml ocr: det_db_box_thresh: 0.4 # 中等检测阈值 det_db_unclip_ratio: 1.6 # 中等扩展比例 enable_merge_det_boxes: true # 允许合并 drop_score: 0.3 # 降低识别阈值 ``` ## 🔧 代码修改位置 1. **`models/adapters/mineru_adapter.py`**: - `MinerUOCRRecognizer.__init__()` - 修改初始化参数 - 添加场景判断逻辑 2. **`core/pipeline_manager_v2.py`**: - `_process_single_page()` - 检测是否有表格 - 传递场景信息给 OCR 识别器 3. **配置文件**: - 添加 OCR 参数配置选项 ## 📈 预期效果 实施阶段1改进后: - ✅ 检测准确率提升:减少噪声框和错误合并 - ✅ 识别完整度提升:保留更多低置信度但正确的结果 - ✅ 表格识别准确率:预计从 60-70% 提升到 85-90% ## ⚠️ 注意事项 1. **参数调优**: - 不同文档可能需要不同的参数 - 建议通过测试集验证最优参数 2. **性能影响**: - 提高 `box_thresh` 可能略微降低召回率 - 需要平衡准确率和召回率 3. **向后兼容**: - 保持默认参数不变,通过配置覆盖 - 确保现有功能不受影响