← 專案

專案筆記

收據 OCR API

PaddleOCR · YOLOv7 · 醫院收據結構化 · 端對端正規化

於 GitHub 檢視 →

收據 OCR API 專案 Bloss0m Note 000

ENGINEERING CASE STUDY · DOCUMENT INTELLIGENCE

工程案例

將不同醫院、不同版型與不同掃描品質的收據,轉換成下游系統可直接使用的統一 JSON。

01

問題與限制

問題

醫療收據的版面、欄位名稱、表格結構與影像品質差異很大。單純 OCR 雖能讀出文字,卻無法保證欄位語意、金額關係與 API 格式一致。

限制

  • 輸入可能是掃描檔或手機照片,包含歪斜、陰影、透視與低對比。
  • 不同醫院採用不同欄位名稱、表格位置與費用分類。
  • OCR 結果必須保留住院日期、健保別、金額與明細的正確關係。
  • 新增醫院時不能重新改寫整條管線,需具備可插拔正規化規則。
02

架構與技術決策

系統流程

  1. 01 影像輸入 掃描收據 · 手機照片
  2. 02 影像校正 UVDoc · deskew · shadow removal · OpenCV
  3. 03 版面偵測 YOLOv7 Stage 1 · 區域裁切
  4. 04 文字與表格辨識 PaddleOCR · YOLOv7 Stage 2
  5. 05 醫院正規化 HospitalPipeline · regex config · field mapping
  6. 06 結構化輸出 統一 schema · API-ready JSON

技術選型

YOLOv7 + PaddleOCR

先找出版面與表格區域再辨識文字,避免整張收據直接 OCR 造成欄位順序混亂。

UVDoc + OpenCV

把透視、歪斜與陰影視為辨識前的工程問題,降低模型需要承擔的變異。

HospitalPipeline

將各醫院差異隔離在設定、regex 與 mapping,核心管線維持一致。

固定 JSON contract

以 API 消費者需要的欄位反推辨識流程,而不是把 OCR 原始文字當成完成品。

03

我的具體責任

  1. 01

    設計從影像校正、區域偵測、OCR 到 JSON 的端對端管線。

  2. 02

    實作醫院版型判斷、欄位與表格偵測、正規表示式與欄位 mapping。

  3. 03

    建立 HospitalPipeline 擴充介面,讓新醫院規則與核心辨識邏輯分離。

  4. 04

    定義下游 API schema,並以真實收據逐欄驗證輸出。

04

評測方式與成果

使用多家醫院真實版型進行端對端驗收,不只檢查字元辨識,而是逐一核對健保別、日期、醫院、科別、總額與費用明細是否能穩定映射到統一 schema。

5+
醫院格式 各自具備版型與欄位規則
6
處理階段 從影像輸入到 JSON contract
1
統一輸出格式 供下游 API 直接使用
05

失敗與修正

01
失敗現象
直接對整張收據 OCR,文字雖可讀但欄位順序和表格關係不穩定。
修正方式
加入兩階段 YOLO 區域偵測,先切出版面區塊與明細表再辨識。
工程教訓
文件理解不能只看字元準確率,版面關係同樣是資料。
02
失敗現象
共用一套 regex 時,新醫院格式常破壞舊有解析。
修正方式
把醫院差異拆成獨立設定、mapping 與 HospitalPipeline adapter。
工程教訓
變動最快的規則必須被隔離,而不是散落在核心流程。
03
失敗現象
OCR 原始輸出無法直接被財務或理賠系統採用。
修正方式
先定義穩定 JSON contract,再回頭設計正規化與驗收欄位。
工程教訓
工程成果應以系統整合是否可用衡量,而不只是模型能否辨識文字。
06

證據與延伸資料

Deep dive · 深入實作

技術實作細節

接續案例摘要,深入查看工作流、實作決策、架構圖與專案產出。

Context(情境)

醫療收據需與財務、理賠或內部系統串接,但各醫院版型與欄位格式不一,人工鍵入耗時且易錯。情境需要從掃描件或照片產出統一、機器可讀的結構化資料,供下游 API 直接使用。

Challenge(痛點)

  • 台灣各大醫院收據版型與欄位位置差異大,單一規則無法涵蓋。
  • 掃描品質(歪斜、陰影、低解析度)影響 OCR 辨識率。
  • 部分收據含表格(費用明細),需區塊偵測後再解析欄位。

Solution(架構+做法)

本專案做端對端收據正規化:不論掃描品質或醫院版型差異,都能輸出統一的結構化 JSON。做法是依「是否含表格」自動切換兩階段 YOLO 偵測與醫院專屬欄位解析,並搭配 UVDoc 展平、歪斜/陰影校正與 PaddleOCR,降低影像品質造成的誤差。

  • 支援台大、長庚、彰基、榮總、奇美等 5 所以上常見醫院,以客製化正則與欄位抽取程式辨識。
  • 輸出欄位含 nhiadmissionDatedischargeDatereceivedAmountitems(費用明細)等,可對接既有 API。

處理管線

  1. 影像前處理 — 判斷正反向、UVDoc 展平、陰影與噪聲抑制(ocr_methods.pycorrect_skew_eliminate_shadows.pyUVDoc/)。
  2. YOLO Stage 1 — 偵測收據區域(yolov7_detect.py)。
  3. 切割與再校正 — 必要時以 crop_image_from_label.py 再切出區塊。
  4. OCR — PaddleOCR(det + rec)取得全文,依 hospital_key.txt 判斷醫院類別。
  5. 表格偵測 — 若有表格則啟用 YOLO Stage 2 偵測表格區塊。
  6. 醫院管線 — 進入對應 HospitalPipelinehospital_pipeline.py),依醫院做欄位正則化與表格補強(receipt_uni/info/*.pyreceipt_uni/config/regex_*.txt)。
  7. 輸出convert_df_to_api_format.py 轉成標準 JSON,由 generate_json_result 輸出。

新增醫院時沿用同一邏輯:判斷是否含表格 → 撰寫欄位 regex 與自訂抽取程式即可。

管線與輸出範例

處理管線 — 從影像輸入到 JSON 輸出的流程。

OCR 處理管線

以下為各院收據辨識後的輸出格式範例(以檔名為 key,欄位含健保、住院/出院日、科別、收據金額與 items 明細)。

台大

台大收據辨識範例

"台大收據1.jpg" : {
    'nhi': 'Y',
    'admissionDate': '2023/07/19',
    'dischargeDate': '2023/07/23',
    'hospitalName': '國立臺灣大學醫學院附設醫院',
    'dept': '骨科部',
    'receivedAmount': '84327',
    'items': {
        '藥費': '251',
        '治療處置費': '520',
        '材料費': '69006',
        '證明書費': '150',
        '病房費': '14400'
    }
},

長庚

長庚收據辨識範例

"長庚收據1.jpg" : {
    'nhi': 'Y',
    'admissionDate': '2023/07/28',
    'dischargeDate': '2023/07/28',
    'hospitalName': '林口長庚紀念醫院',
    'dept': '一般外科系',
    'receivedAmount': '20610',
    'items': {
        '住院部分負擔': '4651',
        '藥品費': '553',
        '材料費': '5520',
        '處置費': '9886'
    }
},

彰基

彰基收據辨識範例

"彰基收據1.jpg" : {
    'nhi': 'Y',
    'admissionDate': '2023/07/21',
    'dischargeDate': '2023/07/27',
    'hospitalName': '彰化基督教醫療財團法人彰化基督教醫院',
    'dept': '耳鼻喉暨頭頸部',
    'receivedAmount': '49430',
    'items': {
        '藥費': '1349',
        '材料費': '41919',
        '治療處置費': '650',
        '部分負擔': '5512'
    }
},

技術棧

  • OCR — PaddleOCR(det / rec),繁體中文權重(如 ch_PP-OCRv4_dettw_PP-OCRv3_rec)。
  • 偵測 — YOLOv7(Stage 1 收據區域、Stage 2 表格區塊)。
  • 影像前處理 — UVDoc 展平、deskew、陰影消除;OpenCV、scikit-image。
  • 環境 — Python 3.9+;可選 CUDA GPU 加速。

依賴:paddleocrpaddlepaddle-gputorchtorchvisionopencv-python-headlessnumpypandasPillowscikit-imagePyYAML 等。

擴充新醫院

  • hospital_pipeline.py 定義 HospitalPipeline 抽象類別與各院實作(NTU、長庚、彰基、榮總、奇美等)。
  • receipt_uni/info/*.py 為醫院專屬欄位邏輯;receipt_uni/config/regex_*.txt 為欄位與 regex 對照。

建議步驟

  1. hospital_key.txt 加入醫院關鍵字與 key。
  2. info/ 新增解析程式與 regex_<HOSP>.txt(必要時 regex_<HOSP>_table.txt)。
  3. hospital_pipeline.py 實作新 class(get_ocr_resultcrop_from_labeltext_infotable_info 等)。
  4. 視需要調整 hospital_api_map.txt

Impact(量化成效)

  • 支援醫院數:5 所以上(台大、長庚、彰基、榮總、奇美等),單一管線輸出統一 JSON。
  • 輸出格式nhiadmissionDatedischargeDatereceivedAmountitems(費用明細)等欄位,可對接既有財務/醫療 API,下游無須再處理各院版型差異。
  • 擴充成本:新增一院僅需撰寫欄位 regex 與抽取邏輯,沿用同一管線即可維持單一 API 格式。

Extension(可延伸方向)

  • 擴充至更多醫院與收據類型(門診、診所、長照單據)。
  • 串接理賠或請款流程,從掃描到審核一鍵完成。
  • 加入準確率監控與人工抽檢介面,持續優化辨識與欄位對應。

歡迎演講、企業內部技術分享與架構交流;可以先查看我適合分享的主題與公開工程成果。

演講與聯絡