图像分类
安装颜色对图像进行分类,可以分为二值图像,灰度图像和彩色图像。
- 二值图像:只有黑色和白色两种颜色的图像。每个像素点可以用0/1表示,0表示黑色,1表示白色。
- 灰度图像:只有灰度的图像。每个像素点用8bit数字[0,255]表示灰度,如:0表示纯黑,255表示纯白。
- 彩色图像:彩色图像通常采用红色(R),绿色(G)和蓝色(B)三个彩色通道的组合表示。
简单阈值
对于每个像素,应用相同的阈值。如果像素值小于阈值,则将其设置为0,否则将其设置为最大值。
cv.threshold(src,thresh,maxval,type,dst)
- src:变换操作的输入图像,ndarray二维数组,必须是单通道灰度图像。
- thresh:阈值,取值范围0~255.
- maxval:填充色,取值范围0~255,一般取255.
- type:变换类型
- dst:返回阈值变换的输出图像。
type值说明
- cv.THRESH_BINARY:表示大于阈值时置255,否则置0.
- cv.THRESH_BINARY_INV:表示大于阈值时置0,否则置255.
- cv.THRESH_TRUNC:表示大于阈值时置为阈值thresh,否则不变(保持原色)
- cv.THRESH_TOZERO:表示大于阈值时不变(保持原色),否则置0。
- cv.THRESH_TOZERO_INV:表示大于阈值时置0,否则不变(保持原色)。
- cv.THRESH_OTSU:表示使用OTSU算法选择阈值。
import cv2 as cv from matplotlib import pyplot as plt img=cv.imread('./images/lena.jpeg',0) ret,binary=cv.threshold(img,127,255,cv.THRESH_BINARY) ret,binary_inv=cv.threshold(img,127,255,cv.THRESH_BINARY_INV) ret,trunc=cv.threshold(img,127,255,cv.THRESH_TRUNC) ret,tozero=cv.threshold(img,127,255,cv.THRESH_TOZERO) ret,tozero_inv=cv.threshold(img,127,255,cv.THRESH_TOZERO_INV) titles=["original","binary","binary_inv","trunc","tozero","tozero_inv"] images=[img,binary,binary_inv,trunc,tozero,tozero_inv] for i in range(6): plt.subplot(2,3,i+1) plt.imshow(images[i],'gray') plt.title(titles[i]) plt.xticks([]) plt.yticks([]) plt.show()
结果:

自适应阈值
上面使用全局值作为阈值,可能并非所用情况都很好。如果图像在不同区域具有不同的光照条件。在这种情况下,自适应阈值可以提供帮助。在此,算法基于像素周围的小区域确定像素的阈值。因此,对于同一图像的不同区域,获得不同的阈值,这为光照强度变换的图像提供了更好的结果。
除了上述参数外,方法cv.adaptiveThreshold还包括三个输入参数:
adaptiveMethod:指定计算阈值的方法
- cv.ADAPTIVE_THRESH_MEAN_C:阈值取自相邻区域的平均值。
- cv.ADAPTIVE_THRESH_GAUSSIAN_C:阈值取自相邻区域的加权和,权重为一个高斯窗口。
Block Size:领域大小(用来计算阈值的区域大小)
C:这就是一个常数,阈值就等于平均值或者加权平均值减去这个常数。
import cv2 as cv import matplotlib.pyplot as plt img=cv.imread('./images/lena.jpeg',0) img=cv.medianBlur(img,5) ret,thresh1=cv.threshold(img,127,255,cv.THRESH_BINARY) thresh2=cv.adaptiveThreshold(img,255,cv.ADAPTIVE_THRESH_MEAN_C,cv.THRESH_BINARY,11,2) thresh3=cv.adaptiveThreshold(img,255,cv.ADAPTIVE_THRESH_GAUSSIAN_C,cv.THRESH_BINARY,11,2) titles=["original","binary(v=127)","adaptive mean","adaptive gaussian"] images=[img,thresh1,thresh2,thresh3] 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()
结果:

Otsu的二值化
在全局阈值化中,使用任意选择的值作为阈值。相反,Otsu的方法避免了必须选择一个值并自动确定它的情况。
考虑仅具有两个不同图像值的图像(双峰图像),其中直方图将仅包含两个峰。一个好的阈值应该在这两个值的中间。类似地,Otsu的方法从图像直方图中确定最佳全局阈值。
在第一种情况下,采用值为127的全局阈值。在第二种情况下,直接采用Otsu阈值法。在第三种情况下,首先使用5x5高斯核对图像进行滤波以去除噪声,然后应用Otsu阈值处理。
import cv2 as cv from matplotlib import pyplot as plt img=cv.imread('./images/lena.jpeg',0) # 全局阈值 ret1,th1=cv.threshold(img,127,255,cv.THRESH_BINARY) # Otsu阈值 ret2,th2=cv.threshold(img,0,255,cv.THRESH_BINARY+cv.THRESH_OTSU) # 高斯滤波后在采用Otsu阈值 blur=cv.GaussianBlur(img,(5,5),0) ret3,th3=cv.threshold(img,0,255,cv.THRESH_BINARY+cv.THRESH_OTSU) images=[img,0,th1, img,0,th2, blur,0,th3] titles=["original","histogram","global thresholdding(v=127)", "original","histogram","otsu's thresholding", "gaussian filter","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()
posted on
浙公网安备 33010602011771号