1. 普通阈值操作
python中用法
对所有矩阵元素应用固定级别阈值
retval, dst = cv.threshold( src, thresh, maxval, type[, dst] )
参数列表
参数类型 | 功能 |
---|---|
src | 输入图像矩阵(多通道、8 位或 32 位浮点) |
thresh | 阈值 |
maxval | 在各种阈值类型中应用的最大值 |
type | 阈值类型 |
dst | 返回图像矩阵 |
ThresholdTypes(阈值类型)如下
实例
img = cv.imread("../file/photos/gradient.png", 0)
ret1, theresh1 = cv.threshold(img, 127, 255, cv.THRESH_BINARY)
ret2, theresh2 = cv.threshold(img, 127, 255, cv.THRESH_BINARY_INV)
ret3, theresh3 = cv.threshold(img, 127, 255, cv.THRESH_TRUNC)
ret4, theresh4 = cv.threshold(img, 127, 255, cv.THRESH_TOZERO)
ret5, theresh5 = cv.threshold(img, 127, 255, cv.THRESH_TOZERO_INV)
titles = ['Oringal image', 'BINARY', 'BINARY_INV', 'TRUNC', 'TOZERO', 'TOZERO_INV']
images = [img, theresh1, theresh2, theresh3, theresh4, theresh5]
for i in range(6):
plt.subplot(2, 3, i+1), plt.imshow(images[i], 'gray'), plt.title(titles[i])
plt.xticks([])# 显示x,y 轴坐标
plt.yticks([])
plt.show()
结果
2. 自适应阈值操作
python中用法
将自适应阈值应用到数组。在前一节中,使用一个全局值作为阈值。但是,这可能并非在所有情况下都是好的,例如,如果图像在不同区域具有不同的照明条件。在这种情况下,自适应阈值会有所帮助。在这里,算法根据周围一个小区域确定像素的阈值。因此,我们为同一图像的不同区域获得不同的阈值,从而为不同照明的图像提供更好的结果。
该函数根据公式将灰度图像转换为二进制图像
dst = cv.adaptiveThreshold( src, maxValue, adaptiveMethod, thresholdType, blockSize, C[, dst] )
参数类型 | 功能 |
---|---|
src | 8 位单通道源图像 |
dst | 返回的图像矩阵 |
maxValue | 分配给条件满足的像素的非零值 |
adaptiveMethod | 参考AdaptiveThresholdTypes |
thresholdType | 参考ThresholdTypes |
blockSize | 用于计算像素阈值的像素邻社区的大小:3、5、7 等。 |
C | 不断从均值或加权均值中减去(参见下面的详细信息)。通常,它是正的,但可能是零或者为负 |
AdaptiveThresholdTypes(自适应阈值类型)
类型 | |
---|---|
平均阈值Python: cv.ADAPTIVE_THRESH_MEAN_C | the threshold value T(x,y) is a mean of the blockSize×blockSize neighborhood of (x,y) minus C |
高斯阈值Python: cv.ADAPTIVE_THRESH_GAUSSIAN_C | the threshold value T(x,y) is a weighted sum (cross-correlation with a Gaussian window) of the blockSize×blockSize neighborhood of (x,y) minus C . The default sigma (standard deviation) is used for the specified blockSize . See getGaussianKernel |
实列
img = cv.imread("../file/photos/sudoku.jpg", 0)
img = cv.medianBlur(img, 5) # (孔径线性尺寸:必须是大于1的奇数,例如3、5、7…)
# 普通阈值法
ret, th1 = cv.threshold(img, 127, 255, cv.THRESH_BINARY)
# 自适应阈值——平均阈值类型
th2 = cv.adaptiveThreshold(img, 255, cv.ADAPTIVE_THRESH_MEAN_C,
cv.THRESH_BINARY, 11, 2)
# 自适应阈值——高斯阈值类型
th3 = cv.adaptiveThreshold(img, 255, cv.ADAPTIVE_THRESH_GAUSSIAN_C,
cv.THRESH_BINARY, 11, 2)
titles = ['Original Image', 'Global Thresholding (v = 127)',
'Adaptive Mean Thresholding', 'Adaptive Gaussian Thresholding']
images = [img, th1, th2, th3]
for i in range(4):
plt.subplot(2, 2, i+1), plt.imshow(images[i], 'gray'), plt.title(titles[i])
plt.xticks([])
plt.yticks([])
plt.show()
结果
其中cv.medianBlur(img, 5)参考medianBlur()该功能使用中位数滤镜平滑图像与 ksize×ksize 孔径。多通道图像的每个通道都独立处理。
3. Otsu二值化
在全局阈值中,我们随意地指定一个值作为阈值,相比之下,大津二值法避免选择一个值,而是自动地决定这个值。考虑一个只有两个不同图像值的图像(双模图像),直方图将只包括两个山峰。一个好的阈值将在这两个值的中间。同样,大津的方法从图像直方图中确定最佳的全局阈值,为了达到这个目的,这里使用cv.threshold()方法,而cv.THRESH_OTSU被作为一个额外的标志,阈值可以任意选择。 然后,该算法找到作为第一个输出返回的最佳阈值。
实例
ret1, th1 = cv.threshold(img, 127, 255, cv.THRESH_BINARY)
ret2, th2 = cv.threshold(img, 0, 255, cv.THRESH_BINARY + cv.THRESH_OTSU)
blur = cv.GaussianBlur(img, (5, 5), 0)
'''
# cv.GaussianBlur( src, ksize, sigmaX[, dst[, sigmaY[, borderType]]] ) -> dst
'''
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 Image", "Histogram", "Global Thresholding (v=127)",
"Original Noisy Image", "Histogram", "Ostu's Thresholding",
"Gaussian filtered Image", "Histogram", "Ostu's Thresholding",
]
for i in range(3):
plt.subplot(3, 3, 3*i+1), plt.imshow(images[i*3], 'gray')
plt.title(titles[i*3]), plt.xticks([]), plt.yticks([])
plt.subplot(3, 3, 3*i+2), plt.hist(images[i*3].ravel(), 256, color="black")
plt.title(titles[i*3+1]), plt.xticks([]), plt.yticks([])
plt.subplot(3, 3, 3*i+3), plt.imshow(images[i*3+2], 'gray')
plt.title(titles[i*3+2]), plt.xticks([]), plt.yticks([])
plt.show()
其中cv.GaussianBlur()高斯模糊参考cv.GaussianBlur
结果
以上示例中,第一个直接进行全局阈值操作;第二个直接进行大津二值法操作:第三个首先用5x5高斯内核过滤以消除噪音,然后应用大津阈值,可以看到噪音过滤改善的结果。