专注算法的马里奥学长

专注算法的马里奥学长

1 基本概念

CV2中使用阈值的作用是将灰度图像二值化,即将灰度图像的像素值根据一个设定的阈值分成黑白两部分。阈值处理可以用于图像分割、去除噪声、增强图像对比度等多个领域。例如,在物体检测和跟踪中,可以通过对图像进行阈值处理来提取目标区域;在图像增强中,可以使用阈值处理来增强图像的轮廓和细节等。
阈值处理可以使用cv2.threshold()函数来完成。

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

其中,参数解释如下:

  • src:输入图像,可以是灰度图像或彩色图像。
  • thresh:设定的阈值。
  • maxval:二值化后的最大值。当typecv2.THRESH_BINARYcv2.THRESH_BINARY_INV时,像素值大于阈值的部分会设置为maxval,否则会设置为0。
  • type:二值化操作的类型,包括:
    • cv2.THRESH_BINARY:二值化操作,大于阈值的像素值设置为maxval,小于等于阈值的像素值设置为0。
    • cv2.THRESH_BINARY_INV:反向二值化操作,大于阈值的像素值设置为0,小于等于阈值的像素值设置为maxval
    • cv2.THRESH_TRUNC:截断操作,大于阈值的像素值设置为阈值,小于等于阈值的像素值保持不变。
    • cv2.THRESH_TOZERO:像素值小于等于阈值的设置为0,大于阈值的保持不变。
    • cv2.THRESH_TOZERO_INV:像素值大于等于阈值的设置为0,小于阈值的保持不变。

cv2.threshold()函数的返回值为一个元组,包括:

  • retval:实际使用的阈值。
  • dst:二值化后的输出图像。

2 二值化处理

灰度图像

通过对灰度图像进行二值处理,可以在图形中只保留两种颜色,通常我们设定为255(白色)和0(黑色),但也可根据需求设置为黑色和灰色的二值图像,如:

import cv2  
img = cv2.imread("lenacolor.png", 0)  # 将图像读成灰度图像  
t1, dst1 = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)  # 二值化阈值处理  
t2, dst2 = cv2.threshold(img, 127, 200, cv2.THRESH_BINARY)  
cv2.imshow('img', img)  
cv2.imshow('dst1', dst1)  
cv2.imshow('dst2', dst2)  
cv2.waitKey()  
cv2.destroyAllWindows()

06 OpenCV 阈值处理、自适应处理与ostu方法-LMLPHP

彩色图像

同样这一方法可用于彩色图像,通过对某一通道进行二值化,使图像的颜色变得更加夸张,如:

import cv2  
  
img = cv2.imread('lenacolor.png')  
b, g, r = cv2.split(img)  # 将BGR通道分离  
  
# 对红色通道进行阈值处理  
t1, r = cv2.threshold(r, 127, 255, cv2.THRESH_BINARY)  
  
img_after = cv2.merge([b, g, r])  
  
cv2.imshow('original', img)  
cv2.imshow('threshold', img_after)  
cv2.waitKey(0)  
cv2.destroyAllWindows()

06 OpenCV 阈值处理、自适应处理与ostu方法-LMLPHP

反二值化处理

反二值化处理(Inverse Thresholding)是二值化处理的一种变体,其作用是将灰度图像的像素值根据一个设定的阈值分成两部分,但是与普通二值化处理不同的是,反二值化处理将像素值大于阈值的部分设置为0,小于等于阈值的部分设置为最大像素值,即产生一个反色的二值化图像。代码中type需要设置为cv2.THRESH_BINARY_INV

3 零处理

低于阈值零处理

低于阈值的部分会被处理为0,此时填入的maxval无效
对灰度图来说,低于阈值的部分将会被处理为黑色;对于RGB彩图来说,低于阈值的部分图像会变暗。

import cv2  
img1 = cv2.imread("test.png", 0)  # 将图像读成灰度图像  
img2 = cv2.imread("test.png")  
  
b, g, r = cv2.split(img2)  # 将BGR通道分离  
  
t1, dst1 = cv2.threshold(img1, 127, 255, cv2.THRESH_TOZERO)  # 低于阈值零处理  
cv2.imshow('img1', img1)    
cv2.imshow('dst1', dst1)    
  
t2, b = cv2.threshold(b, 127, 255, cv2.THRESH_TOZERO)  # 低于阈值零处理  
img_after = cv2.merge([b, g, r])  
cv2.imshow('img2', img2)  
cv2.imshow('img_after', img_after)    
  
cv2.waitKey()  
cv2.destroyAllWindows()

06 OpenCV 阈值处理、自适应处理与ostu方法-LMLPHP

超出阈值零处理

类似反二值化处理。将超出某一阈值的部分进行归零处理。超出阈值零处理可以在一些特定的场合下使用,例如在一些需要保留一定程度的图像细节的场合,超出阈值零处理可以避免将过多的像素值直接设置为0或最大像素值,从而使图像保留更多的细节信息。

4 截断处理

该方法传入的type是cv2.THRESH_TRUNC,代码结构与前面高度重合,此处不再贴代码。
截断处理是二值化处理的一种变体,其作用是将灰度图像的像素值根据一个设定的阈值分成两部分,但是与普通的二值化处理不同的是,超出阈值的部分不会被设置为0或最大像素值,而是被截断为阈值本身。
图像截断处理通常适合用于需要保留图像主要信息的场合,而又不需要进行明显的二值化操作的场合。在这种情况下,截断处理可以使得图像保留更多的灰度级,从而能够更好地保留图像中的细节和信息,同时又能够去除一些噪声或者不需要的部分。

5 自适应处理

自适应阈值处理是图像处理中的一种常见操作,可以根据图像局部的灰度特征来自适应地确定阈值,以达到更好的二值化效果。在OpenCV中,可以使用cv2.adaptiveThreshold()函数进行自适应阈值处理。
相比于阈值处理,自适应处理具有以下优点:

  1. 自适应处理可以根据局部像素的灰度值特征来确定二值化阈值,从而适应图像的不同区域和不同光照条件,能够更好地突出图像中的目标物体。
  2. 自适应处理可以在处理过程中保留更多的细节信息,减少因阈值过大或过小而造成的信息丢失,提高图像处理的准确性。
  3. 自适应处理适用于复杂背景下的目标物体分割,特别是在背景区域灰度分布不均的情况下,能够更好地处理背景区域和目标区域的差异。

自适应处理相比于阈值处理具有更好的适应性和灵活性,可以在不同的图像处理场景中应用。当图像的灰度分布不均、光照条件不同或需要保留更多的细节信息时,自适应处理通常是更好的选择。

cv2.adaptiveThreshold()函数的基本语法如下:

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

其中:

  • src:输入图像,必须为灰度图像。
  • maxValue:二值化后的最大值。
  • adaptiveMethod:自适应阈值处理的方法,包括:
    • cv2.ADAPTIVE_THRESH_MEAN_C:基于均值的自适应阈值处理。
    • cv2.ADAPTIVE_THRESH_GAUSSIAN_C:基于高斯加权平均值的自适应阈值处理。
  • thresholdType:阈值类型,与普通二值化处理相同,包括:
    • cv2.THRESH_BINARY:二值化操作,大于阈值的像素值设置为maxValue,小于等于阈值的像素值设置为0。
    • cv2.THRESH_BINARY_INV:反向二值化操作,大于阈值的像素值设置为0,小于等于阈值的像素值设置为maxValue
  • blockSize:每个像素点周围用来计算阈值的像素数。必须是奇数。
  • C:阈值校正值。该值会被加到均值或加权平均值上,用于调整阈值。

cv2.adaptiveThreshold()函数的返回值为二值化后的输出图像。

仍以上一张图像为例:

import cv2  
  
image_Gray = cv2.imread("test.png", 0)  
  
# 自适应阈值的计算方法为cv2.ADAPTIVE_THRESH_MEAN_C  
athdMEAM = cv2.adaptiveThreshold\  
    (image_Gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 5, 0)  
# 自适应阈值的计算方法为cv2.ADAPTIVE_THRESH_GAUSSIAN_C  
athdGAUS = cv2.adaptiveThreshold\  
    (image_Gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY, 5, 0)  
# 显示自适应阈值处理的结果  
cv2.imshow("MEAN_C", athdMEAM)  
cv2.imshow("GAUSSIAN_C", athdGAUS)  
cv2.waitKey()  
cv2.destroyAllWindows()

06 OpenCV 阈值处理、自适应处理与ostu方法-LMLPHP
可以看出自适应阈值似乎保留了更多细节,但此处效果并不好,也就说明自适应并不能完全代替人工选择。(对于人脸图像,该方法的效果会比上图更好一些)

6 Ostu方法

Otsu’s method 是一种经典的自适应阈值处理算法,可以自动确定图像的二值化阈值。该算法可以将图像中的像素值分为两部分,从而将图像转换为二值图像。在 OpenCV 中,可以使用cv2.threshold()函数进行 Otsu’s method 处理。在type中,输入对应的方法名+cv2.THRESH_OTSU即可调用该方法。该方法的存在也是threshold将阈值作为返回值的意义所在。
在 Otsu’s method 中,不需要预先指定阈值,而是通过计算图像灰度直方图和类间方差来确定阈值。具体来说,该方法会计算每一个像素灰度值作为阈值时,将图像分为前景和背景两部分的类间方差,然后选取类间方差最大的像素灰度值作为二值化阈值。

import cv2

img = cv2.imread('test.png', 0)
ret, thresh = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)

cv2.imshow('original', img)
cv2.imshow('Otsu threshold', thresh)
cv2.waitKey(0)
cv2.destroyAllWindows()

06 OpenCV 阈值处理、自适应处理与ostu方法-LMLPHP

02-16 12:32