在將紙本文件或證件影像送入 OCR (光學字元識別) 引擎之前,「二值化 (Binarization)」 —— 也就是將彩色或灰階影像轉換為純黑白(只有 0 與 255 兩種像素值)的過程,是最關鍵的前處理步驟。
二值化的核心概念非常直覺:逐一比對影像中每個像素的灰階數值,若超過某個「門檻值 (Threshold)」就判定為白色背景(255),反之則判定為黑色文字(0)。
對於在均勻光源下掃描的標準紙本申請書,使用一個固定的全局門檻值(例如 127)就能得到極佳的效果。然而,在行動裝置普及的今天,使用者上傳的往往是用手機隨手拍下的證件或收據影像。這類照片常伴隨著局部陰影、反光、光源不均或紙張折痕。如果強行使用固定門檻值,轉換出來的影像經常會出現一大塊漆黑(陰影處全被判定為黑色)或一大塊死白(反光處文字完全消失)的情形,使後續的 OCR 引擎完全失效。
為了在複雜的實際環境中取得理想的二值化結果,本文將深入比較並實作三種主流的影像二值化演算法。
1. 大津二值化 (Otsu’s Binarization)
大津演算法是一種自適應全局門檻值演算法。它不需要手動設定門檻值,而是透過統計影像的灰階直方圖,尋找一個能讓「類間變異量 (Between-Class Variance)」達到最大的最佳門檻值。
簡單來說,大津演算法會假設影像包含兩種類別:背景(通常是較亮的紙張)與前景(通常是較暗的文字)。演算法會自動計算出一個完美的分割線,使得這兩個群體各自的凝聚度最高,彼此的距離最遠。
大津演算法的適用情境與侷限
- 最佳場景:影像直方圖呈現明顯的「雙峰分佈」(代表前景與背景色差分明),例如光照均勻但文字與紙張對比較低的文件掃描檔。
- 致命缺點:當影像中存在強烈的漸層光源或嚴重局部陰影時,直方圖的雙峰特徵會被破壞,此時大津演算法找出來的「單一全局門檻值」依然會失效,導致陰影區全黑。
以下是使用 OpenCV 呼叫大津二值化的 Python 程式碼:
import cv2
def otsu_binarization(image_path, output_path):
# 讀取灰階影像
img = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)
# 執行大津二值化 (將門檻值設為 0,並傳入 cv2.THRESH_OTSU)
# 演算法會自動計算出最佳門檻值,並回傳於 threshold_value 中
threshold_value, binarized_img = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
print(f"[Otsu] 計算出的最佳全局門檻值為: {threshold_value}")
cv2.imwrite(output_path, binarized_img)
# 使用範例
# otsu_binarization("receipt.jpg", "binarized_otsu.png")
2. 自適應均值門檻值 (Adaptive Mean Thresholding)
當全局二值化(不論是固定門檻值還是大津演算法)因局部光影不均而破功時,局部自適應門檻值 (Adaptive Thresholding) 是最佳的解決方案。
自適應均值門檻值的原理是:影像中的每一個像素,其門檻值都是由它周圍鄰近區域(區塊大小為 $N \times N$)的平均灰階值動態決定的。具體計算方式為:
$$\text{Threshold}(x,y) = \text{Mean}(N \times N \text{ Area}) - C$$
其中 $C$ 是一個使用者自訂的常數,用來排除微小雜訊。因為門檻值是隨著空間位置「因地制宜」地動態調整,所以即使某個區塊處於暗部陰影中,只要文字與紙張在該區域仍有相對的明暗差,文字就能被完美提取出來。
自適應門檻值的適用情境
- 最佳場景:手機拍照的文件、存摺掃描、含有反光或不均勻陰影的證件影像。這是 OCR 前處理管線中最實用、最穩健的演算法。
- 缺點:如果設定的區塊大小 $N$ 太小,在沒有文字的純白紙張區塊,演算法會誤將紙張微小的紋路或雜訊判定為文字,進而產生很多細碎的「點狀雜訊」。
以下是 OpenCV 的實作程式碼:
import cv2
def adaptive_mean_binarization(image_path, output_path):
img = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)
# 執行自適應均值二值化
# Block Size 設為 11 (代表 11x11 像素區塊),常數 C 設為 2
binarized_img = cv2.adaptiveThreshold(
img, 255,
cv2.ADAPTIVE_THRESH_MEAN_C,
cv2.THRESH_BINARY,
11, 2
)
cv2.imwrite(output_path, binarized_img)
# 使用範例
# adaptive_mean_binarization("receipt.jpg", "binarized_adaptive.png")
3. Floyd-Steinberg 抖動演算法 (Dithering)
Floyd-Steinberg 是一種基於誤差擴散 (Error Diffusion) 概念的二值化演算法,主要用於圖像的「半色調 (Halftone)」處理。
它的基本概念是:當我們將一個灰階像素(數值 0~255)強行轉換成純黑(0)或純白(255)時,會產生一個「量化誤差」(例如灰階值 120 被轉成 0,誤差就是 +120)。為了補償這個誤差以保持視覺上的灰階漸層感,演算法會按照特定的比例,將這個誤差擴散傳遞給其右方、下方、右下方與左下方的鄰近像素:
$$\begin{aligned} \text{Pixel}[x+1][y] &\leftarrow \text{Pixel}[x+1][y] + \text{Error} \times \frac{7}{16} \ \text{Pixel}[x-1][y+1] &\leftarrow \text{Pixel}[x-1][y+1] + \text{Error} \times \frac{3}{16} \ \text{Pixel}[x][y+1] &\leftarrow \text{Pixel}[x][y+1] + \text{Error} \times \frac{5}{16} \ \text{Pixel}[x+1][y+1] &\leftarrow \text{Pixel}[x+1][y+1] + \text{Error} \times \frac{1}{16} \end{aligned}$$
這種做法可以在只有黑白兩色的媒介上,透過點陣疏密程度「模擬」出灰階的漸層效果。
Floyd-Steinberg 的適用情境與 OCR 警告
- 最佳場景:電子書閱讀器 (E-ink)、熱感式發票列印機、復古像素風圖像處理。
- OCR 禁用警告:此演算法絕對不可以用於 OCR 預處理。因為它會將原本平滑的文字邊緣打碎成無數的網點雜訊,這會使 OCR 引擎(如 Tesseract 或 PaddleOCR)的特徵提取完全失效,導致辨識率降為零。
由於 OpenCV 沒有內建 Floyd-Steinberg 函數,以下是我們使用 NumPy 進行矩陣加速的完整演算法實作:
import cv2
import numpy as np
def floyd_steinberg_dithering(image_path, output_path):
# 讀取影像並轉換為浮點數矩陣以進行精確誤差計算
img = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE).astype(float)
h, w = img.shape
for y in range(h):
for x in range(w):
old_val = img[y, x]
# 二值化量化
new_val = 255 if old_val > 127 else 0
img[y, x] = new_val
# 計算量化誤差
err = old_val - new_val
# 將誤差向鄰近像素擴散
if x + 1 < w:
img[y, x + 1] += err * 7 / 16
if y + 1 < h:
if x - 1 >= 0:
img[y + 1, x - 1] += err * 3 / 16
img[y + 1, x] += err * 5 / 16
if x + 1 < w:
img[y + 1, x + 1] += err * 1 / 16
# 轉回 8 位元無符號整數並儲存
cv2.imwrite(output_path, img.clip(0, 255).astype(np.uint8))
# 使用範例
# floyd_steinberg_dithering("receipt.jpg", "binarized_dithering.png")
三種二值化演算法綜合比較
| 演算法名稱 | 決策範圍 | 核心優勢 | OCR 適用度 | 最佳應用場景 |
|---|---|---|---|---|
| 大津二值化 | 全局 (Global) | 自動計算門檻值,免手動調整 | ★★☆☆☆ (限均勻光源) | 光源均勻之紙本掃描文件 |
| 自適應均值門檻值 | 局部 (Local) | 抗陰影、抗反光,穩健度極高 | ★★★★★ (最佳) | 手機拍照證件、收據前處理 |
| Floyd-Steinberg | 局部誤差擴散 | 能在黑白媒介上完美模擬漸層灰階 | ☆☆☆☆☆ (禁用) | 電子紙、熱感式發票列印 |