保持纹理的非局部去噪方法

在本例中,我们使用非局部均值过滤器对宇航员图像的细节进行去噪。非局部均值算法用选择的其他像素值的平均值替换像素值:将以其他像素为中心的小面片与以感兴趣像素为中心的面片进行比较,并且仅对具有接近当前面片的面片的像素执行平均。结果表明,该算法能较好地恢复被其他去噪算法模糊的纹理。

fast_mode 论据是 False 在计算面片距离时,将空间高斯权重应用于面片。什么时候 fast_modeTrue 应用了一种在面片上采用均匀空间加权的更快的算法。

对于这些情况中的任何一种,如果噪声标准偏差, sigma ,则在计算面片距离时减去预期噪声方差。这可以带来图像质量的适度改善。

这个 estimate_sigma 函数可以为设置 h (并且可选地, sigma )参数,用于非局部均值算法。 h 是一个常数,它控制面片权重作为面片之间距离的函数的衰减。更大 h 允许在不相似的面片之间进行更平滑的处理。

在此演示中, h ,是手动调整的,以给出每个变体的近似最佳情况性能。

noisy, non-local means (slow), non-local means (slow, using $\sigma_{est}$), original (noise free), non-local means (fast), non-local means (fast, using $\sigma_{est}$)

输出:

/scikit-image/doc/examples/filters/plot_nonlocal_means.py:49: FutureWarning:

`multichannel` is a deprecated argument name for `estimate_sigma`. It will be removed in version 1.0. Please use `channel_axis` instead.

estimated noise standard deviation = 0.07790067598696092
/scikit-image/doc/examples/filters/plot_nonlocal_means.py:57: FutureWarning:

`multichannel` is a deprecated argument name for `denoise_nl_means`. It will be removed in version 1.0. Please use `channel_axis` instead.

/scikit-image/doc/examples/filters/plot_nonlocal_means.py:61: FutureWarning:

`multichannel` is a deprecated argument name for `denoise_nl_means`. It will be removed in version 1.0. Please use `channel_axis` instead.

/scikit-image/doc/examples/filters/plot_nonlocal_means.py:65: FutureWarning:

`multichannel` is a deprecated argument name for `denoise_nl_means`. It will be removed in version 1.0. Please use `channel_axis` instead.

/scikit-image/doc/examples/filters/plot_nonlocal_means.py:69: FutureWarning:

`multichannel` is a deprecated argument name for `denoise_nl_means`. It will be removed in version 1.0. Please use `channel_axis` instead.

PSNR (noisy) = 22.22
PSNR (slow) = 29.39
PSNR (slow, using sigma) = 29.79
PSNR (fast) = 28.96
PSNR (fast, using sigma) = 29.34

import numpy as np
import matplotlib.pyplot as plt

from skimage import data, img_as_float
from skimage.restoration import denoise_nl_means, estimate_sigma
from skimage.metrics import peak_signal_noise_ratio
from skimage.util import random_noise


astro = img_as_float(data.astronaut())
astro = astro[30:180, 150:300]

sigma = 0.08
noisy = random_noise(astro, var=sigma**2)

# estimate the noise standard deviation from the noisy image
sigma_est = np.mean(estimate_sigma(noisy, multichannel=True))
print(f"estimated noise standard deviation = {sigma_est}")

patch_kw = dict(patch_size=5,      # 5x5 patches
                patch_distance=6,  # 13x13 search area
                multichannel=True)

# slow algorithm
denoise = denoise_nl_means(noisy, h=1.15 * sigma_est, fast_mode=False,
                           **patch_kw)

# slow algorithm, sigma provided
denoise2 = denoise_nl_means(noisy, h=0.8 * sigma_est, sigma=sigma_est,
                            fast_mode=False, **patch_kw)

# fast algorithm
denoise_fast = denoise_nl_means(noisy, h=0.8 * sigma_est, fast_mode=True,
                                **patch_kw)

# fast algorithm, sigma provided
denoise2_fast = denoise_nl_means(noisy, h=0.6 * sigma_est, sigma=sigma_est,
                                 fast_mode=True, **patch_kw)

fig, ax = plt.subplots(nrows=2, ncols=3, figsize=(8, 6),
                       sharex=True, sharey=True)

ax[0, 0].imshow(noisy)
ax[0, 0].axis('off')
ax[0, 0].set_title('noisy')
ax[0, 1].imshow(denoise)
ax[0, 1].axis('off')
ax[0, 1].set_title('non-local means\n(slow)')
ax[0, 2].imshow(denoise2)
ax[0, 2].axis('off')
ax[0, 2].set_title('non-local means\n(slow, using $\\sigma_{est}$)')
ax[1, 0].imshow(astro)
ax[1, 0].axis('off')
ax[1, 0].set_title('original\n(noise free)')
ax[1, 1].imshow(denoise_fast)
ax[1, 1].axis('off')
ax[1, 1].set_title('non-local means\n(fast)')
ax[1, 2].imshow(denoise2_fast)
ax[1, 2].axis('off')
ax[1, 2].set_title('non-local means\n(fast, using $\\sigma_{est}$)')

fig.tight_layout()

# print PSNR metric for each case
psnr_noisy = peak_signal_noise_ratio(astro, noisy)
psnr = peak_signal_noise_ratio(astro, denoise)
psnr2 = peak_signal_noise_ratio(astro, denoise2)
psnr_fast = peak_signal_noise_ratio(astro, denoise_fast)
psnr2_fast = peak_signal_noise_ratio(astro, denoise2_fast)

print(f"PSNR (noisy) = {psnr_noisy:0.2f}")
print(f"PSNR (slow) = {psnr:0.2f}")
print(f"PSNR (slow, using sigma) = {psnr2:0.2f}")
print(f"PSNR (fast) = {psnr_fast:0.2f}")
print(f"PSNR (fast, using sigma) = {psnr2_fast:0.2f}")

plt.show()

脚本的总运行时间: (0分1.484秒)

Gallery generated by Sphinx-Gallery