✨博客主页:米开朗琪罗~
✨博主爱好:羽毛球
✨年轻人要:Living for the moment(活在当下)!
推荐专栏:【图像处理】【千锤百炼Python】【深度学习】【排序算法】
本节将对经过噪声污染的图像进行去噪,去噪方法包含均值滤波、中值滤波、方框滤波、双边滤波和高斯滤波。
实验所用的图像为【OpenCV-Python】:对图像添加高斯噪声与椒盐噪声中得到的均值为0,方差为0.01的高斯噪声污染图像和噪声密度为0.05的椒盐噪声污染图像,如图所示:
为了评判去噪质量的好坏,我们将选取PSNR、SSIM和MSE作为评价指标!
评价指标见:【OpenCV-Python】:图像PSNR、SSIM、MSE计算
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
均值滤波也称线性滤波,它是指使用一个模板在原图上进行均值计算并替换原图的值。
均值滤波器的模板有标准像素平均和加权平均之分,一个 3 × 3 3×3 3×3大小的模板如下图所示:
使用函数:cv2.blur()
"""
均值滤波
"""
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()
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
从指标结果可以看出,均值滤波对高斯噪声的去除能力更强!
中值滤波是把图像中的一点用该点的一个邻域中的各值的中值代替。
使用函数:cv2.medianBlur()
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()
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
从指标结果可以看出,中值滤波对椒盐噪声的去除能力更强!
方框滤波又称盒子滤波,方框滤波中可以自由选择是否对均值滤波的结果进行归一化,即可以自由选择滤波结果是邻域像素值之和的平均值(均值滤波),还是邻域像素值之和。也就是说均值滤波是方框滤波的特殊情况。
方框滤波卷积核可以表示为:
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⎣⎢⎢⎢⎢⎢⎢⎡11⋯11111⋯11111⋯111⋯⋯⋯⋯⋯⋯11⋯11111⋯111⎦⎥⎥⎥⎥⎥⎥⎤
上式的对应关系为:
α = { 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
使用函数:cv2.boxFilter(src, ddepth, ksize, anchor, normalize, borderType)
参数说明:
"""
方框滤波
"""
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))
结果为:
方框滤波对高斯噪声污染图像去噪后的指标为:PSNR:5.251255346836561,SSIM:0.415694536225471,MSE:19406.84003829956
方框滤波对椒盐噪声污染图像去噪后的指标为:PSNR:5.328992238651672,SSIM:0.41684132817868463,MSE:19062.556196848553
双边滤波是一种非线性的滤波方法,其同时考虑空间几何距离与灰度相似性。
使用函数:cv2.bilateralFilter(src, d, sigmaColor, sigmaSpace[, dst[, borderType]])
参数说明:
"""
双边滤波
"""
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))
结果为:
双边滤波对高斯噪声污染图像去噪后的指标为:PSNR:25.992916512934414,SSIM:0.6635250024737996,MSE:163.60203806559244
双边滤波对椒盐噪声污染图像去噪后的指标为:PSNR:21.06964250996061,SSIM:0.3879879230675302,MSE:508.2953186035156
从指标结果可以看出,双边滤波对高斯噪声的去除能力更强!
在实际滤波中,将当前像素作为核中心,利用卷积核对周围邻域像素作加权平均,其值作为当前像素的新值。
高斯滤波步骤:
简单来说就是根据高斯分布得到高斯模板然后做卷积相加的一个过程。
https://www.cnblogs.com/kensporger/p/11628050.html
https://www.jianshu.com/p/73e6ccbd8f3f
使用函数:cv2.GaussianBlur(src, ksize, sigmaX [ , dst [ , sigmaY [ , borderType ] ] ] )
参数说明:
"""
高斯滤波
"""
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))
结果为:
高斯滤波对高斯噪声污染图像去噪后的指标为: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))