# 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` 方法中: ```python # 當前代碼 (第604-613行) elif element_type in [ElementType.IMAGE, ElementType.FIGURE]: content = {'path': elem_data.get('img_path', ''), ...} else: content = elem_data.get('content', '') # ← CHART 類型走這裡! ``` **問題**: 1. `CHART` 類型未被視為視覺元素 2. `saved_path` 完全丟失 3. `content` 變成文字而非圖片路徑 --- ## 改善計劃 ### 階段 1: Direct Track 使用 PyMuPDF find_tables (優先級:最高) **問題**: `_detect_tables_by_position` 無法識別合併單元格 **方案**: 改用 PyMuPDF 的 `find_tables()` API **檔案**: `backend/app/services/direct_extraction_engine.py` ```python 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行 **修改**: ```python # 修改前 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: 過濾極小裝飾圖片 (優先級:高) ```python 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 | --- ## 測試計劃 1. **edit.pdf Direct Track**: 確保無回歸 2. **edit3.pdf Direct Track**: - 驗證表格識別到 83 cells(非 204) - 驗證跨欄/跨行正確 - 驗證極小圖片被過濾 - 驗證黑框被過濾 3. **edit.pdf OCR Track**: - **驗證 pp3_1_8.png 正確放回** - 驗證 cell_boxes 座標修復 4. **edit3.pdf OCR Track**: - **驗證 pp3_1_2.png 正確放回** - 驗證 cell_boxes 座標修復