图像的阈值处理

图像的阈值处理是指剔除图像内像素高于一定值或者低于一定值的像素点。在opencv中,函数cv2.threshold()或cv2.adaptiveThreshold()实现阈值处理。

一:cv2.threshold()函数

retval,dst=cv2.threshold(src,thresh,maxval,type)
retval:代表返回的阈值
dst:代表阈值分割结果图像,与原始图像具有相同的大小与类型。
src:待进行阈值分割的图像,可以是多通道的,8位或32位浮点型数值。
thresh:阈值
maxval:当type为THRESH_BINARY或者THRESH_BINARY_INV类型时,需要设定的最大值。
type:阈值分割的类型,见下图。

在这里插入图片描述
(1)、二值化阈值处理(cv2.THRESH_BINARY)
二值化阈值处理会将原始图像处理为仅有两个值的二值图像

import cv2
import numpy as np

img=cv2.resize(cv2.imread("F:/my_project/opencv/img/1.jpg"),(300,300))

t,dst=cv2.threshold(img,127,240,cv2.THRESH_BINARY)
b,g,r=cv2.split(dst)
cv2.imshow("b",b)
cv2.imshow("g",g)
cv2.imshow("r",r)
cv2.imshow("img",img)cv2.imshow("dst",dst)
cv2.waitKey()

在这里插入图片描述
图dst之所以会出现彩色,是因为在做阈值操作时,会对B、G、R每个通道做阈值操作,得到的每个通道都是二值图像(但各不相同),但叠加之后会出现彩色

(2)、反二值化阈值处理(cv2.THRESH_BINARY)
小于阈值时,被处理为设置的最大值maxval,反之被处理为0。

import cv2
import numpy as np

img=cv2.resize(cv2.imread("F:/my_project/opencv/img/1.jpg"),(300,300))
t,dst=cv2.threshold(img,127,240,cv2.THRESH_BINARY_INV)
cv2.imshow("img",img)
cv2.imshow("dst",dst)
cv2.waitKey()		

在这里插入图片描述

(3)、截断阈值化处理(cv2.THRESH_TRUNC)
对于像素值大于阈值的像素点,其像素值被设定为阈值。
对于像素值小于或等于阈值的像素点,其像素值保持不变。
此时maxval参数不起作用

	import cv2
	import numpy as np
	
	img=cv2.resize(cv2.imread("F:/my_project/opencv/img/1.jpg"),(300,300))
	
	t1,dst1=cv2.threshold(img,100,0,cv2.THRESH_TRUNC)
	#改变maxval值
	t2,dst2=cv2.threshold(img,100,150,cv2.THRESH_TRUNC)
	#改变阈值
	t3,dst3=cv2.threshold(img,220,0,cv2.THRESH_TRUNC)
	
	cv2.imshow("img",img)
	cv2.imshow("dst1",dst1)
	cv2.imshow("dst2",dst2)
	cv2.imshow("dst3",dst3)
	cv2.waitKey()

在这里插入图片描述
由图dst1与dst2一致可知,maxval在该模式下不起作用,由于设置的dst1阈值比dst3阈值比,所以整体dst3比dst1亮度更高。

(3)、超阈值零处理(cv2.THRESH_TOZERO_INV)

略,自己实验

(4)、低阈值零处理(cv2.THRESH_TOZERO)

略,自己实验

(4)、自适应阈值处理

对于色彩均衡的图像,只使用一个阈值就能完成对图像的阈值化处理,但是当图像色彩不均衡时,如果只使用一个阈值,就无法得到清晰有效的阈值分割结果图像。

自适应阈值处理:通过计算每个像素点周围临近区域的加权平均值来获得阈值,并使用该阈值对当前像素点进行处理,它能较好的处理明暗差异较大的图像。

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

A:src:必须为8位单通道的图像

B:adaptiveMethod:自适应方法,包含cv2.ADAPTIVE_THRESH_GAUSSIAN_C(加权平均,权重与它的blockSize邻域像素到中心点的距离有关,再减去常量C)与cv2.ADAPTIVE_THRESH_MEAN_C(blockSize邻域内的数值直接平均,再减去常量C)两种方式。

C :thresholdType:阈值处理方式,必须为cv2.THRESH_BINARY或cv2.THRESH_BINARY_INV中的一个

D:blockSize:像素在计算阈值时,所使用的邻域尺寸大小,通常为3,5,7等

E:C:常量

import cv2
import numpy as np

#自适应阈值时一定要单通道
img=cv2.resize(cv2.imread("F:/my_project/opencv/img/7.jpg",0),(300,300))
img1=cv2.resize(cv2.imread("F:/my_project/opencv/img/7.jpg"),(300,300))
#t1返回的是设置的阈值127,dst为阈值分割图
t1,dst=cv2.threshold(img,127,255,cv2.THRESH_BINARY)
dst1=cv2.adaptiveThreshold(img,127,cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY,11, C=0)
dst2=cv2.adaptiveThreshold(img,127,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,11, C=0)
dst3=cv2.adaptiveThreshold(img,127,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY_INV,11, C=0)
dst4=cv2.adaptiveThreshold(img,127,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY_INV,3, C=0)

cv2.imshow("img1",img1)
cv2.imshow("dst",dst)
cv2.imshow("dst1",dst1)
cv2.imshow("dst2",dst2)
cv2.imshow("dst3",dst3)
cv2.imshow("dst4",dst4)
cv2.waitKey()

在这里插入图片描述
图dst2与图dst3采用的阈值处理方式相反。所以成像相反,图dst4相对于dst3采用的blockSize更小,在此体现的细节更明显(blockSize太大的话图像容易模糊)

(5)、Otsu处理
在使用cv2.threshold()进行阈值处理时,需要定义一个阈值,但实际处理的图像往往比较复杂,阈值不太可能用人眼观察得到,而Otsu方法能够根据当前图像给出最佳的类间分割阈值(它会遍历所有可能阈值,从而找到最佳阈值)。

t,otus=cv2.threshold(img,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)

与普通的阈值分割不同之处:
a:在原有的type(阈值分割类型)后面需要加上参数“cv2.THRESH_OTSU”,(只能处理单通道)
b:设定的阈值为0
c:返回值t为返回的最佳阈值

import cv2

#自适应阈值时一定要单通道
img=cv2.resize(cv2.imread("D:/my project/opencv3/chapter_1/img/4.jpg"),(300,300))
img1=cv2.resize(cv2.imread("D:/my project/opencv3/chapter_1/img/4.jpg",0),(300,300))
#显示彩色图像
cv2.imshow("img",img)
#显示灰度图像
cv2.imshow("img1",img1)

b,g,r=cv2.split(img)
#对每个通道Otsu处理
b_t,b_1=cv2.threshold(b,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
g_t,g_1=cv2.threshold(g,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
r_t,r_1=cv2.threshold(r,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
img_1=cv2.merge([b_1,g_1,r_1])
print(b_t,g_t,r_t)
cv2.imshow("otsu",img_1)
#单通道灰度图经过Otsu阈值处理后的图像
gray_t,gray_thd=cv2.threshold(img1,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
cv2.imshow("gray_thd",gray_thd)
#普通阈值处理
t1,thd=cv2.threshold(img,150,255,cv2.THRESH_BINARY)
cv2.imshow("thd",thd)
t2,thd2=cv2.threshold(img1,150,255,cv2.THRESH_BINARY)
cv2.imshow("thd2",thd2)
cv2.waitKey()

在这里插入图片描述
图img与img1分别为原彩色图以及灰度图,gray_thd与thd2分别为灰度图经过Otsu阈值处理后的图以及经过随机筛选阈值的普通阈值处理之后的图,从效果来看,gray_thd要更优一些。最后的图thd与otsu分别为彩色图经普通阈值处理及每个通道经Otsu阈值处理后合并的彩色图像。


版权声明:本文为sc9876543210原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。