通过将图像与低通滤波器内核进行2D卷积来实现图像模糊。这对于消除噪音很有用。它实际上从图像中消除了高频部分(例如噪声,边缘)。因此,在此操作中边缘有些模糊。(有一些模糊技术也可以不模糊边缘)。OpenCV主要提供四种类型的模糊技术:均值模糊、高斯模糊、中值模糊和双边滤波模糊。
当我们只想得到感兴趣的物体时,通过图像模糊,可以将那些尺寸和亮度较小的物体过滤掉,较大的物体则易于检测。除了降低噪声,这就是图像平滑(模糊)的另一个重要应用:减少噪点,突出ROI,以便目标提取。
均值模糊原理很简单,就是将将中心像素点周围的值累加,然后平均,去替代中心像素的值
假设有这么一块区域:
[ 20 18 19 9 2 7 15 12 24 ] \begin{bmatrix} 20&18&19\\ 9&2&7\\ 15&12&24\\ \end{bmatrix} ⎣⎡209151821219724⎦⎤
那么,新的中心像素为:
20 + 18 + 19 + 9 + 2 + 7 + 15 + 12 + 24 = 126 126 9 = 14 20+18+19+9+2+7+15+12+24=126 \\ \frac{126}{9}=14 20+18+19+9+2+7+15+12+24=1269126=14
所以经过均值模糊后新的图像区域为
[ 20 18 19 9 14 7 15 12 24 ] \begin{bmatrix} 20&18&19\\ 9&14&7\\ 15&12&24\\ \end{bmatrix} ⎣⎡2091518141219724⎦⎤
均值模糊适用性很广,运行速度快,但效果较差
高斯模糊,通过二维高斯函数,根据已定义的卷积核半径,正态分布计算出一个卷积核,再对目标图像进行2D卷积,实现高斯模糊
高斯模糊实质上就是一种高级的均值模糊,只是高斯模糊是按照加权平均的,距离越近的点权重越大,距离越远的点权重越小,每一个中心像素都由其本身和邻域内的其他像素值经过加权平均后得到。
f ( x ) = 1 2 π σ e − ( x − u ) 2 2 σ 2 f(x) = \frac{1}{\sqrt{2\pi\\}\sigma\\}e^{-\frac{(x-u)^2}{2\sigma\\^2}} f(x)=2πσ1e−2σ2(x−u)2
可以通过一维函数推导得到二维高斯函数
f ( x , y ) = 1 2 π σ 2 e − ( x 2 + y 2 ) 2 2 σ 2 ( σ 是 x 的 方 差 , x , y 是 坐 标 ) f(x,y) = \frac{1}{{2\pi\\}\sigma\\^2}e^{-\frac{(x^2+y^2)^2}{2\sigma\\^2}} \ \ \ \ \ (\sigma是x的方差,x,y是坐标) f(x,y)=2πσ21e−2σ2(x2+y2)2 (σ是x的方差,x,y是坐标)
注意是以中心点为原点,所以中心点的坐标为(0,0)、
在一维高斯函数中,u是x的平均值,故u=0
根据预设的卷积核半径,二维高斯函数可得2D卷积核,然后再扔进图像里进行加权运算
注意:整个卷积核的总和应该等于1。若大于1,图像变亮;小于1,图像变暗。
高斯模糊对高斯噪声具有良好的模糊效果,那高斯噪声是什么呢?
以下代码给图像添加了高斯噪声:
import cv2
import numpy as np
def clamp(pv):
if pv > 255:
return 255
elif pv < 0:
return 0
else:
return pv
def gaussian_noise(image, mean=0, var=0.005):
image = np.array(image/255,dtype=float)
noise = np.random.normal(mean,var**0.5,image.shape)
out = image + noise
if out.min() < 0:
low_clip = -1.
else:
low_clip = 0.
out = np.clip(out,low_clip,1.0)
out = np.uint8(out*255)
return out
def nothing(pp):
pass
if __name__ == '__main__':
img = cv2.imread("s1.png")
cv2.namedWindow("Preview")
cv2.createTrackbar("mean","Preview",0,5,nothing)
cv2.createTrackbar("var","Preview",0,5,nothing)
while(1):
mean = cv2.getTrackbarPos("mean","Preview")
var = cv2.getTrackbarPos("var","Preview")
img_r = gaussian_noise(img,mean/10,var/100)
cv2.imshow("Result",img_r)
if cv2.waitKey(20) == ord('q'):
break
cv2.destroyAllWindows()
让我们看一下图片
高斯噪声,就是图像上红绿色的斑点
这里跑个题~
2008年家里有第一台电视机,TCL牌子的,每次下雨天,或者几条信号线接触不良的时候,就经常会出现这种红绿色的噪点,这就是高斯噪声。
然后,高斯模糊消除噪声
可见,噪声消除了,图片也模糊了
中值模糊可以有效消除椒盐噪声
那什么是椒盐噪声呢?
字面意思:椒就是花椒粒,黑色的,而盐是白色的
所以我得出:高斯噪声是红绿色的,呈点状;椒盐噪声是黑白色的,且呈粒状
大家可以观察下面两幅图像对比这两种噪声的区别
中值模糊之前讲过,有兴趣的可以自行查阅
CV7 中值滤波详解
在去除噪声的同时保持边缘清晰锐利非常有效。但是,与其他过滤器相比,该操作速度较慢。我们已经看到,高斯滤波器采用像素周围的邻域并找到其高斯加权平均值。高斯滤波器仅是空间的函数,也就是说,滤波时会考虑附近的像素。它不考虑像素是否具有几乎相同的强度。它不考虑像素是否是边缘像素。因此它也模糊了边缘,这是我们不想做的。
双边滤波器在空间中也采用高斯滤波器,但是又有一个高斯滤波器,它是像素差的函数。空间的高斯函数确保仅考虑附近像素的模糊,而强度差的高斯函数确保仅考虑强度与中心像素相似的那些像素的模糊。由于边缘的像素强度变化较大,因此可以保留边缘。
双边滤波就是更高一级的高斯滤波
双边模糊在模糊的同时,保持纹理。但计算机需耗费较多时间和资源去计算
简而言之,双边滤波可以给人像美白,广泛用于给小姐姐PS磨皮中[Doge]
不废话,直接上图片看效果
有点心动的感觉~~~
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('B1.png')
img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
# 1.均值模糊
# blur = cv2.blur(img,(5,5))
# 2.高斯模糊
# blur = cv2.GaussianBlur(img,(31,31),0)
# 3.中值模糊
# blur = cv2.medianBlur(img,5)
# 4.双边滤波模糊
blur = cv2.bilateralFilter(img,32,75,75)
plt.subplot(121),plt.imshow(img),plt.title('Original')
plt.xticks([]),plt.yticks([])
plt.subplot(122),plt.imshow(blur),plt.title('Blurred')
plt.xticks([]),plt.yticks([])
plt.show()
cv2.blur()函数
功能:均值滤波
输入参数:
- 图像名
- 卷积核半径
cv2.GaussianBlur()函数
功能:高斯模糊
输入参数:
- 图像名
- 高斯核的大小,格式为(width, height),其中 width 和 height 可以不同,两者都是正奇数;如果设为 0,则根据 输入参数3 得到。(数值越大,高斯模糊越强)
- x和y轴的标准差
cv2.bilateralFilter()函数
功能:双边滤波
输入参数:
图像名
滤波强度,数值太大图片易卡通化,不真实(一般d=5/9)
sigma参数A
sigma参数B
- 滤波强度
- 过大的滤波器(d>5)执行效率低
- 对于实时应用,建议取d=5
- 对于需要过滤严重噪声的离线应用,可取d=9
- sigma参数
- 简单起见,可以令2个sigma的值相等
- 如果他们很小(小于10),那么滤波器几乎没有什么效果
- 如果他们很大(大于150),那么滤波器的效果会很强,使图像显得非常卡通化
这几天会疯狂更,因为快开学了,到时候比赛+专业课,再学点东西都未必有时间了