From 1d8e02bf387fe667ffba378960a8e2bc3b44556f Mon Sep 17 00:00:00 2001 From: emmanuelle Date: Sat, 10 Jan 2015 12:15:26 +0100 Subject: [PATCH] Removed normalization of h parameters because float images will be normalized anyway. --- skimage/restoration/_nl_means_denoising.pyx | 24 ++++++++++----------- skimage/restoration/nl_means_denoising.py | 8 +++---- 2 files changed, 15 insertions(+), 17 deletions(-) diff --git a/skimage/restoration/_nl_means_denoising.pyx b/skimage/restoration/_nl_means_denoising.pyx index 7a1b866f..f91e0170 100644 --- a/skimage/restoration/_nl_means_denoising.pyx +++ b/skimage/restoration/_nl_means_denoising.pyx @@ -102,8 +102,6 @@ def _nl_means_denoising_2d(image, int s=7, int d=13, float h=0.1): cdef DTYPE_t [:, ::1] padded = np.ascontiguousarray(util.pad(image, offset, mode='reflect').astype(np.float32)) cdef DTYPE_t [:, ::1] result = padded.copy() - # We normalize by the image contrast, and divide by 3 because of 3 channels - h *= (np.max(padded) - np.min(padded)) / 3. cdef float A = ((s - 1.) / 4.) cdef float new_value cdef float weight_sum, weight @@ -115,7 +113,7 @@ def _nl_means_denoising_2d(image, int s=7, int d=13, float h=0.1): cdef int x, y, i, j cdef int x_start, x_end, y_start, y_end cdef int x_start_i, x_end_i, y_start_j, y_end_j - w = 1. / (np.sum(w) * 2 * h ** 2) * w + w = 1. / (np.sum(w) * h ** 2.) * w # Coordinates of central pixel and patch bounds for x in range(offset, n_x + offset): x_start = x - offset @@ -180,7 +178,6 @@ def _nl_means_denoising_2drgb(image, int s=7, int d=13, float h=0.1): ((offset, offset), (offset, offset), (0, 0)), mode='reflect').astype(np.float32)) cdef DTYPE_t [:, :, ::1] result = padded.copy() - h *= (np.max(padded) - np.min(padded)) cdef float A = ((s - 1.) / 4.) cdef float new_value cdef float weight_sum, weight @@ -189,7 +186,7 @@ def _nl_means_denoising_2drgb(image, int s=7, int d=13, float h=0.1): - (xg ** 2 + yg ** 2) / (2 * A ** 2)). astype(np.float32)) cdef float distance - w = 1. / (np.sum(w) * 2 * h ** 2) * w + w = 1. / (np.sum(w) * h ** 2) * w # Coordinates of central pixel and patch bounds for x in range(offset, n_x + offset): x_start = x - offset @@ -255,7 +252,6 @@ def _nl_means_denoising_3d(image, int s=7, image.astype(np.float32), offset, mode='reflect')) cdef DTYPE_t [:, :, ::1] result = padded.copy() - h *= (np.max(padded) - np.min(padded)) cdef float A = ((s - 1.) / 4.) cdef float new_value cdef float weight_sum, weight @@ -268,7 +264,7 @@ def _nl_means_denoising_3d(image, int s=7, cdef int x, y, z, i, j, k cdef int x_start, x_end, y_start, y_end, z_start, z_end cdef int x_start_i, x_end_i, y_start_j, y_end_j, z_start_k, z_end_k - w = 1. / (np.sum(w) * 2 * h ** 2) * w + w = 1. / (np.sum(w) * h ** 2) * w # Coordinates of central pixel and patch bounds for x in range(offset, n_x + offset): x_start = x - offset @@ -337,17 +333,17 @@ def _fast_nl_means_denoising_2d(image, int s=7, int d=13, float h=0.1): cdef int pad_size = offset + d cdef DTYPE_t [:, ::1] padded = np.ascontiguousarray(util.pad(image, pad_size, mode='reflect').astype(np.float32)) - cdef DTYPE_t [:, ::1] result = padded.copy() + cdef DTYPE_t [:, ::1] result = np.zeros_like(padded) cdef DTYPE_t [:, ::1] weights = np.zeros_like(padded) cdef DTYPE_t [:, ::1] integral = np.zeros_like(padded) - h *= (np.max(padded) - np.min(padded)) cdef int n_x, n_y, t1, t2, x, y cdef float weight, distance - cdef float h2 = h**2 - cdef float s2 = s**2. + cdef float h2 = h ** 2. + cdef float s2 = s ** 2. n_x, n_y = image.shape n_x += 2 * pad_size n_y += 2 * pad_size + # Outer loops on patch shifts for t1 in range(-d, d + 1): for t2 in range(-d, d + 1): integral = np.zeros_like(padded) @@ -371,8 +367,10 @@ def _fast_nl_means_denoising_2d(image, int s=7, int d=13, float h=0.1): integral[x - offset, y - offset] - \ integral[x - offset, y + offset] - \ integral[x + offset, y - offset] - distance /= s2 - weight = exp(- distance / h2) + distance /= (s2 * h2) + if distance > 4: + continue + weight = exp(- distance) weights[x, y] += weight result[x, y] += weight * padded[x + t1, y + t2] for x in range(offset, n_x - offset): diff --git a/skimage/restoration/nl_means_denoising.py b/skimage/restoration/nl_means_denoising.py index 79c67e04..5abbec5e 100644 --- a/skimage/restoration/nl_means_denoising.py +++ b/skimage/restoration/nl_means_denoising.py @@ -66,8 +66,8 @@ def nl_means_denoising(image, patch_size=7, patch_distance=11, h=0.1): >>> denoised_a = nl_means_denoising(a, 7, 5, 0.1) """ if image.ndim == 2: - return np.array(_nl_means_denoising_2d(image, patch_size, - patch_distance, h)) + return np.array(_nl_means_denoising_2d(image, s=patch_size, + d=patch_distance, h=h)) if image.ndim == 3 and image.shape[-1] > 4: # only grayscale return np.array(_nl_means_denoising_3d(image, patch_size, patch_distance, h)) @@ -150,8 +150,8 @@ def fast_nl_means_denoising(image, patch_size=7, patch_distance=11, h=0.1): >>> denoised_a = fast_nl_means_denoising(a, 7, 5, 0.1) """ if image.ndim == 2: - return np.array(_fast_nl_means_denoising_2d(image, patch_size, - patch_distance, h)) + return np.array(_fast_nl_means_denoising_2d(image, s=patch_size, + d=patch_distance, h=h)) else: raise ValueError("Fast non local means denoising is only possible for \ 2D grayscale images.")