OpenCV4【8】- 图像阈值即二值化

图像阈值,即图像二值化,包括

简单阈值

自适应阈值

Otsu 阈值

局部阈值

全局阈值

熵算法

等多种方式,本文收集整理一下

简单阈值

对所有像素使用 统一固定 的阈值

def threshold(src, thresh, maxval, type, dst=None):
  • src:单通道图像,通常是灰度图
  • thresh:阈值
  • maxval:该参数与 type 有关,如果type=THRESH_BINARY,小于阈值置0,大于阈值置maxval,type=THRESH_BINARY_INV时刚好相反
  • type:取值见下面代码,通常用 THRESH_BINARY

该方法返回两个输出。第一个是使用的阈值,第二个输出是**阈值后的图像**

示例

img = cv.imread('imgs/2.png', 0)    # 0灰度,1彩色
ret, img_binary = cv.threshold(img, 127, 200, type=cv.THRESH_BINARY)        # 小于阈值127置0,否则置200
ret, img_binary_inv = cv.threshold(img, 127, 210, type=cv.THRESH_BINARY_INV)# 小于阈值127置210,否则置0,和上面相反,故 inv
print(ret)      # 127.0
ret, thresh3 = cv.threshold(img, 127, 255, cv.THRESH_TRUNC)
ret, thresh4 = cv.threshold(img, 127, 255, cv.THRESH_TOZERO)
ret, thresh5 = cv.threshold(img, 127, 255, cv.THRESH_TOZERO_INV)
titles = ['Original Image', 'BINARY', 'BINARY_INV', 'TRUNC', 'TOZERO', 'TOZERO_INV']
images = [img, img_binary, img_binary_inv, thresh3, thresh4, thresh5]
for i in range(6):
    plt.subplot(2, 3, i + 1); plt.imshow(images[i], 'gray')
    plt.title(titles[i])
    plt.xticks([]); plt.yticks([])
plt.show()

效果图

自适应阈值

同一图像的不同区域有不同光照,针对不同光照区域自动计算不同的阈值

def adaptiveThreshold(src, maxValue, adaptiveMethod, thresholdType, blockSize, C, dst=None):
  • adaptiveMethod:取值cv.ADAPTIVE_THRESH_MEAN_C,代表均值滤波,即阈值是邻近区域的平均值减去C;
  •         取值cv.ADAPTIVE_THRESH_GAUSSIAN_C,代表高斯滤波,即阈值是邻近区域的加权和减去C
  • blockSize: 邻近区域大小
  • C: 常数,计算阈值时会用到

返回二值化后的图像

示例

img = cv.imread('imgs/2.png', 0)    # p1
# p2
img = cv.imread('imgs/gz.jpg', 0)
img = cv.resize(img, None, fx=0.3, fy=0.3, interpolation=cv.INTER_LINEAR)
img_adaptive_thresh = cv.adaptiveThreshold(img, 255, adaptiveMethod=cv.ADAPTIVE_THRESH_MEAN_C,
                                           thresholdType=cv.THRESH_BINARY, blockSize=11, C=2)
cv.imshow('org', img)
cv.imshow('adaptiveThreshold', img_adaptive_thresh)
cv.waitKey(0)

效果图

Otsu 阈值

Otsu 方法也是 自动计算阈值 的一种方法;

原理先不讲了,先看用法吧

img = cv.imread('imgs/2.png', 0)
# 全局阈值
ret1, th1 = cv.threshold(img, 127, 255, cv.THRESH_BINARY)
# Otsu阈值
ret2, th2 = cv.threshold(img, 0, 255, cv.THRESH_BINARY+cv.THRESH_OTSU)
# 高斯滤波后再采用Otsu阈值
blur = cv.GaussianBlur(img, (5, 5), 0)
ret3, th3 = cv.threshold(blur, 0, 255, cv.THRESH_BINARY+cv.THRESH_OTSU)
# 绘制所有图像及其直方图
images = [img, 0, th1,
          img, 0, th2,
          blur, 0, th3]
titles = ['Original Noisy Img', 'Histogram', 'Global Thresh(v=127)',
          'Original Noisy Img', 'Histogram', "Otsu's Thresh",
          'Gaussian filtered Img', 'Histogram', "Otsu's Thresh"]
for i in range(3):
    plt.subplot(3, 3, i * 3 + 1)
    plt.imshow(images[i * 3], 'gray')
    plt.title(titles[i * 3])

    plt.subplot(3, 3, i * 3 + 2)
    plt.hist(images[i * 3].ravel(), 256)
    plt.title(titles[i * 3 + 1])

    plt.subplot(3, 3, i * 3 + 3)
    plt.imshow(images[i * 3 + 2], 'gray')
    plt.title(titles[i * 3 + 2])
plt.show()

未完待续... 

参考资料:

https://www.cnblogs.com/angle6-liu/p/10673585.html#top  图像二值化,阈值处理(十)

https://wenku.baidu.com/view/acc24dcf680203d8ce2f2469.html  图像二值化阈值选取常用方法汇总

https://blog.csdn.net/sinat_21258931/article/details/61418681  python-opencv函数总结之(一)threshold、adaptiveThreshold、Otsu 二值化

https://blog.csdn.net/u010128736/article/details/52801310  阈值化分割(二)OTSU法-附Python实现

https://zhuanlan.zhihu.com/p/143492231  基于Python的阈值分割算法实现(一)

https://www.cnblogs.com/gezhuangzhuang/p/10295181.html  OpenCV-Python入门教程6-Otsu阈值法

https://blog.csdn.net/shawroad88/article/details/87965784  python-opencv3教程:阈值分割(全阈值分割,局部阈值分割,直方图技术法,熵算法,自适应算法,Otsu算法)

原文地址:https://www.cnblogs.com/yanshw/p/12485935.html