怎么理解阈值处理?
阈值处理(Thresholding)是一种常用的图像处理技术,在机器学习和计算机视觉中经常被用于二值化图像或二分类任务。它基于设定一个阈值来将像素值进行分类,将像素值大于或小于阈值的部分分为两个不同的类别,从而得到二值化的图像或进行二分类预测。
在图像处理中的阈值处理:
图像二值化:将灰度图像转换为二值图像,其中像素值大于或等于阈值的部分设为一个值(通常为255),而小于阈值的部分设为另一个值(通常为0)。
自适应阈值处理:根据图像局部的灰度特点来自动调整不同区域的阈值,适应图像的不同部分。
在二分类任务中的阈值处理:
对于分类模型的输出概率:将模型输出的概率值与阈值进行比较,大于阈值的样本被划分为一个类别,小于阈值的样本被划分为另一个类别。
对于回归模型的输出:将模型输出的连续值与阈值进行比较,大于阈值的样本被划分为一个类别,小于阈值的样本被划分为另一个类别。
阈值处理的应用场景
- 图像二值化:将灰度图像转换为二值图像,常用于图像分割、边缘检测、形态学运算等图像处理任务。
- 自适应阈值处理:根据图像局部的灰度特点来自动调整不同区域的阈值,适应图像的不同部分。适用于光照不均匀或对比度变化较大的图像。
- 目标检测中的二分类:在目标检测任务中,通常需要将模型输出的概率值转换为二分类结果,判断目标是否存在。
- 人脸识别和人脸表情分析:在人脸图像处理中,可以通过阈值处理来检测和分析人脸的不同表情或情绪。
- 图像分割:将图像分为多个区域,常用于图像分析、目标提取和图像理解等任务。
- 文字识别和OCR(光学字符识别):在文字识别任务中,可以通过阈值处理将图像中的文字部分提取出来,便于后续识别过程。
- 遥感图像处理:在遥感图像中,阈值处理可以用于土地覆盖分类、植被检测等应用。
- 信号处理:在信号处理中,可以通过阈值处理来检测信号的起始点或结束点,以及滤除噪声。
- 异常检测:在异常检测任务中,可以使用阈值处理来识别异常点或异常事件。
- 机器学习中的二分类问题:在机器学习中,对于二分类任务,可以通过设定阈值来将模型输出的概率值转换为类别标签。
OpenCV 提供了函数 cv2.threshold()和函数 cv2.adaptiveThreshold(),用于实现阈值处理
threshold 函数
OpenCV 3.0 使用 cv2.threshold()函数进行阈值化处理,该函数的语法格式为:
retval, dst = cv2.threshold( src, thresh, maxval, type )
式中:
retval 代表返回的阈值。
dst 代表阈值分割结果图像,与原始图像具有相同的大小和类型。
src 代表要进行阈值分割的图像,可以是多通道的,8 位或 32 位浮点型数值。
thresh 代表要设定的阈值。
maxval 代表当 type 参数为 THRESH_BINARY 或者 THRESH_BINARY_INV 类型时,需要设定的最大值。
type 代表阈值分割的类型,具体类型值如表 6-1 所示。
上述公式相对抽象,可以将其可视化,具体如图 6-2 所示。
二值化阈值处理(cv2.THRESH_BINARY)
二值化阈值处理会将原始图像处理为仅有两个值的二值图像,其示意图如图 6-3 所示。其
针对像素点的处理方式为:
- 对于灰度值大于阈值thresh的像素点,将其灰度值设定为最大值。
- 对于灰度值小于或等于阈值thresh的像素点,将其灰度值设定为 0
如果使用表达式表示,其目标值的产生规则为:
式中,thresh是选定的特定阈值。
在 8 位图像中,最大值是 255。因此,在对 8 位灰度图像进行二值化时,如果将阈值设定
为 127,那么:
- 所有大于 127 的像素点会被处理为 255。
- 其余值会被处理为 0。
为了方便,在后续说明中,我们都以 8 位图像为例,即像素值最大值为 255。
实验:使用函数 cv2.threshold()对数组进行二值化阈值处理,观察处理结果
import cv2
import numpy as np
img=np.random.randint(0,256,size=[4,5],dtype=np.uint8)t,rst=cv2.threshold(img,127,255,cv2.THRESH_BINARY)
print("img=\n",img)
print("t=",t)
print("rst=\n",rst)
运行结果:
img=[[235 26 81 7 121][ 81 82 15 64 40][156 250 246 30 226][136 202 129 243 65]]
t= 127.0
rst=[[255 0 0 0 0][ 0 0 0 0 0][255 255 255 0 255][255 255 255 255 0]]
实验2:使用函数 cv2.threshold()对图像进行二值化阈值处理
import cv2
img=cv2.imread("lena.png")
#将图像转换为灰度图像
img=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
t,rst=cv2.threshold(img,127,255,cv2.THRESH_BINARY)
cv2.imshow("img",img)
cv2.imshow("rst",rst)
cv2.waitKey()
cv2.destroyAllWindows()
运行结果:
左图是原始图像,右图是二值化阈值处理结果。
反二值化阈值处理(cv2.THRESH_BINARY_INV)
反二值化阈值处理的结果也是仅有两个值的二值图像,与二值化阈值处理的区别在于,二
者对像素值的处理方式不同。反二值化阈值处理针对像素点的处理方式为:
对于灰度值大于阈值的像素点,将其值设定为 0。
对于灰度值小于或等于阈值的像素点,将其值设定为 255。
反二值化阈值处理方式的示意图如图 6-5 所示。
如果使用表达式来表示,其目标值的产生规则为:
式中,thresh 是选定的阈值.
实验3:使用函数 cv2.threshold()对数组进行反二值化阈值处理
import cv2
import numpy as np
img=np.random.randint(0,256,size=[4,5],dtype=np.uint8)
t,rst=cv2.threshold(img,127,255,cv2.THRESH_BINARY_INV)
print("img=\n",img)
print("t=",t)
print("rst=\n",rst)
运行程序,结果如下所示:
img=
[[ 56 64 150 48 41]
[108 165 112 213 110]
[122 244 10 213 46]
[247 30 90 0 26]]
t= 127.0
rst=
[[255 255 0 255 255]
[255 0 255 0 255]
[255 0 255 0 255]
[ 0 255 255 255 255]]
大于127的置为0,小于127的置为255
后面还有
截断阈值化处理(cv2.THRESH_TRUNC)
超阈值零处理(cv2.THRESH_TOZERO_INV)
低阈值零处理(cv2.THRESH_TOZERO)
感兴趣的同学自己去多实操几遍