【OpenCV-Python】:基于均值、中值、方框、双边和高斯滤波的图像去噪

✨博客主页:王乐予🎈
✨年轻人要:Living for the moment(活在当下)!💪
🏆推荐专栏:【图像处理】【千锤百炼Python】【深度学习】【排序算法

本节将对经过噪声污染的图像进行去噪,去噪方法包含均值滤波、中值滤波、方框滤波、双边滤波和高斯滤波

😺一、引言

🐶1.1 图像用例

实验所用的图像为【OpenCV-Python】:对图像添加高斯噪声与椒盐噪声中得到的均值为0,方差为0.01的高斯噪声污染图像和噪声密度为0.05的椒盐噪声污染图像,如图所示:
在这里插入图片描述

🐶1.2 评价指标

为了评判去噪质量的好坏,我们将选取PSNR、SSIM和MSE作为评价指标!

评价指标见:【OpenCV-Python】:图像PSNR、SSIM、MSE计算

🐶1.3 定义图像质量评价函数

def compare(ori, gaussian_denosing, sp_denosing):

    # ori为原图(未被噪声污染的图),gaussian_denosing为经过高斯噪声污染的图通过去噪算法去噪后的图;sp_denosing为经过椒盐噪声污染的图通过去噪算法去噪后的图
    gaussian_psnr = compare_psnr(ori, gaussian_denosing)
    sp_psnr = compare_psnr(ori, sp_denosing)

    gaussian_ssim = compare_ssim(ori, gaussian_denosing, multichannel=True)
    sp_ssim = compare_ssim(ori, sp_denosing, multichannel=True)

    gaussian_mse = compare_mse(ori, gaussian_denosing)
    sp_mse = compare_mse(ori, sp_denosing)

    return gaussian_psnr, sp_psnr, gaussian_ssim, sp_ssim, gaussian_mse, sp_mse

😺二、均值滤波

🐶2.1 滤波原理

均值滤波也称线性滤波,它是指使用一个模板在原图上进行均值计算并替换原图的值。

均值滤波器的模板有标准像素平均和加权平均之分,一个 3 × 3 3×3 3×3大小的模板如下图所示:
在这里插入图片描述

🐶2.2 实验过程

使用函数:cv2.blur()

🦄2.2.1 程序设计

"""
均值滤波
"""
gaussian_blur = cv2.blur(gaussian_img, (3, 3))
sp_blur = cv2.blur(sp_img, (3, 3))
h1 = np.hstack([gaussian_img, gaussian_blur])
h2 = np.hstack([sp_img, sp_blur])
v = np.vstack([h1, h2])
cv2.imshow('out', v)
cv2.waitKey()

🦄2.2.2 实验结果

在这里插入图片描述

  • 第一幅图为被高斯噪声污染的图像;
  • 第二幅图为使用均值滤波对第一幅图去噪后的图像;
  • 第三幅图为被椒盐噪声污染的图像;
  • 第四幅图为使用均值滤波对第三幅图去噪后的图像。

🦄2.2.3 指标参数

gaussian_psnr, sp_psnr, gaussian_ssim, sp_ssim, gaussian_mse, sp_mse = compare(original, gaussian_blur, sp_blur)
print('均值滤波对高斯噪声污染图像去噪后的指标为:PSNR:{},SSIM:{},MSE:{}'.format(gaussian_psnr, gaussian_ssim, gaussian_mse))
print('均值滤波对椒盐噪声污染图像去噪后的指标为:PSNR:{},SSIM:{},MSE:{}'.format(sp_psnr, sp_ssim, sp_mse))

结果为:

均值滤波对高斯噪声污染图像去噪后的指标为:PSNR:27.51495578617511,SSIM:0.7044879580272968,MSE:115.23509979248047
均值滤波对椒盐噪声污染图像去噪后的指标为:PSNR:25.66665449076371,SSIM:0.5821969899711158,MSE:176.36601893107095

从指标结果可以看出,均值滤波对高斯噪声的去除能力更强!

😺三、中值滤波

🐶3.1 滤波原理

中值滤波是把图像中的一点用该点的一个邻域中的各值的中值代替。

🐶3.2 实验过程

使用函数:cv2.medianBlur()

🦄3.2.1 程序设计

gaussian_blur = cv2.medianBlur(gaussian_img, (3, 3))
sp_blur = cv2.medianBlur(sp_img, (3, 3))
h1 = np.hstack([gaussian_img, gaussian_blur])
h2 = np.hstack([sp_img, sp_blur])
v = np.vstack([h1, h2])
cv2.imwrite(r"C:\Users\Lenovo\Desktop\DIP\median_filter.jpg", v)
cv2.imshow('out', v)
cv2.waitKey()

🦄3.2.2 实验结果

在这里插入图片描述

  • 第一幅图为被高斯噪声污染的图像;
  • 第二幅图为使用中值滤波对第一幅图去噪后的图像;
  • 第三幅图为被椒盐噪声污染的图像;
  • 第四幅图为使用中值滤波对第三幅图去噪后的图像。

🦄3.2.3 指标参数

gaussian_psnr, sp_psnr, gaussian_ssim, sp_ssim, gaussian_mse, sp_mse = compare(original, gaussian_blur, sp_blur)
print('中值滤波对高斯噪声污染图像去噪后的指标为:PSNR:{},SSIM:{},MSE:{}'.format(gaussian_psnr, gaussian_ssim, gaussian_mse))
print('中值滤波对椒盐噪声污染图像去噪后的指标为:PSNR:{},SSIM:{},MSE:{}'.format(sp_psnr, sp_ssim, sp_mse))

结果为:

中值滤波对高斯噪声污染图像去噪后的指标为:PSNR:26.882078435438537,SSIM:0.6406334892144118,MSE:133.31300481160483
中值滤波对椒盐噪声污染图像去噪后的指标为:PSNR:28.5392567826037,SSIM:0.7218574470291008,MSE:91.0237414042155

从指标结果可以看出,中值滤波对椒盐噪声的去除能力更强!

😺四、方框滤波

🐶4.1 滤波原理

方框滤波又称盒子滤波,方框滤波中可以自由选择是否对均值滤波的结果进行归一化,即可以自由选择滤波结果是邻域像素值之和的平均值(均值滤波),还是邻域像素值之和。也就是说均值滤波是方框滤波的特殊情况

方框滤波卷积核可以表示为:

K = 1 α [ 1 1 1 ⋯ 1 1 1 1 1 ⋯ 1 1 ⋯ ⋯ ⋯ ⋯ ⋯ ⋯ 1 1 1 ⋯ 1 1 1 1 1 ⋯ 1 1 1 1 1 ⋯ 1 1 ] K=\frac{1}{\alpha }\begin{bmatrix} 1& 1& 1& \cdots & 1& 1\\ 1& 1& 1& \cdots & 1& 1\\ \cdots & \cdots & \cdots & \cdots & \cdots & \cdots \\ 1& 1& 1& \cdots & 1& 1\\ 1& 1& 1& \cdots & 1& 1\\ 1& 1& 1& \cdots & 1& 1 \end{bmatrix} K=α1 1111111111111111111111111
上式的对应关系为:
α = { 1 w i d t h × h e i g h t n o r m a l i z e = 1 1 n o r m a l i z e = 0 \alpha =\left\{\begin{matrix} \frac{1}{width\times height}& normalize=1\\ 1& normalize=0 \end{matrix}\right. α={width×height11normalize=1normalize=0

🐶4.2 实验过程

使用函数:cv2.boxFilter(src, ddepth, ksize, anchor, normalize, borderType)

参数说明:

  • src:输入图像;
  • ddepth:图像深度,-1表示用原图深度;
  • ksize:内核大小;
  • anchor:锚点,默认为(-1,-1),表示当前计算均值的点位于核的中心点位置;
  • normalize:表示是否进行归一化处理,值为1,进行归一化处理;值为0,不进行归一化处理;
  • borderType:表示以何种方式处理边界,默认即可。

🦄4.2.1 程序设计

"""
方框滤波
"""
gaussian_blur = cv2.boxFilter(gaussian_img, -1, (3, 3), normalize=0)
sp_blur = cv2.boxFilter(sp_img, -1, (3, 3), normalize=0)
h1 = np.hstack([gaussian_img, gaussian_blur])
h2 = np.hstack([sp_img, sp_blur])
v = np.vstack([h1, h2])
cv2.imwrite(r"C:\Users\Lenovo\Desktop\DIP\box_filter.jpg", v)
cv2.imshow('out', v)
cv2.waitKey()

🦄4.2.2 实验结果

在这里插入图片描述

  • 第一幅图为被高斯噪声污染的图像;
  • 第二幅图为使用方框滤波对第一幅图去噪后的图像;
  • 第三幅图为被椒盐噪声污染的图像;
  • 第四幅图为使用方框滤波对第三幅图去噪后的图像。

由图可知,不经过归一化的方框滤波很容易出现大面积的白色。

🦄4.2.3 指标参数

gaussian_psnr, sp_psnr, gaussian_ssim, sp_ssim, gaussian_mse, sp_mse = compare(original, gaussian_blur, sp_blur)
print('方框滤波对高斯噪声污染图像去噪后的指标为:PSNR:{},SSIM:{},MSE:{}'.format(gaussian_psnr, gaussian_ssim, gaussian_mse))
print('方框滤波对椒盐噪声污染图像去噪后的指标为:PSNR:{},SSIM:{},MSE:{}'.format(sp_psnr, sp_ssim, sp_mse))

结果为:

方框滤波对高斯噪声污染图像去噪后的指标为:PSNR:5.251255346836561,SSIM:0.415694536225471,MSE:19406.84003829956
方框滤波对椒盐噪声污染图像去噪后的指标为:PSNR:5.328992238651672,SSIM:0.41684132817868463,MSE:19062.556196848553

😺五、双边滤波

🐶5.1 滤波原理

双边滤波是一种非线性的滤波方法,其同时考虑空间几何距离与灰度相似性。

🐶5.2 实验过程

使用函数:cv2.bilateralFilter(src, d, sigmaColor, sigmaSpace[, dst[, borderType]])

参数说明:

  • src:输入图像;
  • d:滤波期间使用的每个像素邻域的直径,如果其值为非正数,则从sigmaSpace计算;
  • sigmaColor:在颜色空间中过滤sigma,较大的参数意味着像素邻域内较远的颜色将相互影响;
  • sigmaSpace:在几何空间中过滤sigma,较大的参数意味着更远的像素将相互影响;

🦄5.2.1 程序设计

"""
双边滤波
"""
gaussian_blur = cv2.bilateralFilter(gaussian_img, 25, 100, 100)
sp_blur = cv2.bilateralFilter(sp_img, 25, 100, 100)
h1 = np.hstack([gaussian_img, gaussian_blur])
h2 = np.hstack([sp_img, sp_blur])
v = np.vstack([h1, h2])
cv2.imwrite(r"C:\Users\Lenovo\Desktop\DIP\bilateral_filter.jpg", v)
cv2.imshow('out', v)
cv2.waitKey()

🦄5.2.2 实验结果

在这里插入图片描述

  • 第一幅图为被高斯噪声污染的图像;
  • 第二幅图为使用双边滤波对第一幅图去噪后的图像;
  • 第三幅图为被椒盐噪声污染的图像;
  • 第四幅图为使用双边滤波对第三幅图去噪后的图像。

🦄5.2.3 指标参数

gaussian_psnr, sp_psnr, gaussian_ssim, sp_ssim, gaussian_mse, sp_mse = compare(original, gaussian_blur, sp_blur)
print('双边滤波对高斯噪声污染图像去噪后的指标为:PSNR:{},SSIM:{},MSE:{}'.format(gaussian_psnr, gaussian_ssim, gaussian_mse))
print('双边滤波对椒盐噪声污染图像去噪后的指标为:PSNR:{},SSIM:{},MSE:{}'.format(sp_psnr, sp_ssim, sp_mse))

结果为:

双边滤波对高斯噪声污染图像去噪后的指标为:PSNR:25.992916512934414,SSIM:0.6635250024737996,MSE:163.60203806559244
双边滤波对椒盐噪声污染图像去噪后的指标为:PSNR:21.06964250996061,SSIM:0.3879879230675302,MSE:508.2953186035156

从指标结果可以看出,双边滤波对高斯噪声的去除能力更强!

😺六、高斯滤波

🐶6.1 滤波原理

在实际滤波中,将当前像素作为核中心,利用卷积核对周围邻域像素作加权平均,其值作为当前像素的新值。

高斯滤波步骤:

  • 移动相关核的中心元素,使它位于输入图像待处理像素的正上方;
  • 将输入图像的像素值作为权重,乘以相关核;
  • 将上面各步得到的结果相加做为输出。

简单来说就是根据高斯分布得到高斯模板然后做卷积相加的一个过程。

https://www.cnblogs.com/kensporger/p/11628050.html
https://www.jianshu.com/p/73e6ccbd8f3f

🐶6.2 实验过程

使用函数:cv2.GaussianBlur(src, ksize, sigmaX [ , dst [ , sigmaY [ , borderType ] ] ] )
参数说明:

  • src:输入图像;
  • ksize:高斯核大小,必须是正数和奇数;
  • sigmaX:X方向的高斯核标准差;
  • sigmaY:Y方向的高斯核标准差;如果该值为0,则默认为与sigma相等。
  • borderType:边界处理方式。

🦄6.2.1 程序设计

"""
高斯滤波
"""
gaussian_blur = cv2.GaussianBlur(gaussian_img, (5, 5), 0, 0)
sp_blur = cv2.GaussianBlur(sp_img, (5, 5), 0, 0)
h1 = np.hstack([gaussian_img, gaussian_blur])
h2 = np.hstack([sp_img, sp_blur])
v = np.vstack([h1, h2])
cv2.imwrite(r"C:\Users\Lenovo\Desktop\DIP\gaussian_filter.jpg", v)
cv2.imshow('out', v)
cv2.waitKey()

🦄6.2.2 实验结果

在这里插入图片描述

  • 第一幅图为被高斯噪声污染的图像;
  • 第二幅图为使用高斯滤波对第一幅图去噪后的图像;
  • 第三幅图为被椒盐噪声污染的图像;
  • 第四幅图为使用高斯滤波对第三幅图去噪后的图像。

🦄6.2.3 指标参数

gaussian_psnr, sp_psnr, gaussian_ssim, sp_ssim, gaussian_mse, sp_mse = compare(original, gaussian_blur, sp_blur)
print('高斯滤波对高斯噪声污染图像去噪后的指标为:PSNR:{},SSIM:{},MSE:{}'.format(gaussian_psnr, gaussian_ssim, gaussian_mse))
print('高斯滤波对椒盐噪声污染图像去噪后的指标为:PSNR:{},SSIM:{},MSE:{}'.format(sp_psnr, sp_ssim, sp_mse))

结果为:

高斯滤波对高斯噪声污染图像去噪后的指标为:PSNR:27.80345326784865,SSIM:0.7496298168722767,MSE:107.82886505126953
高斯滤波对椒盐噪声污染图像去噪后的指标为:PSNR:26.360239863855103,SSIM:0.6420068535144939,MSE:150.33370971679688

从指标结果可以看出,高斯滤波对高斯噪声的去除能力更强!

😺七、全部代码

import numpy as np
import cv2
from skimage.measure import compare_ssim, compare_psnr, compare_mse

original = cv2.imread(r"C:\Users\Lenovo\Desktop\DIP\lena1.jpg")
gaussian_img = cv2.imread(r"C:\Users\Lenovo\Desktop\DIP\gaussian.jpg")
sp_img = cv2.imread(r"C:\Users\Lenovo\Desktop\DIP\sp.jpg")

def compare(ori, gaussian_denosing, sp_denosing):

    # ori为原图(未被噪声污染的图),gaussian_denosing为经过高斯噪声污染的图通过去噪算法去噪后的图;sp_denosing为经过椒盐噪声污染的图通过去噪算法去噪后的图
    gaussian_psnr = compare_psnr(ori, gaussian_denosing)
    sp_psnr = compare_psnr(ori, sp_denosing)

    gaussian_ssim = compare_ssim(ori, gaussian_denosing, multichannel=True)
    sp_ssim = compare_ssim(ori, sp_denosing, multichannel=True)

    gaussian_mse = compare_mse(ori, gaussian_denosing)
    sp_mse = compare_mse(ori, sp_denosing)

    return gaussian_psnr, sp_psnr, gaussian_ssim, sp_ssim, gaussian_mse, sp_mse

"""
均值滤波
"""
gaussian_blur = cv2.blur(gaussian_img, (3, 3))
sp_blur = cv2.blur(sp_img, (3, 3))
h1 = np.hstack([gaussian_img, gaussian_blur])
h2 = np.hstack([sp_img, sp_blur])
v = np.vstack([h1, h2])
cv2.imwrite(r"C:\Users\Lenovo\Desktop\DIP\mean_filter.jpg", v)
cv2.imshow('out', v)
cv2.waitKey()

gaussian_psnr, sp_psnr, gaussian_ssim, sp_ssim, gaussian_mse, sp_mse = compare(original, gaussian_blur, sp_blur)
print('均值滤波对高斯噪声污染图像去噪后的指标为:PSNR:{},SSIM:{},MSE:{}'.format(gaussian_psnr, gaussian_ssim, gaussian_mse))
print('均值滤波对椒盐噪声污染图像去噪后的指标为:PSNR:{},SSIM:{},MSE:{}'.format(sp_psnr, sp_ssim, sp_mse))

"""
中值滤波
"""
gaussian_blur = cv2.medianBlur(gaussian_img, 3)
sp_blur = cv2.medianBlur(sp_img, 3)
h1 = np.hstack([gaussian_img, gaussian_blur])
h2 = np.hstack([sp_img, sp_blur])
v = np.vstack([h1, h2])
cv2.imwrite(r"C:\Users\Lenovo\Desktop\DIP\median_filter.jpg", v)
cv2.imshow('out', v)
cv2.waitKey()

gaussian_psnr, sp_psnr, gaussian_ssim, sp_ssim, gaussian_mse, sp_mse = compare(original, gaussian_blur, sp_blur)
print('中值滤波对高斯噪声污染图像去噪后的指标为:PSNR:{},SSIM:{},MSE:{}'.format(gaussian_psnr, gaussian_ssim, gaussian_mse))
print('中值滤波对椒盐噪声污染图像去噪后的指标为:PSNR:{},SSIM:{},MSE:{}'.format(sp_psnr, sp_ssim, sp_mse))

"""
方框滤波
"""
gaussian_blur = cv2.boxFilter(gaussian_img, -1, (3, 3), normalize=0)
sp_blur = cv2.boxFilter(sp_img, -1, (3, 3), normalize=0)
h1 = np.hstack([gaussian_img, gaussian_blur])
h2 = np.hstack([sp_img, sp_blur])
v = np.vstack([h1, h2])
cv2.imwrite(r"C:\Users\Lenovo\Desktop\DIP\box_filter.jpg", v)
cv2.imshow('out', v)
cv2.waitKey()

gaussian_psnr, sp_psnr, gaussian_ssim, sp_ssim, gaussian_mse, sp_mse = compare(original, gaussian_blur, sp_blur)
print('方框滤波对高斯噪声污染图像去噪后的指标为:PSNR:{},SSIM:{},MSE:{}'.format(gaussian_psnr, gaussian_ssim, gaussian_mse))
print('方框滤波对椒盐噪声污染图像去噪后的指标为:PSNR:{},SSIM:{},MSE:{}'.format(sp_psnr, sp_ssim, sp_mse))

"""
双边滤波
"""
gaussian_blur = cv2.bilateralFilter(gaussian_img, 25, 100, 100)
sp_blur = cv2.bilateralFilter(sp_img, 25, 100, 100)
h1 = np.hstack([gaussian_img, gaussian_blur])
h2 = np.hstack([sp_img, sp_blur])
v = np.vstack([h1, h2])
cv2.imwrite(r"C:\Users\Lenovo\Desktop\DIP\bilateral_filter.jpg", v)
cv2.imshow('out', v)
cv2.waitKey()

gaussian_psnr, sp_psnr, gaussian_ssim, sp_ssim, gaussian_mse, sp_mse = compare(original, gaussian_blur, sp_blur)
print('双边滤波对高斯噪声污染图像去噪后的指标为:PSNR:{},SSIM:{},MSE:{}'.format(gaussian_psnr, gaussian_ssim, gaussian_mse))
print('双边滤波对椒盐噪声污染图像去噪后的指标为:PSNR:{},SSIM:{},MSE:{}'.format(sp_psnr, sp_ssim, sp_mse))

"""
高斯滤波
"""
gaussian_blur = cv2.GaussianBlur(gaussian_img, (5, 5), 0, 0)
sp_blur = cv2.GaussianBlur(sp_img, (5, 5), 0, 0)
h1 = np.hstack([gaussian_img, gaussian_blur])
h2 = np.hstack([sp_img, sp_blur])
v = np.vstack([h1, h2])
cv2.imwrite(r"C:\Users\Lenovo\Desktop\DIP\gaussian_filter.jpg", v)
cv2.imshow('out', v)
cv2.waitKey()

gaussian_psnr, sp_psnr, gaussian_ssim, sp_ssim, gaussian_mse, sp_mse = compare(original, gaussian_blur, sp_blur)
print('高斯滤波对高斯噪声污染图像去噪后的指标为:PSNR:{},SSIM:{},MSE:{}'.format(gaussian_psnr, gaussian_ssim, gaussian_mse))
print('高斯滤波对椒盐噪声污染图像去噪后的指标为:PSNR:{},SSIM:{},MSE:{}'.format(sp_psnr, sp_ssim, sp_mse))
  • 31
    点赞
  • 256
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

王乐予

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值