Like Share Discussion Bookmark Smile

J.J. Huang   2026-01-27   Python OpenCV 03.圖片處理篇:基礎技巧   瀏覽次數:次   DMCA.com Protection Status

Python | OpenCV 二值化與閾值處理

📚 前言

在前面我們學會了 基本濾波與模糊效果
這一篇要進一步學習 二值化與閾值處理,這些操作能將影像轉換成黑白二值影像,方便後續的物件偵測、邊緣分析或特徵提取。

🔍 什麼是二值化?

二值化(Binarization,又稱閾值二進制)是一種簡單的影像分割方法。
它的原理是設定一個「閾值」(臨界值),並依照像素的灰階值進行轉換:

  • 當像素灰階值 大於或等於閾值 → 設為白色 (255)。
  • 當像素灰階值 小於閾值 → 設為黑色 (0)。

經過二值化處理後,影像只剩下黑與白兩種顏色,能大幅簡化影像內容,凸顯出結構與形狀。

📌 為什麼要用二值化?

  • 簡化影像:去除多餘的色彩資訊,保留最重要的形狀。
  • 常見用途:輪廓偵測、邊緣檢測、OCR(文字辨識)、影像分割。
  • 前處理步驟:許多影像分析流程會先進行二值化,再做後續計算。

🎨 測試圖片怎麼來?

如果你手邊沒有現成的圖片,也可以使用線上的「梯度生成器」工具快速製作一張灰階或彩色漸層圖,當作範例測試用:


圖:梯度生成器介面示例

  • 工具名稱:梯度生成器 Mdigi Gradient Generator
  • 功能:可自訂圖片尺寸、漸層角度與顏色,並下載成 JPEG 或 SVG 格式。
  • 操作方式:選擇三種顏色(例如白、灰、黑),設定角度為 90°,即可產生垂直漸層圖。

範例圖片:

圖:範例漸層圖片

這類漸層圖片非常適合用來觀察二值化的效果,尤其在不同閾值下的轉換結果。

📌 threshold() 方法原型

在 OpenCV 中,最常用的二值化方法是 cv2.threshold()

1
retval, dst = cv2.threshold(src, thresh, maxval, type)

參數說明

  • src:來源影像,通常是灰階圖像。
  • thresh:閾值(臨界值),用來判斷像素是否要轉換。
  • maxval:當條件成立時要設定的最大值(通常是 255)。
  • type:閾值模式(ThresholdTypes),決定轉換方式,例如 THRESH_BINARYTHRESH_TRUNC 等。

回傳值

  • retval:實際使用的閾值(在 Otsu 或 Triangle 模式下會自動計算)。
  • dst:處理後的影像。

📊 閾值模式比較表

模式 說明 行為公式
THRESH_BINARY 大於閾值 → 設為 maxval;否則 → 0 dst(x,y) = { maxval if src(x,y) > thresh, else 0 }
THRESH_BINARY_INV 大於閾值 → 0;否則 → 設為 maxval dst(x,y) = { 0 if src(x,y) > thresh, else maxval }
THRESH_TRUNC 大於閾值 → 設為閾值;否則保持原值 dst(x,y) = { thresh if src(x,y) > thresh, else src(x,y) }
THRESH_TOZERO 大於閾值 → 保持原值;否則 → 0 dst(x,y) = { src(x,y) if src(x,y) > thresh, else 0 }
THRESH_TOZERO_INV 大於閾值 → 0;否則保持原值 dst(x,y) = { 0 if src(x,y) > thresh, else src(x,y) }
THRESH_OTSU 使用 Otsu 演算法自動計算最佳閾值 常與 THRESH_BINARY 搭配
THRESH_TRIANGLE 使用 Triangle 演算法自動計算最佳閾值 適合直方圖單峰影像

參考:ThresholdTypes

💻 範例程式:基本閾值處理

1
2
3
4
5
6
7
8
9
10
11
12
import cv2

# 轉換前,先將圖片轉換成灰階色彩
img = cv2.imread("gradient.png", cv2.IMREAD_GRAYSCALE)

# 基本閾值處理
ret, thresh = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)

cv2.imshow("Original", img)
cv2.imshow("Threshold", thresh)
cv2.waitKey(0)
cv2.destroyAllWindows()


圖:程式碼執行結果 — 基本閾值處理

💻 範例程式:反向閾值處理

1
2
3
4
5
6
7
8
9
10
11
12
import cv2

# 轉換前,先將圖片轉換成灰階色彩
img = cv2.imread("gradient.png", cv2.IMREAD_GRAYSCALE)

# 反向閾值處理
ret, thresh_inv = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY_INV)

cv2.imshow("Original", img)
cv2.imshow("Threshold Inverse", thresh_inv)
cv2.waitKey(0)
cv2.destroyAllWindows()


圖:程式碼執行結果 — 反向閾值處理

💻 範例程式:多種閾值模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import cv2

# 轉換前,先將圖片轉換成灰階色彩
img = cv2.imread("gradient.png", cv2.IMREAD_GRAYSCALE)

# 閾值模式示例
_, thresh_binary = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)
_, thresh_binary_inv = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY_INV)
_, thresh_trunc = cv2.threshold(img, 127, 255, cv2.THRESH_TRUNC)
_, thresh_tozero = cv2.threshold(img, 127, 255, cv2.THRESH_TOZERO)
_, thresh_tozero_inv = cv2.threshold(img, 127, 255, cv2.THRESH_TOZERO_INV)

cv2.imshow("Binary", thresh_binary)
cv2.imshow("Binary Inv", thresh_binary_inv)
cv2.imshow("Trunc", thresh_trunc)
cv2.imshow("ToZero", thresh_tozero)
cv2.imshow("ToZero Inv", thresh_tozero_inv)
cv2.waitKey(0)
cv2.destroyAllWindows()


圖:程式碼執行結果 — 多種閾值模式

🔍 自適應二值化 (adaptiveThreshold)

在使用 threshold() 方法時,需要手動設定固定的閾值,這對於內容單純的影像很合適。但如果影像內容複雜、光線不均,每個區域的最佳閾值可能不同,這時就可以使用 adaptiveThreshold() 進行自適應二值化。

方法原型

1
dst = cv2.adaptiveThreshold(src, maxValue, adaptiveMethod, thresholdType, blockSize, C)

參數說明

  • src:來源影像,通常是灰階圖像。
  • maxValue:最大灰度值,通常設定為 255。
  • adaptiveMethod:自適應閾值計算方法。
  • thresholdType:二值化轉換方式,可參考前面 threshold() 的模式表。
  • blockSize:計算區域大小,必須為奇數(例如 11)。
  • C:偏移量,用來微調結果,常用值為 2。

自適應方法比較

方法 說明
cv2.ADAPTIVE_THRESH_MEAN_C 使用區域平均值作為閾值。
cv2.ADAPTIVE_THRESH_GAUSSIAN_C 使用區域加權高斯平均值作為閾值。

💻 範例程式:自適應閾值處理 (Adaptive Threshold)

範例圖片:

圖:範例 Sudoku 圖片

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import cv2
import numpy as np

# 讀取並轉換成灰階
img = cv2.imread("sudoku.png", cv2.IMREAD_GRAYSCALE)

# Global Thresholding(固定閾值)
_, global_thresh = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)

# Adaptive Mean Thresholding
adaptive_mean = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_MEAN_C,
cv2.THRESH_BINARY, 11, 2)

# Adaptive Gaussian Thresholding
adaptive_gaussian = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
cv2.THRESH_BINARY, 11, 2)

# 顯示四張圖
cv2.imshow("Original Image", img)
cv2.imshow("Global Thresholding (v=127)", global_thresh)
cv2.imshow("Adaptive Mean Thresholding", adaptive_mean)
cv2.imshow("Adaptive Gaussian Thresholding", adaptive_gaussian)

cv2.waitKey(0)
cv2.destroyAllWindows()


圖:圖片來源 — OpenCV 官方文件:Python Thresholding 教學


圖:程式碼執行結果 — 自適應閾值處理

💡 如果要降低圖片的雜訊,可以使用 cv2.medianBlur() 先將圖片模糊化,有模糊化和沒有模糊化的差異。

回顧OpenCV 基本濾波與模糊效果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import cv2
import numpy as np

# 讀取圖片並轉換為灰階
img_gray = cv2.imread("sudoku.png", cv2.IMREAD_GRAYSCALE)

# Step 1:原始影像(灰階)
original = img_gray

# Step 2:模糊化處理(降低雜訊)
blurred = cv2.medianBlur(img_gray, 5)

# Step 3:Adaptive Gaussian Thresholding(未模糊)
adaptive_gaussian_raw = cv2.adaptiveThreshold(img_gray, 255,
cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
cv2.THRESH_BINARY, 11, 2)

# Step 4:Adaptive Gaussian Thresholding(已模糊)
adaptive_gaussian_blur = cv2.adaptiveThreshold(blurred, 255,
cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
cv2.THRESH_BINARY, 11, 2)

# 顯示四張圖進行比較
cv2.imshow("Original Image (Grayscale)", original)
cv2.imshow("Blurred Image (Median Blur)", blurred)
cv2.imshow("Adaptive Gaussian Thresholding (Raw)", adaptive_gaussian_raw)
cv2.imshow("Adaptive Gaussian Thresholding (With Blur)", adaptive_gaussian_blur)

cv2.waitKey(0)
cv2.destroyAllWindows()


圖:程式碼執行結果 — 模糊化與未模糊化的差異


圖:靜態比較 — 模糊化與未模糊化的差異

⚠️ 注意事項

  • 閾值選擇:固定閾值可能不適合光線不均的影像,自適應閾值能更靈活。
  • 模式差異THRESH_BINARYTHRESH_BINARY_INV 最常用,其他模式適合特殊需求。
  • 模糊化前處理:在文字或數字影像中,先模糊化能降低雜訊,提升二值化效果。
  • 應用場景:OCR、邊緣檢測、影像分割、特徵提取。

    🎯 結語

這一篇我們學會了如何進行 二值化與閾值處理,包含基本閾值、反向閾值、多種閾值模式與自適應閾值,掌握影像黑白化的基礎技巧。這些方法能簡化影像內容,並在物件偵測與特徵分析中扮演重要角色。

在下一篇,我們將進一步學習 圖片的侵蝕與膨脹(形態學操作),探索如何利用形態學方法處理影像結構。

📖 如在學習過程中遇到疑問,或是想了解更多相關主題,建議回顧一下 Python | OpenCV 系列導讀,掌握完整的章節目錄,方便快速找到你需要的內容。


註:以上參考了
OpenCV Tutorials
OpenCV-Python Tutorials
Thresholding
ThresholdTypes