图像平滑(模糊)

目的:主要是去除图像中的高频成分(如噪音、边界),出发点往往是去除噪音信号,但处理过程中也会模糊边界。

OpenCV中常用的几种模糊技术:

1.平均

利用卷积框覆盖区域所有像素的平均值来代替中心位置像素值,通常使用cv2.blur()或者cv2.boxFilter()来完成,其中前者是一个归一化卷积框(核所有元素和为1),后者则可以不用归一化卷积框,需要传入参数normalize=False,此时,核的系数就不再是1/9,而是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则会对滤波器产生较大的影响,会使图片看起来像卡通,调整适当的参数,可以起到美颜效果。参考链接

实验效果:

从左至右从上至下依次为:1)加高斯噪音,2)加椒盐噪音,3)双边滤波,4)高斯滤波,5)中值滤波,6)不同参数的双边滤波

相关代码主要在于添加椒盐噪声和高斯噪声,其中关于高斯噪声部分由于方法的原因,做出的效果和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)


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值