OpenCV 您所在的位置:网站首页 阈值二值化算法 OpenCV

OpenCV

2023-08-25 15:05| 来源: 网络整理| 查看: 265

简单阈值(全局阈值)

  函数:threshold(src, thresh, maxval, type, dst=None),返回两个值retVal(阈值) 和 threshImg(处理后的图像)

    函数中四个参数分别是原图像、阈值、最大值、阈值类型 

  阈值类型一般分为五种:     cv2.THRESH_BINARY:大于阈值的部分像素值变为maxval,其他变为0     cv2.THRESH_BINARY_INV:大于阈值的部分变为0,其他部分变为最大值     cv2.THRESH_TRUNC:大于阈值的部分变为阈值,其余部分不变     cv2.THRESH_TOZERO:大于阈值的部分不变,其余部分变为0     cv2.THRESH_TOZERO_INV:大于阈值的部分变为0,其余部分不变

1 import numpy as np 2 import cv2 3 from matplotlib import pyplot as plt 4 5 # 读取灰度图 6 img = cv2.imread("../image/sight.jpg", 0) 7 8 ret1, thresh1 = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY) 9 ret2, thresh2=cv2.threshold(img, 127, 255, cv2.THRESH_BINARY_INV) 10 ret3, thresh3=cv2.threshold(img, 127, 255, cv2.THRESH_TRUNC) 11 ret4, thresh4=cv2.threshold(img, 127, 255, cv2.THRESH_TOZERO) 12 ret5, thresh5=cv2.threshold(img, 127, 255, cv2.THRESH_TOZERO_INV) 13 14 titles = ['Original Image','BINARY','BINARY_INV','TRUNC','TOZERO','TOZERO_INV'] 15 images = [img, thresh1, thresh2, thresh3, thresh4, thresh5] 16 for i in range(6): 17 plt.subplot(2,3,i + 1),plt.imshow(images[i], 'gray') 18 plt.title(titles[i]) 19 plt.xticks([]), plt.yticks([]) 20 plt.show()

结果:

 自适应阈值

  在前面的部分我们使用是全局阈值,整幅图像采用同一个数作为阈值。当时这种方法并不适应与所有情况,尤其是当同一幅图像上的不同部分的具有不同亮度时。这种情况下我们需要采用自适应阈值。此时的阈值是根据图像上的每一个小区域计算与其对应的阈值。因此在同一幅图像上的不同区域采用的是不同的阈值,从而使我们能在亮度不同的情况下得到更好的结果。

  adaptiveThreshold(src, maxValue, adaptiveMethod, thresholdType, blockSize, C, dst=None)  这种方法需要我们指定六个参数,返回值只有一个。

    • Adaptive Method- 指定计算阈值的方法。      – cv2.ADPTIVE_THRESH_MEAN_C:阈值取自相邻区域的平均值      – cv2.ADPTIVE_THRESH_GAUSSIAN_C:阈值取值相邻区域的加权和,权重为一个高斯窗口。    • Block Size - 邻域大小(用来计算阈值的区域大小)。    • C - 这就是是一个常数,阈值就等于的平均值或者加权平均值减去这个常数。

代码:

1 import numpy as np 2 import cv2 3 from matplotlib import pyplot as plt 4 5 # 读取灰度图 6 img = cv2.imread("../image/sight.jpg", 0) 7 8 # 中值滤波,用来平滑图像,去除噪声 9 img = cv2.medianBlur(img, 5) 10 11 # 简单阈值 12 ret, thresh1 = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY) 13 14 # 自适应,阈值取相邻区域的平均值 15 thresh2 = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 11, 2) 16 17 # 自适应,阈值取值相邻区域的加权和,权重为一个高斯窗口。 18 thresh3 = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2) 19 20 21 titles = ['Original Image', 'Global Thresholding (v = 127)', 22 'Adaptive Mean Thresholding', 'Adaptive Gaussian Thresholding'] 23 images = [img, thresh1, thresh2, thresh3] 24 for i in range(4): 25 plt.subplot(2,2,i+1),plt.imshow(images[i],'gray') 26 plt.title(titles[i]) 27 plt.xticks([]),plt.yticks([]) 28 plt.show()

结果:

如果不进行滤波处理,会出现噪声,如下图所示:

 Otsu’s 二值化

  在使用全局阈值时,只能通过不停的尝试来确定一个效果比较好的阈值。如果是一副双峰图像(简单来说双峰图像是指图像直方图中存在两个峰)呢?我们岂不是应该在两个峰之间的峰谷选一个值作为阈值?这就是 Otsu 二值化要做的。简单来说就是对一副双峰图像自动根据其直方图计算出一个阈值。(对于非双峰图像,这种方法得到的结果可能会不理想)。 

  函数还是 cv2.threshold(),但是需要多传入一个参数( flag): cv2.THRESH_OTSU。这时要把阈值设为 0。然后算法会找到最优阈值,这个最优阈值就是返回值 retVal。如果不使用 Otsu 二值化,返回的retVal 值与设定的阈值相等。

  算法分类的原理是让背景和目标之间的类间方差最大,因为背景和目标之间的类间方差越大,说明构成图像的两部分的差别越大,错分的可能性越小。 

代码:

import numpy as np import cv2 from matplotlib import pyplot as plt # 读取灰度图 img = cv2.imread("../image/girl.jpg", 0) # 全局阈值 ret1, th_img1 = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY) # Otsu’s 二值化 re2, th_img2 = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU) # Otsu’s 二值化之前先对图像进行高斯滤波处理,平滑图像,去除噪声 # (5,5)为高斯核大小,0为标准差 blur = cv2.GaussianBlur(img, (5, 5), 0) re3, th_img3 = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU) images = [img, 0, th_img1, img, 0, th_img2, blur, 0, th_img3] titles = ['Original Noisy Image','Histogram','Global Thresholding (v=127)', 'Original Noisy Image','Histogram',"Otsu's Thresholding", 'Gaussian filtered Image','Histogram',"Otsu's Thresholding"] for i in range(3): plt.subplot(3,3,i*3+1),plt.imshow(images[i*3],'gray') plt.title(titles[i*3]), plt.xticks([]), plt.yticks([]) plt.subplot(3,3,i*3+2),plt.hist(images[i*3].ravel(),256) plt.title(titles[i*3+1]), plt.xticks([]), plt.yticks([]) plt.subplot(3,3,i*3+3),plt.imshow(images[i*3+2],'gray') plt.title(titles[i*3+2]), plt.xticks([]), plt.yticks([]) plt.show()

结果: 高斯滤波后在进行二值化处理,会有明显的去除噪声的效果。(打印后看到, Otsu’s 二值化自动选取的阈值为122)

 



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有