2024年5月29日 星期三

tesseract 之數字表格圖片轉試算表 (最簡單的 OCR 應用)

雜食小股東的股利收入 老婆:「快點啦! 報稅軟體都幫你下載好了,快來算啦!」 好吧, 就用她的 windows 電腦一路 「下一步」 快速通關。 謝謝財政部。 可是身為很多家公司的小股東的她, 還想要把所有股利收入逐筆放入試算表。 問題是: 下載的 pdf 是圖檔, 讀不出文字! 幹嘛啊, 這又沒有保護作用, 只是增加納稅人的麻煩而已, 真沒意思。 沒關係, 那就把 pdf 檔搬到我的電腦, 用 OCR (optical character recognition) 工具來讀吧。

  1. Linux 下的 OCR 軟體是 tesseract。 另外, 每種語言也要安裝各自的套件。 我們安裝正體中文套件: apt install tesseract-ocr-chi-tra 系統會自動把基本的 tesseract 套件一起裝進來。
  2. 假設你的 pdf 檔叫做 tax24.pdf。 先拆成一張張的圖片 x-01.ppm、 x-02.ppm、 ...: pdftoppm tax24.pdf x
  3. [可省略] 把每張 ppm 轉成 png: for f in x-*.ppm ; do convert $f ${f%.ppm}.png ; done
  4. 可以先拿上圖測試: tesseract tax.png tax -l eng+chi_tra 這會產生一個文字檔 tax.txt。 辨識效果不是很好。 沒關係, 等一下再來處理。
  5. 用 tesseract 處理每張 ppm 或 png: for f in x-*.ppm ; do tesseract $f ${f%.ppm} -l eng+chi_tra ; done 產生 x-01.txt、 x-02.txt、 ... 等等一堆文字檔。

看起來它對中文的專有名詞 (人名、 公司名稱) 辨識效果不太好。 沒關係, 如果我們只抓數字欄位, 正確率應該就會比較高了吧? 以下先抓出統編跟下一欄 「給付/收入總額」, 再把「金額」裡面的逗號都刪掉, 最後再用逗號取代空格作為欄位分隔字元。 perl -ne 'print("$1 $2\n") if /\b(\d{8})\s+([\d,]+)/' tax.txt | perl -pe 's/,//g; s/\s+/,/' > tax.csv

把這個 csv 檔匯入 google 試算表、 把統編欄位轉成文字 (選取該欄、 在 「格式」=>「數值」 選單底下點選 「純文字」) 就大致成形了。

匯入 info.csv 時的選項 再下載 stock-info.csv 改名為 info.csv。 這是我從 公開資訊觀測站 整理而成的: 用 「上市」、「上櫃」分兩次下載回來、 合併、 把 big5 編碼轉成 utf8、 把 「統編」 欄位前面多餘的空格刪掉、 把「統編」欄位移到最左側, 方便等一下用 vlookup() 查詢。 把這張參考表再匯入先前的試算表, 成為其中一張新的工作表 (分頁), 但不要把文字轉成數字。

再回到 tax.csv 那一張工作表。 在左側加上兩欄、 在最上面加上欄位名稱, 欄位 ABCD 分別是: 股票代號、股票名稱、統一編號、利息收入。 隨便挑一列, 假設是第12列。 在 A12 輸入: =iferror(vlookup($C12,info!$A$1:$D$3000,2,false),"") 也就是用統編到另一張表查詢出股票代號。 B12 輸入類似的公式, 2 改成 4, 查詢公司簡稱。 如果正確, 把這兩格複製到其他列, 就可以看到雜食小股東去年的所有股利收入細項啦! 還要跟原始的 pdf 用人眼核對一下。 我的狀況, 有幾筆遺漏數字甚至遺漏一整列; 不過大部分 ok, 至少省了一些手工。

做完以後才發現財政部根本就有提供網頁版, 可以直接剪貼 html 表格。 那我過去幾年都在幹嘛?

哦,對了, 我現在在寫教學文。 那就順便提一下使用 tesseract 之前需要的前置處理。 螢幕截圖通常比較簡單, 尤其此例是 pdf 文件檔, 不需要前置處理。 如果是含有彩色或是對比不太清楚的黑白螢幕截圖, 可以先用 imagemagick 套件的 convert 指令, 把圖片轉成黑白兩色: convert screen-shot.png +dither -colors 2 -colorspace gray -contrast-stretch 0 black-white.png 這是我搜尋到的最簡單的轉換, 從 這裡 看來的。 如果是掃描或相片, 那就比較複雜了, 先筆記 imagemagick 官網的教學, 以後有遇到再研究。

沒有留言:

張貼留言

因為垃圾留言太多,現在改為審核後才發佈,請耐心等候一兩天。