/
non_local_means.py
130 lines (110 loc) · 5.46 KB
/
non_local_means.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
import numpy as np
from .._shared.utils import skimage_deprecation, warn
from ._nl_means_denoising import (
_nl_means_denoising_2d,
_nl_means_denoising_3d,
_fast_nl_means_denoising_2d,
_fast_nl_means_denoising_3d)
def denoise_nl_means(image, patch_size=7, patch_distance=11, h=0.1,
multichannel=None, fast_mode=True):
"""
Perform non-local means denoising on 2-D or 3-D grayscale images, and
2-D RGB images.
Parameters
----------
image : 2D or 3D ndarray
Input image to be denoised, which can be 2D or 3D, and grayscale
or RGB (for 2D images only, see ``multichannel`` parameter).
patch_size : int, optional
Size of patches used for denoising.
patch_distance : int, optional
Maximal distance in pixels where to search patches used for denoising.
h : float, optional
Cut-off distance (in gray levels). The higher h, the more permissive
one is in accepting patches. A higher h results in a smoother image,
at the expense of blurring features. For a Gaussian noise of standard
deviation sigma, a rule of thumb is to choose the value of h to be
sigma of slightly less.
multichannel : bool, optional
Whether the last axis of the image is to be interpreted as multiple
channels or another spatial dimension. Set to ``False`` for 3-D images.
fast_mode : bool, optional
If True (default value), a fast version of the non-local means
algorithm is used. If False, the original version of non-local means is
used. See the Notes section for more details about the algorithms.
Returns
-------
result : ndarray
Denoised image, of same shape as `image`.
Notes
-----
The non-local means algorithm is well suited for denoising images with
specific textures. The principle of the algorithm is to average the value
of a given pixel with values of other pixels in a limited neighbourhood,
provided that the *patches* centered on the other pixels are similar enough
to the patch centered on the pixel of interest.
In the original version of the algorithm [1]_, corresponding to
``fast=False``, the computational complexity is
image.size * patch_size ** image.ndim * patch_distance ** image.ndim
Hence, changing the size of patches or their maximal distance has a
strong effect on computing times, especially for 3-D images.
However, the default behavior corresponds to ``fast_mode=True``, for which
another version of non-local means [2]_ is used, corresponding to a
complexity of
image.size * patch_distance ** image.ndim
The computing time depends only weakly on the patch size, thanks to
the computation of the integral of patches distances for a given
shift, that reduces the number of operations [1]_. Therefore, this
algorithm executes faster than the classic algorith
(``fast_mode=False``), at the expense of using twice as much memory.
This implementation has been proven to be more efficient compared to
other alternatives, see e.g. [3]_.
Compared to the classic algorithm, all pixels of a patch contribute
to the distance to another patch with the same weight, no matter
their distance to the center of the patch. This coarser computation
of the distance can result in a slightly poorer denoising
performance. Moreover, for small images (images with a linear size
that is only a few times the patch size), the classic algorithm can
be faster due to boundary effects.
The image is padded using the `reflect` mode of `skimage.util.pad`
before denoising.
References
----------
.. [1] Buades, A., Coll, B., & Morel, J. M. (2005, June). A non-local
algorithm for image denoising. In CVPR 2005, Vol. 2, pp. 60-65, IEEE.
.. [2] J. Darbon, A. Cunha, T.F. Chan, S. Osher, and G.J. Jensen, Fast
nonlocal filtering applied to electron cryomicroscopy, in 5th IEEE
International Symposium on Biomedical Imaging: From Nano to Macro,
2008, pp. 1331-1334.
.. [3] Jacques Froment. Parameter-Free Fast Pixelwise Non-Local Means
Denoising. Image Processing On Line, 2014, vol. 4, p. 300-326.
Examples
--------
>>> a = np.zeros((40, 40))
>>> a[10:-10, 10:-10] = 1.
>>> a += 0.3 * np.random.randn(*a.shape)
>>> denoised_a = denoise_nl_means(a, 7, 5, 0.1)
"""
if multichannel is None:
warn('denoise_nl_means will default to multichannel=False in v0.15')
multichannel = True
if image.ndim == 2:
image = image[..., np.newaxis]
multichannel = True
if image.ndim != 3:
raise NotImplementedError("Non-local means denoising is only \
implemented for 2D grayscale and RGB images or 3-D grayscale images.")
if multichannel: # 2-D images
if fast_mode:
return np.squeeze(np.array(_fast_nl_means_denoising_2d(image,
patch_size, patch_distance, h)))
else:
return np.squeeze(np.array(_nl_means_denoising_2d(image,
patch_size, patch_distance, h)))
else: # 3-D grayscale
if fast_mode:
return np.array(_fast_nl_means_denoising_3d(image, s=patch_size,
d=patch_distance, h=h))
else:
return np.array(_nl_means_denoising_3d(image, patch_size,
patch_distance, h))