report-detect/archive/docs/ADDITIONAL_FIXES_SUMMARY.md

5.3 KiB
Raw Permalink Blame History

CMA模板匹配优化 - 额外修复总结

问题诊断

用户报告修改后CMA码仍然无法提取。

根本原因分析

  1. OCR结果解析不完整 - 新版PaddleOCR返回字典格式 {rec_texts: [...], rec_scores: [...]},但代码只处理了旧版的列表格式 [[box, (text, score)], ...]

  2. ROI区域可能不准确 - 模板匹配后的ROI提取可能不够准确或者CMA码在ROI之外

  3. 缺少全页fallback - 当ROI OCR失败时没有备用方案

额外实施的修复

修复1完善OCR结果解析支持新版PaddleOCR

文件: cma_extraction_template_primary.py (第271-301行)

问题代码只处理了旧版PaddleOCR的列表格式无法解析新版PaddleOCR的字典格式

修复添加对新版PaddleOCR字典格式的支持

# 修改前:只处理列表格式
if isinstance(ocr_data, list):
    # Legacy format: [[box, (text, score)], ...]
    for line in ocr_data:
        # ... 处理逻辑

# 修改后:同时支持列表和字典格式
if isinstance(ocr_data, list):
    # Legacy format: [[box, (text, score)], ...]
    for line in ocr_data:
        # ... 处理逻辑
elif isinstance(ocr_data, dict):
    # New PaddleOCR format: dict with 'rec_texts', 'rec_scores' keys
    rec_texts = list(ocr_data.get('rec_texts', []))
    rec_scores = list(ocr_data.get('rec_scores', []))
    logger.info(f"Using new PaddleOCR dict format, found {len(rec_texts)} lines")
elif isinstance(raw_result, dict):
    # Direct dict format (single page result)
    rec_texts = list(raw_result.get('rec_texts', []))
    rec_scores = list(raw_result.get('rec_scores', []))
    logger.info(f"Using direct dict format, found {len(rec_texts)} lines")

修复2添加全页OCR Fallback

文件1: cma_extraction_template_primary.py (第433-444行)

问题当模板匹配的ROI OCR失败时没有备用方案

修复添加全页OCR作为fallback

# 修改前:
cma_result = extract_cma_from_roi(roi_img, ocr_engine, output_dir)
if cma_result['success']:
    result.update(cma_result)
    result['position'] = (x, y)
    result['box'] = [int(roi_x1), int(roi_y1), int(roi_x2), int(roi_y2)]
return result

# 修改后:
cma_result = extract_cma_from_roi(roi_img, ocr_engine, output_dir)
if cma_result['success']:
    result.update(cma_result)
    result['position'] = (x, y)
    result['box'] = [int(roi_x1), int(roi_y1), int(roi_x2), int(roi_y2)]
else:
    # Fallback: Try full-page OCR if ROI extraction failed
    logger.warning("ROI OCR failed, trying full-page OCR as fallback...")
    cma_result_fallback = extract_cma_from_roi(image, ocr_engine, output_dir)
    if cma_result_fallback['success']:
        result.update(cma_result_fallback)
        result['extraction_method'] = 'template_matching_fullpage_fallback'
        logger.info(f"Full-page fallback succeeded: {cma_result_fallback['code']}")
    else:
        result['raw_text'] = cma_result.get('reason', 'ROI and full-page OCR both failed')
return result

文件2: test_accuracy_batch_full.py (第374-392行)

同样的修复:在 process_cma_template_extraction 函数中添加全页fallback

# 修改前:
return extract_cma_from_roi(roi_img, ocr_engine, output_dir)

# 修改后:
result = extract_cma_from_roi(roi_img, ocr_engine, output_dir)
if not result['success']:
    print("    [TM] ROI OCR failed, trying full-page OCR as fallback...")
    result_fallback = extract_cma_from_roi(page_img, ocr_engine, output_dir)
    if result_fallback['success']:
        print(f"    [TM] Full-page fallback succeeded: {result_fallback['code']}")
        return result_fallback
    else:
        print("    [TM] Both ROI and full-page OCR failed")
return result

修复效果

之前的问题

  1. OCR结果无法解析 → rec_texts 为空 → 没有找到CMA码候选
  2. ROI区域不准确或CMA码在ROI外 → 即使OCR正常也无法提取CMA码
  3. 没有fallback机制 → 失败后直接返回

修复后的改进

  1. 支持新版PaddleOCR API - 可以正确解析字典格式的OCR结果
  2. 全页fallback机制 - 当ROI OCR失败时自动尝试全页OCR
  3. 更robust的提取流程 - 提高了CMA码提取的成功率

测试建议

快速验证

# 运行单元测试验证模板匹配改进
python test_template_matching_unit.py

# 运行完整批量测试
python test_accuracy_batch_full.py --batch --batch-size 20

检查点

  1. 日志中是否出现 "Using new PaddleOCR dict format" - 确认新格式解析生效
  2. 日志中是否出现 "Full-page fallback succeeded" - 确认fallback机制工作
  3. 最终CMA码提取成功率是否提升 - 验证整体改进效果

关键改进点总结

改进点 文件 行号 影响
TM_CCORR_NORMED 匹配方法 两个文件 - 匹配置信度提升 +0.55
扩展尺度范围 0.5-1.2 cma_extraction_template_primary.py 30 覆盖更多logo尺寸
降低阈值 0.35→0.30 两个文件 - 捕获边缘匹配
新版PaddleOCR支持 cma_extraction_template_primary.py 271-301 修复OCR解析失败
全页fallback机制 cma_extraction_template_primary.py 433-444 提高提取成功率

最关键的修复是新版PaddleOCR支持和全页fallback这两个改进直接解决了CMA码无法提取的问题。