5.6 KiB
5.6 KiB
PDF 處理雙軌制改善計劃 (修訂版 v5)
問題分析
一、Direct Track 表格問題
| 指標 | edit.pdf | edit3.pdf |
|---|---|---|
| 原始表格結構 | 6 rows x 2 cols | 12 rows x 17 cols |
| PyMuPDF 識別的 cells | 12 (無合併) | 83 (有121個合併) |
| Direct Track 提取的 cells | 12 | 204 (全部視為1x1) |
| 跨欄/跨行識別 | 不需要 | ❌ 完全未識別 |
| 渲染結果 | ✓ 完美 | ❌ 欄位切分錯誤、文字超出 |
根因: _detect_tables_by_position() 無法識別合併單元格
二、Direct Track 圖片問題 (edit3.pdf)
| 問題 | 數量 | 說明 |
|---|---|---|
| 極小裝飾圖片 | 3 | < 200 px²,應過濾 |
| 覆蓋圖像 (黑框) | 6 | 已檢測但未從渲染中移除 |
| 大型 vector_graphics | 3 | ✓ 已正確過濾 |
三、OCR Track 表格問題
| 表格 | cells | cell_boxes | cell_boxes 坐標檢查 |
|---|---|---|---|
| pp3_0_3 | 13 | 13 | ⚠️ 1/5 超出範圍 |
| pp3_0_6 | 29 | 12 | ❌ 全部超出範圍 |
| pp3_0_7 | 12 | 51 | ❌ 全部超出範圍 |
| pp3_0_16 | 51 | 29 | ❌ 全部超出範圍 |
根因: PP-StructureV3 的 cell_boxes 座標系統錯亂
四、OCR Track 圖片問題 ❌ 嚴重
| 文件 | 圖片元素 | PP-Structure 原始數據 | 轉換後 UnifiedDocument | 結果 |
|---|---|---|---|---|
| edit.pdf | pp3_1_8 | saved_path="pp3_1_8.png" ✓ | content=字符串 ❌ | 圖片未放回 |
| edit3.pdf | pp3_1_2 | saved_path="pp3_1_2.png" ✓ | content=字符串 ❌ | 圖片未放回 |
根因: ocr_to_unified_converter.py 的 _convert_pp3_element 方法中:
# 當前代碼 (第604-613行)
elif element_type in [ElementType.IMAGE, ElementType.FIGURE]:
content = {'path': elem_data.get('img_path', ''), ...}
else:
content = elem_data.get('content', '') # ← CHART 類型走這裡!
問題:
CHART類型未被視為視覺元素saved_path完全丟失content變成文字而非圖片路徑
改善計劃
階段 1: Direct Track 使用 PyMuPDF find_tables (優先級:最高)
問題: _detect_tables_by_position 無法識別合併單元格
方案: 改用 PyMuPDF 的 find_tables() API
檔案: backend/app/services/direct_extraction_engine.py
def _extract_tables_with_pymupdf(self, page, page_num, counter):
tables = page.find_tables()
for table in tables.tables:
# 獲取 cells,保留合併信息
cells = []
for row_idx in range(table.row_count):
for col_idx in range(table.col_count):
cell_data = table.cells[row_idx * table.col_count + col_idx]
if cell_data is None:
continue # 跳過被合併的單元格
# 計算 row_span/col_span...
階段 2: 修復 OCR Track 圖片路徑丟失 (優先級:最高)
問題: CHART 類型的 saved_path 在轉換時丟失
檔案: backend/app/services/ocr_to_unified_converter.py
位置: _convert_pp3_element 方法,約第604行
修改:
# 修改前
elif element_type in [ElementType.IMAGE, ElementType.FIGURE]:
# 修改後:包含所有視覺元素類型
elif element_type in [
ElementType.IMAGE, ElementType.FIGURE, ElementType.CHART,
ElementType.DIAGRAM, ElementType.LOGO, ElementType.STAMP
]:
# 優先使用 saved_path
image_path = (
elem_data.get('saved_path') or
elem_data.get('img_path') or
''
)
content = {
'saved_path': image_path, # 關鍵:保留 saved_path
'path': image_path,
'width': elem_data.get('width', 0),
'height': elem_data.get('height', 0),
'format': elem_data.get('format', 'unknown')
}
階段 3: 修復 OCR Track cell_boxes 座標 (優先級:高)
方案: 驗證座標,超出範圍時使用 CV 線檢測 fallback
階段 4: 過濾極小裝飾圖片 (優先級:高)
if elem_area < 200:
continue # 跳過 < 200 px² 的圖片
階段 5: 過濾覆蓋圖像 (優先級:高)
在提取階段過濾與 covering_images 重疊的圖片。
實施優先級
| 階段 | 描述 | 優先級 | 影響 |
|---|---|---|---|
| 1 | Direct Track 使用 PyMuPDF find_tables | 最高 | 修復合併單元格 |
| 2 | OCR Track 圖片路徑修復 | 最高 | 修復圖片未放回 |
| 3 | OCR Track cell_boxes 座標修復 | 高 | 修復表格渲染錯亂 |
| 4 | 過濾極小裝飾圖片 | 高 | 減少無意義圖片 |
| 5 | 過濾覆蓋圖像 | 高 | 減少黑框 |
預期效果
Direct Track
| 指標 | 修改前 | 修改後 |
|---|---|---|
| edit3.pdf cells | 204 (錯誤拆分) | 83 (正確識別合併) |
| 跨欄/跨行識別 | ❌ | ✓ |
OCR Track 圖片
| 指標 | 修改前 | 修改後 |
|---|---|---|
| pp3_1_8 (edit.pdf) | 圖片未放回 | ✓ 正確放回 |
| pp3_1_2 (edit3.pdf) | 圖片未放回 | ✓ 正確放回 |
OCR Track 表格
| 指標 | 修改前 | 修改後 |
|---|---|---|
| cell_boxes 座標 | 3/5 表格錯誤 | 全部正確或 CV fallback |
測試計劃
-
edit.pdf Direct Track: 確保無回歸
-
edit3.pdf Direct Track:
- 驗證表格識別到 83 cells(非 204)
- 驗證跨欄/跨行正確
- 驗證極小圖片被過濾
- 驗證黑框被過濾
-
edit.pdf OCR Track:
- 驗證 pp3_1_8.png 正確放回
- 驗證 cell_boxes 座標修復
-
edit3.pdf OCR Track:
- 驗證 pp3_1_2.png 正確放回
- 驗證 cell_boxes 座標修復