阈值的作用是根据设定的值处理图像的灰度值,比如灰度大于某个数值像素点保留。通过阈值以及有关算法可以实现从图像中抓取特定的图形,比如去除背景等。
cv2中的阈值相关函数有:

  1. 普通阈值函数threshold
  2. 自适应阈值函数adaptivthreshold

首先介绍简单阈值函数:cv2.threshold(src, thresh, maxval, type[, dst]),返回值为retval, dst
其中:
src是灰度图像
thresh是起始阈值
maxval是最大值
type是定义如何处理数据与阈值的关系。有以下几种:

选项像素值>thresh其他情况
cv2.THRESH_BINARYmaxval0
cv2.THRESH_BINARY_INV0maxval
cv2.THRESH_TRUNCthresh当前灰度值
cv2.THRESH_TOZERO当前灰度值0
cv2.THRESH_TOZERO_INV0当前灰度值

另外的取值为:

  • cv2.THRESH_OTSU
  • cv2.THRESH_TRIANGLE
  • cv2.THRESH_MASK

cv2.THRESH_OTSU使用最小二乘法处理像素点,而cv2.THRESH_TRIANGLE使用三角算法处理像素点。一般情况下,cv2.THRESH_OTSU适合双峰图。cv2.THRESH_TRIANGLE适合单峰图。单峰图或者双峰图指的是灰度直方图。
比如下面的图片的灰度直方图是:
在这里插入图片描述
cv2.THRESH_OTSU、cv2.THRESH_TRIANGLE是标志位,他们可以和其他参数,比如cv2.THRESH_BINARY一起使用。
当使用cv2.THRESH_OTSU或cv2.THRESH_TRIANGLE时,阈值是动态的,会根据计算结果返回相应的数值。
以下是固定阈值、使用了OTSU、使用了TRIANGLE的结果:

import cv2
import matplotlib.pyplot as plt

img = cv2.imread('d:\\xk.png')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
min_value=127
#固定阈值
ret,thresh1 = cv2.threshold(gray,min_value,255,cv2.THRESH_BINARY)
ret,thresh2 = cv2.threshold(gray,min_value,255,cv2.THRESH_BINARY_INV)
ret,thresh3 = cv2.threshold(gray,min_value,255,cv2.THRESH_TRUNC)
ret,thresh4 = cv2.threshold(gray,min_value,255,cv2.THRESH_TOZERO)
ret,thresh5 = cv2.threshold(gray,min_value,255,cv2.THRESH_TOZERO_INV)
print("固定阈值:", ret)
#使用了OTSU
ret,thresh11 = cv2.threshold(gray,min_value,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
ret,thresh12 = cv2.threshold(gray,min_value,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)
ret,thresh13 = cv2.threshold(gray,min_value,255,cv2.THRESH_TRUNC+cv2.THRESH_OTSU)
ret,thresh14 = cv2.threshold(gray,min_value,255,cv2.THRESH_TOZERO+cv2.THRESH_OTSU)
ret,thresh15 = cv2.threshold(gray,min_value,255,cv2.THRESH_TOZERO_INV+cv2.THRESH_OTSU)
print("OTSU:", ret)
#使用了TRIANGLE
ret, thresh21 = cv2.threshold(gray, min_value, 255, cv2.THRESH_BINARY + cv2.THRESH_TRIANGLE)
ret, thresh22 = cv2.threshold(gray, min_value, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_TRIANGLE)
ret, thresh23 = cv2.threshold(gray, min_value, 255, cv2.THRESH_TRUNC + cv2.THRESH_TRIANGLE)
ret, thresh24 = cv2.threshold(gray, min_value, 255, cv2.THRESH_TOZERO + cv2.THRESH_TRIANGLE)
ret, thresh25 = cv2.threshold(gray, min_value, 255, cv2.THRESH_TOZERO_INV + cv2.THRESH_TRIANGLE)
print("TRIANGLE:", ret)
titles = ['BINARY','BINARY_INV','TRUNC','TOZERO','TOZERO_INV',
          'BINARY+OTSU','BINARY_INV+OTSU','TRUNC+OTSU','TOZERO+OTSU','TOZERO_INV+OTSU',
          'BINARY+TRI','BINARY_INV+TRI','TRUNC+TRI','TOZERO+TRI','TOZERO_INV+TRI']
images = [thresh1,thresh2,thresh3,thresh4,thresh5,
          thresh11,thresh12,thresh13,thresh14,thresh15,
          thresh21,thresh22,thresh23,thresh24,thresh25]
for i in range(15):
    plt.subplot(3,5,i+1),plt.imshow(images[i],'gray')
    plt.title(titles[i])
    plt.xticks([]),plt.yticks([])
plt.show()

在这里插入图片描述
在没使用任何算法的情况下,使用阈值=127会过滤掉绿色的圆。另外,可以发现返回的阈值也是不同的:

固定阈值: 127.0
OTSU: 123.0
TRIANGLE: 93.0

原始的图片和直方图如下:
在这里插入图片描述
实际的图片处理要比这个复杂。后面会介绍更多的图像处理使用方法。

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐