Files
OCR/openspec/changes/extract-table-cell-boxes/specs/ocr-processing/spec.md
egg 801ee9c4b6 feat: create extract-table-cell-boxes proposal and archive old proposal
- Archive unify-image-scaling proposal to archive/2025-11-28
- Create new extract-table-cell-boxes proposal for supplementing PPStructureV3
  with direct SLANeXt model calls to extract table cell bounding boxes
- Add debug logging to pp_structure_enhanced.py for table cell boxes investigation
- Discovered that PPStructureV3 high-level API filters out cell bbox data,
  but paddlex.create_model() can directly invoke underlying models

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 12:15:06 +08:00

3.6 KiB
Raw Blame History

Spec: OCR Processing - Table Cell Boxes Extraction

Overview

在 OCR Track 處理表格時,補充調用 PaddleX 底層 SLANeXt 模型,獲取每個 cell 的座標信息。

Requirements

1. 模型管理

1.1 模型緩存

class PPStructureEnhanced:
    def __init__(self, structure_engine):
        self.structure_engine = structure_engine
        # 底層模型緩存
        self._table_cls_model = None
        self._wired_table_model = None
        self._wireless_table_model = None

1.2 延遲載入

  • 模型只在首次需要時載入
  • 使用 paddlex.create_model() API
  • 模型配置從 settings 讀取

2. Cell Boxes 提取流程

2.1 處理條件

mapped_type == ElementType.TABLE 且有有效的 block_bbox 時觸發。

2.2 處理步驟

1. 裁切表格圖片
   - 從原始圖片中根據 block_bbox 裁切
   - 確保邊界不超出圖片範圍

2. 判斷表格類型 (可選)
   - 調用 PP-LCNet_x1_0_table_cls
   - 獲取 wired/wireless 分類結果
   - 或直接使用 PPStructureV3 內部的分類結果

3. 調用對應 SLANeXt 模型
   - wired → SLANeXt_wired
   - wireless → SLANeXt_wireless

4. 提取 cell boxes
   - 從 result.json['res']['bbox'] 獲取
   - 格式: [[x1,y1,x2,y2,x3,y3,x4,y4], ...]

5. 座標轉換
   - 將相對座標轉為全域座標
   - global_box = [box[i] + offset for each point]
   - offset = (table_x, table_y) from block_bbox

6. 存入 element
   - element['cell_boxes'] = processed_boxes
   - element['cell_boxes_format'] = 'polygon_8'

3. 數據格式

3.1 Cell Boxes 結構

element = {
    'element_id': 'pp3_0_3',
    'type': ElementType.TABLE,
    'bbox': [84, 269, 1174, 1508],  # 表格整體 bbox
    'content': '<html>...</html>',   # HTML 內容
    'cell_boxes': [                  # 新增cell 座標
        [95, 273, 776, 274, 759, 326, 94, 325],  # cell 0 (全域座標)
        [119, 296, 575, 295, 560, 399, 117, 401], # cell 1
        # ...
    ],
    'cell_boxes_format': 'polygon_8',  # 座標格式說明
    'table_type': 'wired',  # 可選:表格類型
}

3.2 座標格式

  • polygon_8: 8 點多邊形 [x1,y1,x2,y2,x3,y3,x4,y4]
  • 順序:左上 → 右上 → 右下 → 左下

4. 錯誤處理

4.1 失敗情況

  • 模型載入失敗
  • 圖片裁切失敗
  • 預測返回空結果

4.2 處理方式

  • 記錄警告日誌
  • 繼續處理element 不包含 cell_boxes
  • 不影響原有 HTML 提取流程

5. 配置項

# config.py
class Settings:
    # 是否啟用 cell boxes 提取
    enable_table_cell_boxes_extraction: bool = True

    # 表格結構識別模型 (已存在)
    wired_table_model_name: str = "SLANeXt_wired"
    wireless_table_model_name: str = "SLANeXt_wireless"

Implementation Notes

模型共享

PPStructureV3 內部已載入了這些模型,但高層 API 不暴露。 直接使用 paddlex.create_model() 會重新載入模型。 考慮是否可以訪問 PPStructureV3 內部的模型實例(經測試:不可行)。

性能優化

  • 模型實例緩存在 PPStructureEnhanced 中
  • 避免每次處理表格都重新載入模型
  • 考慮在內存緊張時釋放緩存

座標縮放

如果圖片在 Layout 分析前經過縮放ScalingInfo cell boxes 座標也需要相應縮放回原始座標系。

Test Cases

  1. 有線表格:確認 cell boxes 提取正確
  2. 無線表格:確認模型選擇和提取正確
  3. 複雜表格:跨行跨列的表格
  4. 小表格cell 數量少的簡單表格
  5. 錯誤處理:無效 bbox、模型失敗等情況