在这一节中,我分析了关于openCV中的阈值操作,还有对于图像的平滑处理,实践了均值滤波、方框滤波、高斯滤波、中值滤波这几个滤波器对于一张带有噪音的图像处理。
function:
def threshold(src, thresh, maxval, type, dst=None):
对每个数组元素应用固定级别阈值。
该功能将固定级阈值应用于单通道阵列。该函数通常用于从灰度图像中获取双层(二进制)图像(cv :: compare也可用于此目的)
或用于消除噪声,即滤除太小或太小的像素很大的价值。函数支持几种类型的阈值处理。它们由类型参数确定。
此外,特殊值#THRESH_OTSU或#THRESH_TRIANGLE可以与上述值之一组合。
在这些情况下,函数使用Otsu或Triangle算法确定最佳阈值,并使用它而不是指定的阈值。该函数返回计算的阈值。
目前,Otsu和Triangle方法仅适用于8位图像。
参数
SRC 输入数组(单通道,8位或32位浮点)。
DST 输出与src大小和类型相同的数组。
THRESH 阈值。
MAXVAL 与THRESH_BINARY和THRESH_BINARY_INV阈值类型一起使用的最大值。
类型 阈值类型(参见cv :: ThresholdTypes)。
ThresholdTypes.
#ThresholdTypes的类型
二值化的操作类型,包含以下5种类型,
cv2.THRESH_BINARY 大于阈值会取值maxval 小于阈值取值0 亮越亮 暗越暗
cv2.THRESH_BINARY_INV 对THRESH_BINARY的取值方式翻转 亮变暗 暗变亮
cv2.THRESH_TRUNC 截断法,对于每一个像素点,大于阈值的一律取为阈值,小的不变 亮变暗 暗则暗
cv2.THRESH_TOZERO 大于阈值的不变,小于阈值的赋为0 亮则亮 暗更暗
cv2.THRESH_TOZERO_INV 对THRESH_TOZERO的取值方式翻转 亮变暗 暗则暗
Eg.
#阈值操作
#读取图片,并将其从BGR to RGB
img = cv2.cvtColor(cv2.imread('dog.jpg'),cv2.COLOR_BGR2RGB)
ret,thresh1 = cv2.threshold(img,127,255,cv2.THRESH_BINARY)
ret,thresh2 = cv2.threshold(img,127,255,cv2.THRESH_BINARY_INV)
ret,thresh3 = cv2.threshold(img,127,255,cv2.THRESH_TRUNC)
ret,thresh4 = cv2.threshold(img,127,255,cv2.THRESH_TOZERO)
ret,thresh5 = cv2.threshold(img,127,255,cv2.THRESH_TOZERO_INV)
titles = ['Original Image','BINARY','BINARY_INV','TRUNC','TOZERO','TOZERO_INV']
images = [img, thresh1, thresh2, thresh3, thresh4, thresh5]
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()
Image Smoothing:图像平滑是指用于突出图像的宽大区域、低频成分、主干部分或抑制图像噪声和干扰高频成分的图像处理方法,目的是使图像亮度平缓渐变,减小突变梯度,改善图像质量。
方法:插值方法,线性平滑方法,卷积法等等。
function
def blur(src, ksize, dst=None, anchor=None, borderType=None):
使用标准化的盒式过滤器平滑图像。
该函数使用此内核来平滑图像:
参数
SRC 输入图像; 它可以有任意数量的通道,这些通道是独立处理的,但深度应该是CV_8U,CV_16U,CV_16S,CV_32F或CV_64F。
DST 输出与src相同大小和类型的图像。
ksize 平滑内核大小。
anchor 锚点; 默认值Point(-1,-1)表示锚点位于内核中心。
borderType 外推图像时的像素填充模式,请参阅cv :: BorderTypes
Eg.
#图像平滑
#导入一张带有噪音的图像
img = cv2.imread('lena.jpg')
img1 = cv2.imread('lenaNoise.png')
img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
img1 = cv2.cvtColor(img1,cv2.COLOR_BGR2RGB)
plt.subplot(121)
plt.imshow(img)
plt.title('Original')
plt.subplot(122)
plt.imshow(img1)
plt.title('Noise lena')
plt.show()
#均值滤波操作
blur = cv2.blur(lenaNoise,(3,3))
plt.subplot(131)
plt.imshow(lena)
plt.title("Original")
plt.subplot(132)
plt.imshow(lenaNoise)
plt.title("Lena Noise")
plt.subplot(133)
plt.imshow(blur)
plt.title("After Blur")
plt.show()
1.The call blur(src, dst, ksize, anchor, borderType) is equivalent to boxFilter(src, dst, src.type(), anchor, true, borderType).
function
def boxFilter(src, ddepth, ksize, dst=None, anchor=None, normalize=None, borderType=None):
使用盒式过滤器来平滑图像。
该函数使用此内核平滑图像:
参数
SRC 输入图像。
DST 输出与src相同大小和类型的图像。
ddepth 输出图像深度(为-1时使用src.depth())。
ksize 平滑内核大小。
anchor 锚点; 默认值Point(-1,-1)表示锚点位于内核中心。
normalize 标签,指定内核是否按其区域进行规范化。
borderType 外推图像时的像素填充模式,请参阅cv :: BorderTypes
Eg.
#当ddepth指定为-1时,输出的图像大小与输入大小一致,normalize表示是否归一化
#当normalize指定为True的时候,其计算方式等同于blur
box = cv2.boxFilter(lenaNoise,-1,(3,3),normalize=True)
#当normalize指定为false,即不进行归一化,
#那么卷积过程中的像素点,会溢出,但不是饱和操作
box_unNormalize = cv2.boxFilter(lenaNoise,-1,(3,3),normalize=False)
#显示输出
plt.subplot(131)
plt.imshow(lenaNoise)
plt.title('Noise lena')
plt.subplot(132)
plt.imshow(box)
plt.title('box_Normalize')
plt.subplot(133)
plt.imshow(box_unNormalize)
plt.title('box_unNormalize')
plt.show()
Note.
1.非标准化盒式滤波器可用于计算每个像素邻域上的各种积分特性,例如图像导数的协方差矩阵(用于密集光流算法等)。
2.如果需要在可变大小的窗口上计算像素总和,请使用cv :: integral。
function
def GaussianBlur(src, ksize, sigmaX, dst=None, sigmaY=None, borderType=None):
使用高斯滤波器平滑图像。
该函数将源图像与指定的高斯内核进行卷积,支持就地过滤。
参数
SRC 输入图像; 图像可以有任意数量的通道,这些通道是独立处理的,但深度应该是CV_8U,CV_16U,CV_16S,CV_32F或CV_64F。
DST 输出与src相同大小和类型的图像。
ksize 高斯核大小。ksize.width和ksize.height可以不同,但它们都必须为正数且为奇。
或者,它们可以是零,然后它们是从sigma计算得到。
sigmaX X方向的高斯核标准偏差。
sigmaY Y方向的高斯核标准偏差; 如果sigmaY为零,则将其设置为等于sigmaX;
如果两个sigma均为零,则分别从ksize.width和ksize.height计算(详见cv :: getGaussianKernel);
为了完全控制结果,无论将来可能修改所有这些语义,建议指定所有ksize,sigmaX和sigmaY。
borderType 像素外推法,参见cv :: BorderTypes
Eg.
#高斯滤波
aussian = cv2.GaussianBlur(lenaNoise,(3,3),1)
#显示输出
plt.subplot(121)
plt.imshow(lenaNoise)
plt.title('lenaNoise')
plt.subplot(122)
plt.imshow(aussian)
plt.title('aussian')
plt.show()
function
def getGaussianKernel(ksize, sigma, ktype=None):
返回高斯滤波器系数。
该函数计算并返回高斯滤波器系数的?????×1矩阵:
其中两个生成的内核可以传递给sepFilter2D。
这些函数自动识别平滑内核(一个权重总和等于1的对称内核)并相应地处理它们。 您也可以使用更高级别的GaussianBlur。
function
def medianBlur(src, ksize, dst=None):
使用中值滤波器平滑图像。
该功能使用具有?????×????? aperture 的中值滤波器平滑图像。
多通道图像的每个通道都是独立处理的,支持就地过滤。
参数
SRC 输入1,3或4通道图像; 当ksize为3或5时,图像深度应为CV_8U,CV_16U或CV_32F,对于较大的光圈尺寸,它只能是CV_8U。
DST 与src具有相同大小和类型的目标数组。
ksize aperture linear size; 它必须是奇数且大于1,例如:3,5,7 ......
Eg.
#中值滤波
median = cv2.medianBlur(lenaNoise,3)
#显示输出
plt.subplot(121)
plt.imshow(lenaNoise)
plt.title('lenaNoise')
plt.subplot(122)
plt.imshow(median)
plt.title('median')
plt.show()
Note.
1.中值过滤器在内部使用BORDER_REPLICATE来处理边界像素,请参阅cv :: BorderTypes
Eg.
#几种不同的滤波器
blur = cv2.blur(lenaNoise,(3,3))
box = cv2.boxFilter(lenaNoise,-1,(3,3),normalize=True)
aussian = cv2.GaussianBlur(lenaNoise,(3,3),1)
median = cv2.medianBlur(lenaNoise,3)
#显示输出
plt.subplot(221)
plt.imshow(lenaNoise)
plt.title('Noise lena')
plt.subplot(222)
plt.imshow(box)
plt.title('boxFilter')
plt.subplot(223)
plt.imshow(aussian)
plt.title('GaussianBlur')
plt.subplot(224)
plt.imshow(median)
plt.title('medianBlur')
plt.show()
Note.
1.因为,均值滤波等同于标准化的boxfilter,所以没有在上图加入均值滤波的比较。
2.目前来看,中值滤波表现最佳。
1.之前一直没有怎么关心API里面体现的 In-place filtering is supported 是什么意思,于是研究了并记录一下。
in-place操作,意思是所有的操作都是”就地“操作,不允许进行移动,或者称作 原位操作,即不允许使用临时变量。
所以在滤波中的过滤操作(暂且都认为是卷积操作),“就地过滤”应该是指,卷积过程中不使用临时变量,通过加减、位运算来实现。
END