目的:主要是去除图像中的高频成分(如噪音、边界),出发点往往是去除噪音信号,但处理过程中也会模糊边界。
OpenCV中常用的几种模糊技术:
1.平均
import cv2
from matplotlib import pyplot as plt
import pylab
pylab.rcParams['figure.figsize'] = (25.0, 12.0) # 显示大小
img=cv2.imread('building.jpg')
#注意:当用OpenCV读取彩色图像时,OpenCV是以(BGR)的顺序存储图像数据的,而Matplotlib是以(RGB)的顺序显示图像的
b,g,r = cv2.split(img)
img = cv2.merge([r,g,b])
#均值滤波,可以采用3×3或者5×5的卷积框,实验发现3×3效果不明显
blurImg=cv2.blur(img,(5,5))
#boxFilter()其中normalize=False
boxBlurImg=cv2.boxFilter(img,-1,(3,3),normalize=False)
plt.subplot(131),plt.imshow(img),plt.title('original image')
#plt.xticks([]),plt.yticks([])用来设置坐标轴显示
plt.subplot(132),plt.imshow(blurImg),plt.title('after blur')
plt.xticks([]),plt.yticks([])
plt.subplot(133),plt.imshow(boxBlurImg),plt.title('unnormalized blur')
plt.xticks([]),plt.yticks([])
plt.savefig('blurResult.png')#保存实验结果
plt.show()
2.高斯滤波
原卷积框大小不变,将其值的大小改为符合高斯分布(正态分布),方框中心值最大,将原来求平均值变为求加权平均值,卷积框的行、列必须是奇数。函数cv2.GaussianBlur(),高斯滤波能够有效去除高斯噪音。
3.中值滤波
利用区域像素的中值来替代中心像素的值,有效去除椒盐噪音,随机噪音,函数cv2.medianBlur(img,5)
4. 双边滤波
能够在保持边界清晰的情况下来有效去除噪音(相对其他滤波要慢一点),使用空间高斯权重(只有空间离中心像素点近的像素点权重大)和灰度值相似性高斯权重(只有灰度值与中心相似性高的像素才会用来做模糊运算)函数cv2.bilateralFilter(src,d,sigmaColor,sigmaSpace),
其中 d表示在过滤过程中每个像素邻域的直径范围,如果这个值是非正数,则函数会从第五个参数sigmaSpace计算该值;
(double) sigmaColor: 颜色空间过滤器的sigma值,这个参数的值月大,表明该像素邻域内有月宽广的颜色会被混合到一起,产生较大的半相等颜色区域;
(double) sigmaSpace: 坐标空间中滤波器的sigma值,如果该值较大,则意味着颜色相近的较远的像素将相互影响,从而使更大的区域中足够相似的颜色获取相同的颜色,当d>0时,d指定了邻域大小且与sigmaSpace五官,否则d正比于sigmaSpace.
对于简单的滤波而言,可以将两个sigma值设置成相同的值,如果值<10,则对滤波器影响很小,如果值>150则会对滤波器产生较大的影响,会使图片看起来像卡通,调整适当的参数,可以起到美颜效果。参考链接。
实验效果:
相关代码主要在于添加椒盐噪声和高斯噪声,其中关于高斯噪声部分由于方法的原因,做出的效果和Matlab自带的imnoise()函数中的高斯噪声效果不一样,本次采用的相关资源[链接]。比较有趣的是双边滤波部分,适当的调节参数堪比美图秀秀,当然还是比较单调的修饰,主要起到的效果是使图像看上去更加朦胧,可以做一个动态调节参数的,类似这样(参考资源,不得不说被该作者的实验效果吓到了)。
附上添加噪声部分代码:
#添加椒盐噪音
def addSaltNoise(src,n=10000):
dst=src.copy()
row,col,channels=src.shape
for k in range(n):
#随机选取位置
i=random.randint(0,row-1)
j=random.randint(0,col-1)
if channels==1:
dst[i,j]=255#盐噪音
else:
dst[i,j,:]=255
for k in range(n):
i=random.randint(0,row-1)
j=random.randint(0,col-1)
if channels==1:
dst[i,j]=0#椒噪音
else:
dst[i,j,:]=0
return dst
#产生高斯噪音
def addGaussianNoise(src,miu=0.1,sigma=0.01):
#miu为正态分布的均值,sigma为方差,N(μ,σ^2),当μ = 0,σ = 1时的正态分布是标准正态分布
dst=src.copy()
row,col,_=src.shape
#r通道
r=src[:,:,0].flatten()
#g通道
g=src[:,:,1].flatten()
#b通道
b=src[:,:,2].flatten()
#计算新的像素值
for i in range(row*col):
pr=int(r[i])+random.gauss(miu,sigma)
pg=int(g[i])+random.gauss(miu,sigma)
pb=int(b[i])+random.gauss(miu,sigma)
if pr<0:
pr=0
elif pr >255:
pr=255
if pg<0:
pg=0
elif pg >255:
pg=255
if pb<0:
pb=0
elif pb >255:
pb=255
r[i]=pr
g[i]=pg
b[i]=pb
dst[:,:,0]=r.reshape(row,col)
dst[:,:,1]=g.reshape(row,col)
dst[:,:,2]=b.reshape(row,col)
return dst
参考文献:OpenCV官方教程中文版(for python)