引言
閾值處理是圖像處理中最基礎、最常用的技術之一,它能夠將灰度圖像轉換為二值圖像,為后續的圖像分析和處理奠定基礎。本文將全面介紹OpenCV中的各種閾值處理方法,包括原理講解、代碼實現和實際應用場景。
一、什么是閾值處理?
閾值處理(Thresholding)是通過設定一個或多個閾值,將圖像的像素值分為若干類的過程。對于灰度圖像,通常是選擇一個閾值,將像素分為"黑"和"白"兩類,從而創建二值圖像。
數學表達式:
dst(x,y) = maxVal if src(x,y) > thresh= 0 otherwise
二、OpenCV中的閾值處理函數
OpenCV提供了cv2.threshold()
函數用于基本的閾值處理,其函數原型為:
retval, dst = cv2.threshold(src, thresh, maxval, type[, dst])
參數說明:
src
:輸入圖像(必須為灰度圖)thresh
:閾值maxval
:當像素值超過閾值時賦予的最大值type
:閾值類型retval
:實際使用的閾值(某些方法會自動計算)dst
:輸出圖像
三、5種基本閾值處理方法
1. 二進制閾值化(THRESH_BINARY)
import cv2
import numpy as npimg = cv2.imread('image.jpg', 0) # 以灰度模式讀取
ret, thresh1 = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)
效果:像素值>127設為255,否則設為0
2. 反二進制閾值化(THRESH_BINARY_INV)
ret, thresh2 = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY_INV)
效果:與THRESH_BINARY相反
3. 截斷閾值化(THRESH_TRUNC)
ret, thresh3 = cv2.threshold(img, 127, 255, cv2.THRESH_TRUNC)
效果:像素值>127設為127,否則保持不變
4. 閾值化為0(THRESH_TOZERO)
ret, thresh4 = cv2.threshold(img, 127, 255, cv2.THRESH_TOZERO)
效果:像素值>127保持不變,否則設為0
5. 反閾值化為0(THRESH_TOZERO_INV)
ret, thresh5 = cv2.threshold(img, 127, 255, cv2.THRESH_TOZERO_INV)
效果:與THRESH_TOZERO相反
四、自適應閾值處理
當圖像光照不均時,全局閾值效果不佳,此時可以使用自適應閾值:
thresh = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY, 11, 2)
參數說明:
adaptiveMethod
:自適應方法ADAPTIVE_THRESH_MEAN_C
:鄰域均值ADAPTIVE_THRESH_GAUSSIAN_C
:鄰域加權和(高斯)
blockSize
:鄰域大小(奇數)C
:從均值或加權和中減去的常數
五、Otsu’s二值化(大津算法)
對于雙峰圖像(直方圖有兩個明顯峰值),Otsu方法可以自動確定最佳閾值:
ret2, th2 = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)
六、實際應用案例
1. 文檔掃描與OCR預處理
def preprocess_for_ocr(image_path):img = cv2.imread(image_path, 0)# 使用Otsu方法自動閾值化_, thresh = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)# 去噪kernel = np.ones((3,3), np.uint8)processed = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations=1)return processed
2. 工業檢測中的缺陷識別
def detect_defects(reference_img, test_img):# 轉換為灰度圖ref_gray = cv2.cvtColor(reference_img, cv2.COLOR_BGR2GRAY)test_gray = cv2.cvtColor(test_img, cv2.COLOR_BGR2GRAY)# 計算差異diff = cv2.absdiff(ref_gray, test_gray)# 自適應閾值處理thresh = cv2.adaptiveThreshold(diff, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY, 11, 2)# 尋找輪廓contours, _ = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)# 繪制缺陷區域result = test_img.copy()for cnt in contours:if cv2.contourArea(cnt) > 10: # 忽略小面積x,y,w,h = cv2.boundingRect(cnt)cv2.rectangle(result, (x,y), (x+w,y+h), (0,0,255), 2)return result
七、閾值處理的高級技巧
1. 多閾值處理
def multi_threshold(image):gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)# 定義三個閾值_, th1 = cv2.threshold(gray, 50, 255, cv2.THRESH_BINARY)_, th2 = cv2.threshold(gray, 100, 255, cv2.THRESH_BINARY)_, th3 = cv2.threshold(gray, 150, 255, cv2.THRESH_BINARY)# 組合結果result = np.zeros_like(gray)result[(gray >= 0) & (gray < 50)] = 0result[(gray >= 50) & (gray < 100)] = 100result[(gray >= 100) & (gray < 150)] = 200result[gray >= 150] = 255return result
2. 基于HSV空間的閾值處理
def hsv_threshold(image):hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)# 定義顏色范圍(示例:紅色)lower_red = np.array([0, 120, 70])upper_red = np.array([10, 255, 255])mask1 = cv2.inRange(hsv, lower_red, upper_red)lower_red = np.array([170, 120, 70])upper_red = np.array([180, 255, 255])mask2 = cv2.inRange(hsv, lower_red, upper_red)# 合并maskmask = mask1 + mask2# 應用maskresult = cv2.bitwise_and(image, image, mask=mask)return result
八、性能優化
性能優化建議:
- 對小圖像使用全局閾值,對大圖像使用自適應閾值
- 在循環中處理視頻幀時,預先轉換為灰度圖
- 合理選擇blockSize(通常11-31之間的奇數)
九、總結
閾值處理是圖像分割和特征提取的基礎,掌握各種閾值處理方法能夠為更復雜的計算機視覺任務打下堅實基礎。本文介紹了OpenCV中的基本閾值處理方法、自適應閾值和大津算法,并提供了實際應用案例和高級技巧。希望通過本文的學習,您能夠根據不同的應用場景選擇合適的閾值處理方法。