Files
OCR/openspec/changes/archive/2025-12-11-improve-ocr-track-algorithm/proposal.md
egg cfe65158a3 feat: enable document orientation detection for scanned PDFs
- Enable PP-StructureV3's use_doc_orientation_classify feature
- Detect rotation angle from doc_preprocessor_res.angle
- Swap page dimensions (width <-> height) for 90°/270° rotations
- Output PDF now correctly displays landscape-scanned content

Also includes:
- Archive completed openspec proposals
- Add simplify-frontend-ocr-config proposal (pending)
- Code cleanup and frontend simplification

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-11 17:13:46 +08:00

2.1 KiB
Raw Blame History

Change: Improve OCR Track Algorithm Based on PP-StructureV3 Best Practices

Why

目前 OCR Track 的 Gap Filling 演算法使用 IoU (Intersection over Union) 判斷 OCR 文字是否被 Layout 區域覆蓋。根據 PaddleX 官方文件 (paddle_review.md) 建議,應改用 IoA (Intersection over Area) 才能正確判斷「小框是否被大框包含」的非對稱關係。此外,現行使用統一閾值處理所有元素類型,但不同類型應有不同閾值策略。

What Changes

  1. IoU → IoA 演算法變更: 將 gap_filling_service.py 中的覆蓋判定從 IoU 改為 IoA
  2. 動態閾值策略: 依元素類型 (TEXT, TABLE, FIGURE) 使用不同的 IoA 閾值
  3. 使用 PP-StructureV3 內建 OCR: 改用 overall_ocr_res 取代獨立執行 Raw OCR節省推理時間並確保座標一致
  4. 邊界收縮處理: OCR 框內縮 1-2 px 避免邊緣重複渲染

Impact

  • Affected specs: ocr-processing
  • Affected code:
    • backend/app/services/gap_filling_service.py - 核心演算法變更
    • backend/app/services/ocr_service.py - 改用 overall_ocr_res
    • backend/app/services/processing_orchestrator.py - 調整 OCR 資料來源
    • backend/app/core/config.py - 新增元素類型閾值設定

Technical Details

1. IoA vs IoU

IoU = 交集面積 / 聯集面積  (對稱,用於判斷兩框是否指向同物體)
IoA = 交集面積 / OCR框面積 (非對稱,用於判斷小框是否被大框包含)

當 Layout 框遠大於 OCR 框時IoU 會過小導致誤判為「未覆蓋」。

2. 動態閾值建議

元素類型 IoA 閾值 說明
TEXT/TITLE 0.6 容忍邊界誤差
TABLE 0.1 嚴格過濾,避免破壞表格結構
FIGURE 0.8 保留圖中文字 (如軸標籤)

3. overall_ocr_res 驗證結果

已確認 PP-StructureV3 的 json['res']['overall_ocr_res'] 包含:

  • dt_polys: 檢測框座標 (polygon 格式)
  • rec_texts: 識別文字
  • rec_scores: 識別信心度

測試結果顯示與獨立執行 Raw OCR 的結果數量相同 (59 regions),可安全替換。