# OCR技術分享 - 以Google Vision 為例
## 簡介及費用
### 目前常見OCR方案比較
| OCR 服務 | 技術特點 | 中文支持 | 成本 | 適用場景 |
|--------------------|-----------------------------------------------------------------------|-----------------|-------------------------|-----------------------------------|
| **Google OCR (Cloud Vision API)** | 多語言支持(100+),包括繁簡體中文,具高精準度;支援印刷體、手寫文字識別,並可結合 NLP 進行進階分析 | 支持良好 | 前 1,000 次免費,之後每 1,000 次約 $1.50 | 電子商務、教育、醫療等高精度文件處理 |
| **百度 OCR** | 對中文識別進行優化,特別是繁簡體中文印刷體,支援手寫識別;結合行業字典,如財務票據、身份證等高精度識別 | 中文識別出色 | 免費試用 500 次,標準版每 1,000 次約 ¥0.8;專業版每 1,000 次約 ¥1.5 | 適合中文場景應用,如財務發票、身份識別、合同管理 |
| **Tesseract OCR (地端)[演示]** | 免費開源,支援多語言(可通過語言訓練增強中文),適合印刷體;不支持雲端,需要開發者自行配置 | 支持基本,精度一般 | 免費開源,但配置及後續維護成本 | 開源社群使用、個人項目、本地開發測試 |
---
### 為什麼選擇Google?
- 依上述的比較表評估- [Try It](https://cloud.google.com/vision/docs/drag-and-drop?hl=zh-tw)
### Google OCR申請方式及費用
- [如何申請並取得API KEY](https://cloud.google.com/vision/docs/ocr?hl=zh-tw)
- 代碼示例
```C#=
public async Task<BatchAnnotateImagesResponse> ProcessImageAsync(string imageFilePath)
{
LogInfo<object> logInfo = new LogInfo<object>("IMEIRecognitionService.ProcessImageAsync");
Random random = new Random();
string apiKey = GOOGLE_KEYS[random.Next(0, 2)];
string uri = $"{GOOGLE_API_URL}?key={apiKey}";
byte[] imageBytes = File.ReadAllBytes(imageFilePath);
string base64Image = Convert.ToBase64String(imageBytes);
string jsonRequest = $"{{\"requests\": [{{\"image\": {{\"content\": \"{base64Image}\"}}, \"features\": [{{\"type\": \"TEXT_DETECTION\"}}]}}]}}";
var client = new RestClient(uri);
var request = new RestRequest(Method.POST);
request.AddJsonBody(jsonRequest);
try
{
var response = await client.ExecuteAsync(request);
logInfo.Data = response;
if (response.IsSuccessful)
{
var datePath = DateTime.Now.ToString("yyyyMMdd");
var directoryPath = Path.Combine(Common.FILE_UPLOAD_PATH, datePath);
string responseContent = response.Content;
string jsonFilePath = Path.Combine(directoryPath, $"{Path.GetFileNameWithoutExtension(imageFilePath)}.json");
File.WriteAllText(jsonFilePath, responseContent);
LogRepository.Instance.Trace(responseContent, LogType.INFO);
return JsonConvert.DeserializeObject<BatchAnnotateImagesResponse>(responseContent);
}
else
{
LogRepository.Instance.Trace(logInfo, LogType.WARM);
}
}
catch (Exception ex)
{
logInfo.Data = ex;
LogRepository.Instance.Trace(logInfo, LogType.ERROR);
}
return null;
}
```
## Google OCR使用方式及技巧
## 了解Google OCR回傳JSON檔的資訊結構
Google OCR 回傳的 JSON 檔中包含了豐富的資訊,涵蓋了文字內容、文字的位置信息、語言識別等。以下是 JSON 中一些常見的欄位及其描述:
### 1. `textAnnotations` *
- **內容**:包含每個檢測到的文字段(包括單詞或整句文字)。
- **主要欄位**:
- **description**:識別到的文字內容。
- **boundingPoly**:文字的邊界框座標,用於定位文字在圖像中的位置。包含四個點的坐標(左上、右上、右下、左下),可表示文字區域的矩形範圍。
- **locale**:文字的語言代碼(如 "en" 表示英文,"zh" 表示中文),如果能夠識別語言則會顯示。
### 2. `fullTextAnnotation` *
- **內容**:包含整個圖像的全文內容,特別適用於多行或多段文字的文件。
- **主要欄位**:
- **text**:整幅圖像的完整文本內容。
- **pages**:如果文檔包含多頁,這裡會包含多頁內容,進一步細分為段落、詞彙和符號。
- **blocks, paragraphs, words, symbols**:提供更細緻的文檔結構。`blocks` 表示文字塊,`paragraphs` 表示段落,`words` 表示詞彙,`symbols` 表示單個字符。每個級別都包含 `boundingBox` 和 `text` 信息。
### 3. `boundingPoly`
- **內容**:每段文字或單詞的四個邊框點座標(x, y),通常位於 `textAnnotations` 和 `fullTextAnnotation` 的子欄位中。
- **用途**:用於確定文字在圖像上的精確位置,方便進一步處理,如高亮顯示文字或文本定位。
### 4. `confidence`
- **內容**:OCR 識別準確度的分數(0.0 到 1.0 之間),數字越高表示識別的準確性越高。
- **用途**:用來評估文字識別的可靠性,通常在 `fullTextAnnotation` 的細分結構中(如段落、詞彙等級別)包含此欄位。
### 5. `locale`(語言代碼)
- **內容**:識別出的文字的語言代碼(例如,"en" 代表英文,"zh" 代表中文)。
- **用途**:方便處理多語言文件,可以根據語言代碼進行分類或翻譯處理。
### 6. `breakType`(換行標記)
- **內容**:標記行結束、段落結束或其他分隔符,通常在 `fullTextAnnotation` 的 `words` 或 `symbols` 級別中。
- **用途**:適合處理段落分隔或分行的需求,如在多段文字識別中重建段落結構。
### 7. `property`
- **內容**:存儲附加屬性信息,例如檢測到的語言、符號屬性等。
- **主要欄位**:
- **detectedLanguages**:如果一段文字包含多語言,這裡會列出檢測到的語言代碼。
- **detectedBreak**:指示當前文字或符號後是否有分隔符(如空格、換行符等)。
---
### JSON 結構範例
以下是一個簡單的 JSON 結構範例,展示上述欄位在 Google OCR 回傳結果中的位置:
```json
{
"textAnnotations": [
{
"description": "Hello, World!",
"boundingPoly": {
"vertices": [
{"x": 10, "y": 20},
{"x": 100, "y": 20},
{"x": 100, "y": 60},
{"x": 10, "y": 60}
]
},
"locale": "en"
}
],
"fullTextAnnotation": {
"text": "Hello, World!",
"pages": [
{
"blocks": [
{
"paragraphs": [
{
"words": [
{
"symbols": [
{
"text": "H",
"confidence": 0.98,
"property": {
"detectedLanguages": [{"languageCode": "en"}]
}
}
// 其他字符信息...
]
}
]
}
]
}
]
}
]
}
}
```
## 擷取OCR本文的一些技巧
- 使用正規表示式進行篩選
- 自建訓練(例如直接抓取統編的公司名稱或銀行代碼的銀行名稱)
- 增加交互比對提高辨識的可信度
- 暴力辨識與模糊比對
## 未來擴展的一些方向
### 與NLP結合進行自動化內容分類與標籤
- 如自動識別身份證、財力證明等文件,並為檔案進行分類、標簽
### 實體識別與關聯分析
- 在處理身份證明、合同或票據等文件時,OCR 可以提取文本,而 NLP 則可進一步識別人名、地名、日期等關鍵實體,並進行關聯分析。例如,在合同中識別公司名稱、簽署人及日期,可以進行匹配和驗證,甚至與其他數據庫交叉比對,以驗證信息的準確性。