OpenCV阈值处理完全指南:从基础到高级应用
引言
阈值处理是图像处理中最基础、最常用的技术之一,它能够将灰度图像转换为二值图像,为后续的图像分析和处理奠定基础。本文将全面介绍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中的基本阈值处理方法、自适应阈值和大津算法,并提供了实际应用案例和高级技巧。希望通过本文的学习,您能够根据不同的应用场景选择合适的阈值处理方法。