# Denoise images using Non-Local Means (NLMEANS)

Using the non-local means filter [Coupe08] and [Coupe11] and you can denoise 3D or 4D images and boost the SNR of your datasets. You can also decide between modeling the noise as Gaussian or Rician (default).

import numpy as np
import nibabel as nib
import matplotlib.pyplot as plt
from time import time
from dipy.denoise.nlmeans import nlmeans
from dipy.denoise.noise_estimate import estimate_sigma
from dipy.data import get_fnames

dwi_fname, dwi_bval_fname, dwi_bvec_fname = get_fnames('sherbrooke_3shell')

mask = data[..., 0] > 80

# We select only one volume for the example to run quickly.
data = data[..., 1]

print("vol size", data.shape)

# lets create a noisy data with Gaussian data


In order to call non_local_means first you need to estimate the standard deviation of the noise. We use N=4 since the Sherbrooke dataset was acquired on a 1.5T Siemens scanner with a 4 array head coil.

sigma = estimate_sigma(data, N=4)

t = time()


Calling the main function non_local_means

t = time()

print("total time", time() - t)


Let us plot the axial slice of the denoised output

axial_middle = data.shape // 2

before = data[:, :, axial_middle].T
after = den[:, :, axial_middle].T

difference = np.abs(after.astype(np.float64) - before.astype(np.float64))

fig, ax = plt.subplots(1, 3)
ax.imshow(before, cmap='gray', origin='lower')
ax.set_title('before')
ax.imshow(after, cmap='gray', origin='lower')
ax.set_title('after')
ax.imshow(difference, cmap='gray', origin='lower')
ax.set_title('difference')

plt.savefig('denoised.png', bbox_inches='tight') Showing axial slice before (left) and after (right) NLMEANS denoising

nib.save(nib.Nifti1Image(den, affine), 'denoised.nii.gz')


An improved version of non-local means denoising is adaptive soft coefficient matching, please refer to example_denoise_ascm for more details.