4.opencv——图像变换2(图像模糊-均值滤波,高斯滤波,中值滤波,方框,双边滤波,2D卷积)

图像模糊

\qquad 图像模糊也称图像平滑处理,它主要处理图像中与周围差异较大的点,将其像素值调整为与周围点像素值近似的值,其目的主要是消除图像噪声和边缘。线性的平滑滤波可以有效地消除噪声,但同时将使图像中的细节产生模糊,清晰度下降,低通滤波效应明显。非线性平滑滤波可以在消除图像孤立噪声的同时,较好地保持图像的细节信息。

均值滤波

\qquad 均值滤波是指以当前点为中心点,用其周围N × \times ×N个点的像素值的平均值来代替当前这个点的像素值。用于计算平均值的N × \times ×N个点称为邻域,用于滤波计算的卷积大小与邻域相同。举个例子,一个大小为 3 × 3 3\times3 3×3的邻域如下图
在这里插入图片描述
则卷积核为:
1 3 × 3 [ 1 1 1 1 1 1 1 1 1 ] \frac{1}{3\times3} \quad \left[ \begin{matrix} 1 & 1 & 1 \\ 1 & 1 & 1 \\ 1 & 1 & 1 \\ \end{matrix} \right] 3×31111111111
则中心点的均值滤波值=(125+132+124+67+251+123+113+142+102)÷9=120,120比251 更接近周围的值,所以用120替换251。
OpenCV 的 cv2.blur()函数用于实现均值滤波,其基本格式如下:

dst=cv2.blur(src,ksize [,anchor [,borderType]])

其参数说明如下:

参数 说明
dst 为滤波结果图像
src 为原图像
ksize 为卷积核大小,表示为(width,height), width 和 height 通常设置为相同值,且为正数和奇数
anchor 为锚点,默认值为(-1,-1),表示锚点位于卷积核中心
borderType 为边界值处理方式
import cv2


img = cv2.imread('lena2.jpg')
cv2.imshow('img', img)
img2 = cv2.blur(img, (5, 5))		# 可调整卷积核大小查看不同效果
cv2.imshow('imgBlur', img2)
cv2.waitKey(0)

在这里插入图片描述

高斯滤波

高斯滤波与均值滤波略有不同,它按像素点与中心点的不同距离,赋予像素点不同的权重值,越靠近中心点权重值越大,越远离中心点权重值越小;然后根据权重值计算邻域内所有像素点的和,将和作为中心点的像素值。
常用的高斯卷积核有以下两种:
1 16 [ 1 2 1 2 4 2 1 2 1 ] \frac{1}{16} \quad \left[ \begin{matrix} 1 & 2 & 1 \\ 2 & 4 & 2\\ 1 & 2 & 1 \\ \end{matrix} \right] 161121242121
1 273 [ 1 4 7 4 1 4 16 26 16 4 7 26 41 26 7 4 16 26 16 4 1 4 7 4 1 ] \frac{1}{273} \quad \left[ \begin{matrix} 1 & 4 & 7&4&1 \\ 4 & 16 & 26&16&4\\ 7 & 26 & 41&26&7 \\ 4 & 16 & 26&16&4\\ 1 & 4 & 7&4&1 \\ \end{matrix} \right] 27311474141626164726412674162616414741
这两种高斯卷积核是如何得来的呢?其实是通过高斯函数计算出来的,公式如下:
G ( x , y ) = 1 2 π σ 2 e − x 2 + y 2 2 σ 2 G(x,y) = \frac{1}{2\pi\sigma^2} \quad e^- \frac{x^2+y^2}{2\sigma^2} \quad G(x,y)=2πσ21e2σ2x2+y2

以3 × 3的高斯卷积核为例,以模板的中心位置为坐标原点进行取样。模板在各个位置的坐标,如下所示(x轴水平向右,y轴竖直向上)。

在这里插入图片描述

这样,将各个位置的坐标带入到高斯函数G中,得到的每个值按照位置排列,就得到了高斯卷积核。

这样输出的高斯卷积核有两种形式:

① 小数类型:直接计算得到的值,没有经过任何处理。

② 整数类型:将得到的值进行归一化处理,即将坐上叫的值归一化为1,其他每个系数都除以左上角的系数,然后取整。在使用整数模板时,则需要在模板的前面加一个系数,该系数为模板系数之和的倒数。(上面的就是整数类型)

例如:生成高斯卷积核为3 × 3,σ = 0.8的模板

小数模板:

在这里插入图片描述

整数模板:

在这里插入图片描述
再经过四舍五入和添加系数得到最终结果:
1 16 [ 1 2 1 2 4 2 1 2 1 ] \frac{1}{16} \quad \left[ \begin{matrix} 1 & 2 & 1 \\ 2 & 4 & 2\\ 1 & 2 & 1 \\ \end{matrix} \right] 161121242121

OpenCV 的 cv2.GaussianBlur()函数用于实现高斯滤波,其基本格式如下:

dst=cv2.GaussianBlur(src,ksize,SigmaX [,sigmaY [,borderType]]

参数说明如下:

参数 说明
sigmaX 为水平方向上的权重值
sigmaY 为垂直方向上的权重值
其他参数 含义和 cv2.blur)函数中的一致

如果 sigmaY 为0,则令其等于 sigmaX;如果sigmaX 和 sigmaY 均为0,则按下面的公式计算其值,其中 ksize 为(width,height)。

sigmaX = 0.3×((width-1)×0.5-1)+0.8
sigmar = 0.3×((height-1)×0.5-1)+0.8
import cv2


img = cv2.imread('lena2.jpg')
cv2.imshow('img', img)
img2 = cv2.GaussianBlur(img, (51, 51), 0, 0)  # 可调整卷积核大小查看不同效果
cv2.imshow('imgBlur', img2)
cv2.waitKey(0)

在这里插入图片描述

方框滤波

方框滤波以均值滤波为基础,可选择是否对滤波结果进行归一化。如果选择进行归一化,则滤波结果为邻域内点的像素值之和的平均值,否则滤波结果为像素值之和。
OpencV 的cv2.boxFilter()函数用于实现方框滤波,其基本格式如下。

dst=cv2.boxFilter(snc,ddepth,ksize[,anchor[,normalize[,bordertype]]])

其参数说明如下:

参数 说明
ddepth 为目标图像的深度,一般使用-1 表示与原图像的深度一致
normalize 为 True(默认值)时执行归一化操作,为 False 时不执行归一化操作
其他参数含义 和 cv2.blur()函数中的一致
import cv2


img = cv2.imread('lena2.jpg')
cv2.imshow('img', img) 
img2 = cv2.boxFilter(img, -1, (7, 7), normalize=True)   # 可调整卷积核大小查看不同效果
cv2.imshow('imgBlur', img2)
cv2.waitKey(0)

在这里插入图片描述

中值滤波

中值滤波将邻域内的所有像素值排序,取中间值作为邻域中心点的像素值。其设计思想是使拥有不同像素点的值看起来更接近它的邻域值,因为噪声的出现,使该点像素比周围的像素亮(暗)许多,中值滤波是给出滤波用的模板,对模板中的像素值由小到大排列,最终待处理像素的灰度取这个模板中的灰度的中值。在一定条件下,中值滤波可以克服线性滤波器所带来的图像细节模糊,而且对滤除脉冲干扰及颗粒噪声最为有效。但是对一些细节多,特别是点、线、尖顶细节多的图像则不宜采用中值滤波的方法。
中值滤波的步骤
(1)模板在图中漫游,模板中心与图中某个像素位置重合。
(2)读取模板中各个对应像素值。
(3)将这些像素值从小到大排成一列。
(4)找出这些值里排在中间的一个。
(5)将这个中间值赋给当前对应模板中心位置的像素。

OpenCV 的 cv2.medianBilur()函数用于实现中值滤波,其基本格式如下。

dst=cv2.medianBlur(src,ksize)

其中,ksize 表示卷积核大小,必须是大于 1 的奇数。

import cv2


img = cv2.imread('lena2.jpg')
cv2.imshow('img', img) 
img2 = cv2.medianBlur(img, 5)   # 可调整卷积核大小查看不同效果
cv2.imshow('imgBlur', img2)
cv2.waitKey(0)

在这里插入图片描述

双边滤波

双边滤波在计算像素值的同时会考虑距离和色差信息,从而可在消除噪声的同时保护边缘信息。在执行双边滤波操作时,如果像素点与当前点色差较小,则赋予其较大的权重值,否则赋予其较小的权重值。
OpenCV 的 cv2.bilateralFflter()函数用于实现双边滤波,其基本格式如下:

dst=cv2.bilateralFilter(snc,d,sigmacolor,sigmaSpace[,borderType])

其参数说明如下:

参数 说明
d 表示以当前点为中心的邻域的直径,一般为 5
sigmaColor 为双边滤波选择的色差范围
sigmaSpace 为空间坐标中的 sigma值,值越大表示越多的像素点参与滤波计算。当d>0时,忽略 sigmaSpace,由d决定邻域大小;否则d 由 sigmaSpace 计算得出,与 sigmaSpace 成比例
import numpy as np
import cv2


img = cv2.imread('lena2.jpg')
cv2.imshow('img', img) 
img2 = cv2.bilateralFilter(img, 50, 50, 50)  # 可调整参数查看不同效果
cv2.imshow('imgBlur', img2)
cv2.waitKey(0)

在这里插入图片描述

2D卷积

均值滤波、高斯滤波、方框滤波、中值滤波和双边滤波等可以通过参数柬碩定卷积核,2D 卷积可使用自定义的卷积核来执行滤波操作。
OpenCV的 cv2.filter2D()函数用于实现 2D 卷积,其基本格式如下:

dst=cv2.filter2D(src,ddepth,kennel[,anchor[,delta[,bondenType]]])

其参数说明如下:

参数 说明
ddepth 表示目标图像 dst 的深度,一般使用-1 表示与原图像 SrC一致
kernel 为单通道卷积核(一维数组))
anchor 为图像处理的锚点
delta 为修正值,未省略时,将加上该值作为最终的滤波结果
borderType 为边界值处理方式
import numpy as np
import cv2


img = cv2.imread('lena2.jpg')
k1 = np.array([[3, 3, 3, 3, 3],
               [3, 9, 9, 9, 3],
               [3, 11, 12, 13, 3],
               [3, 8, 8, 8, 3],
               [3, 3, 3, 3, 3], ])/25   # 自定义卷积核1
k2 = np.ones((5, 5), np.float32)/25     # 自定义卷积核2
img2 = cv2.filter2D(img, -1, k1)
cv2.imshow('imgK1', img2)
img2 = cv2.filter2D(img, -1, k2)
cv2.imshow('imgK2', img2)
cv2.waitKey(0)

在这里插入图片描述

方法对比和总结

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_47166032/article/details/120656456