文章目录
阈值处理类似于分段函数处理,设定一个阈值,若图像中的像素点灰度值大于阈值,对其做一定处理;对低于阈值的像素点做另一类处理。如对于一幅灰度图,我们设定阈值为125,大于125的像素点灰度值设为255,小于255的像素点设为0,这样我们就可以得到一副二值图像。
在OpenCV中提供了cv2.threshold()和cv2.adaptiveThreshold()来实现阈值处理。
一.threshold函数
该函数语法格式:
retval,dst=cv2.threshold(src,thresh,maxval,type)
参数说明:
retval:返回的阈值
dst:目标输出图像
src:原始输入图像
thresh:要设定的阈值
maxval:当阈值类型参数type设定为THRESH_BINARY或者THRESH_BINARY_INV类型时,需要设定的最大值。
type:阈值类型,具体如下表:
各种阈值类型的图形表示:
几种应用实例:
1.将灰度图转化为二值图像:
import cv2
import numpy as np
cat=cv2.imread("cat_gray.jpg")
retval,binary=cv2.threshold(cat,127,255,cv2.THRESH_BINARY)
cv2.imshow("cat",cat)
cv2.imshow("binary",binary)
cv2.waitKey(0)
cv2.destroyAllWindows()
运行结果:
2.对图像进行反二值变换:
import cv2
import numpy as np
cat=cv2.imread("cat_gray.jpg")
retval,binary=cv2.threshold(cat,127,255,cv2.THRESH_BINARY_INV)
cv2.imshow("cat",cat)
cv2.imshow("binary",binary)
cv2.waitKey(0)
cv2.destroyAllWindows()
运行结果:
3.对图像进行截断阈值处理:
import cv2
import numpy as np
cat=cv2.imread("cat_gray.jpg")
retval,binary=cv2.threshold(cat,127,255,cv2.THRESH_TRUNC)
cv2.imshow("cat",cat)
cv2.imshow("binary",binary)
cv2.waitKey(0)
cv2.destroyAllWindows()
运行结果:
4.对图像进行超阈值置零处理
import cv2
import numpy as np
cat=cv2.imread("cat_gray.jpg")
retval,binary=cv2.threshold(cat,127,255,cv2.THRESH_TOZERO_INV)
cv2.imshow("cat",cat)
cv2.imshow("binary",binary)
cv2.waitKey(0)
cv2.destroyAllWindows()
运行结果:
5.对图像进行低阈值置零处理:
import cv2
import numpy as np
cat=cv2.imread("cat_gray.jpg")
retval,binary=cv2.threshold(cat,127,255,cv2.THRESH_TOZERO)
cv2.imshow("cat",cat)
cv2.imshow("binary",binary)
cv2.waitKey(0)
cv2.destroyAllWindows()
运行结果:
二.自适应阈值处理
对于色彩分布不均匀的图像,仅仅使用一个阈值来进行处理是无法得到清晰的图像,此时阈值应随像素点周围像素值的具体情况来进行选取。opencv提供了自适应阈值处理函数cv2.adaptiveThreshold(),其原理为计算每个像素点领域像素加权平均值来得到对应的阈值。
其语法格式:
dst=cv2.adaptiveThreshold(src,maxValue,adaptiveMethod,thresholdType,blockSize,C)
参数说明:
dst:目标输出图像
src:原始输入图像
maxValue:代表最大值,与普通阈值函数中的maxval的含义相同。
adaptiveMethod:代表自适应方法
thresholdType:阈值处理方式,只能为cv2.THRESH_BINARY与cv2.THRESH_BINARY_INV中的一个。
blockSize:代表邻域大小。
C:常量
其计算不同点的阈值是根据参数adaptiveMethod来决定的,其一般有以下两种方式:
(1)cv2.ADAPTIVE_THRESH_MEAN_C:邻域内求平均值时,所有像素的权重一致。
(2)cv2.ADAPTIVE_THRESH_GAUSSIAN_C:与邻域内各点到中心点的距离有关,通过高斯方程计算个点的权重。
观察比较两种阈值方式对图像处理的差异:
import cv2
import numpy as np
cat=cv2.imread("cat_gray.jpg",cv2.IMREAD_GRAYSCALE)
retval,binary=cv2.threshold(cat,127,255,cv2.THRESH_BINARY)
binary1=cv2.adaptiveThreshold(cat,255,cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY,5,3)
binary2=cv2.adaptiveThreshold(cat,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,5,3)
cv2.imshow("cat",cat)
cv2.imshow("binary",binary)
cv2.imshow("binary1",binary1)
cv2.imshow("binary2",binary2)
cv2.waitKey(0)
cv2.destroyAllWindows()
print(retval)
运行结果:
观察发现使用自适应阈值处理,得到的图像保留的细节更多。
三.Otsu处理
在普通阈值处理中,阈值是我们自己预先设定的,但我们肉眼观察图像像素值的分布,所找出的那个阈值并不是最优的,有时甚至阈值的结果比较差,此时使用Otsu算法,其是通过遍历尝试所有可能的阈值,最终找出最优的那个。我们只需将阈值类型设为cv2.THRESH_OTSU即可,注意此时的阈值thresh一定要设为0
比较人为设定阈值与通过Otsu算法设定阈值的处理效果:
import cv2
import numpy as np
cat=cv2.imread("cat_gray.jpg",cv2.IMREAD_GRAYSCALE)
#人为设定阈值为127
retval,binary=cv2.threshold(cat,127,255,cv2.THRESH_BINARY)
#使用Otsu得到最优阈值
best,binary1=cv2.threshold(cat,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
cv2.imshow("cat",cat)
cv2.imshow("binary",binary)
cv2.imshow("binary1",binary1)
cv2.waitKey(0)
cv2.destroyAllWindows()
print(best)
运行结果: