发布时间:2021-09-29 00:24:51编辑:run阅读(6153)
scikit-image库还在图像复原模块中提供了一组非线性滤波器。
双边滤波器是一种边缘识别的平滑滤波器,对于这种滤波器,中心像素被设置为它的某些邻域像素值的加权平均值,而这些邻域像素值的亮度与中心像素的大致相似。使用scikit-image包中的双边滤波器实现图像去噪。
生成一幅噪声图像
from skimage import data, img_as_float,img_as_ubyte, exposure, io, color from skimage import color, data, restoration from skimage.util import random_noise import matplotlib.pylab as pylab pylab.rcParams['font.sans-serif'] = ['KaiTi'] pylab.rcParams['axes.unicode_minus'] = False def plot_image(image, title=''): pylab.title(title, size=20) pylab.imshow(image) pylab.axis('off') im = color.rgb2gray(img_as_float(io.imread(r'D:\image_processing\image4\aa.jpg'))) pylab.figure(figsize=(20, 15)) pylab.subplot(1, 2, 1) plot_image(im, '原始图像') sigma = 0.155 noisy = random_noise(im, var=sigma**2) pylab.subplot(1, 2, 2) plot_image(noisy, '噪声图像') pylab.show()
使用双边滤波器对上面的噪声图像去噪,采用不同的参数值。
from skimage import data, img_as_float,img_as_ubyte, exposure, io, color from skimage import color, data, restoration from skimage.restoration import denoise_bilateral from skimage.util import random_noise import matplotlib.pylab as pylab pylab.rcParams['font.sans-serif'] = ['KaiTi'] pylab.rcParams['axes.unicode_minus'] = False def plot_image(image, title=''): pylab.title(title, size=25) pylab.imshow(image) pylab.axis('off') im = color.rgb2gray(img_as_float(io.imread(r'D:\image_processing\image4\aa.jpg'))) pylab.figure(figsize=(20, 15)) pylab.subplot(1, 2, 1) plot_image(im, '原始图像') sigma = 0.155 noisy = random_noise(im, var=sigma**2) pylab.figure(figsize=(20, 15)) i = 1 for sigma_sp in [5, 10, 20]: for sigma_col in [0.1, 0.25, 5]: pylab.subplot(3, 3, i) pylab.imshow(denoise_bilateral(noisy, sigma_color=sigma_col, sigma_spatial=sigma_sp, multichannel=False)) pylab.title(r'$\sigma_r=$' + str(sigma_col) + r', $\sigma_s=$' + str(sigma_sp), size=20) i += 1 pylab.show()
可以看到,如果标准差越大,那么图像的噪声越小,但模糊程度越高。
非局部均值滤波器实际上是一种保留纹理的非线性去噪算法,在该算法中,对于任意给定的像素,仅使用与感兴趣的像素具有相似局部邻域像素的加权平均值来设置它的值。换言之,就是将以其他像素为中心的小斑块与以感兴趣像素为中心的斑块进行比较。通过使用非局部均值滤波器对图像去噪来演示算法。函数的h参数控制斑块权重的衰减,它是斑块之间距离的函数。如果h很大,它允许不同的斑块之间有更多的平滑。
from skimage.io import imread from skimage import data, img_as_float from skimage.restoration import denoise_bilateral, denoise_nl_means, estimate_sigma import matplotlib.pylab as pylab import numpy as np from skimage import metrics pylab.rcParams['font.sans-serif'] = ['KaiTi'] pylab.rcParams['axes.unicode_minus'] = False def plot_image_axes(image, axes, title): axes.imshow(image) axes.axis('off') axes.set_title(title, size=25) parrot = img_as_float(imread(r'D:\image_processing\image4\aa.jpg')) sigma = 0.25 noisy = parrot + sigma * np.random.standard_normal(parrot.shape) noisy = np.clip(noisy, 0, 1) sigma_est = np.mean(estimate_sigma(noisy, multichannel=True)) patch_kw = dict(patch_size=5, patch_distance=6, multichannel=True) denoise = denoise_nl_means(noisy, h=1.15 * sigma_est, fast_mode=False, **patch_kw) denoise_fast = denoise_nl_means(noisy, h=0.8 * sigma_est, fast_mode=True, **patch_kw) fig, axes = pylab.subplots(nrows=2, ncols=2, figsize=(15, 12), sharex=True, sharey=True) plot_image_axes(noisy, axes[0, 0], '噪声图像') plot_image_axes(denoise, axes[0, 1], '非局部均值(慢)') plot_image_axes(parrot, axes[1, 0], '原始图像(无噪声)') plot_image_axes(denoise_fast, axes[1, 1], '非局部均值(快)') fig.tight_layout() psnr_noisy = metrics.peak_signal_noise_ratio(parrot, noisy) psnr = metrics.peak_signal_noise_ratio(parrot, denoise.astype(np.float64)) psnr_fast = metrics.peak_signal_noise_ratio(parrot, denoise_fast.astype(np.float64)) pylab.show()
可以看到,慢版本的算法比快版本的峰值信噪比更好,这是一种权衡。两种算法输出图像的PSNR都比噪声图像高得多。
上一篇: python3-PIL非线性噪声平滑
47603
45980
36906
34465
29078
25710
24565
19711
19242
17755
5562°
6153°
5688°
5734°
6701°
5482°
5483°
5986°
5963°
7294°