From 9b3c5792a008feec1b88fc83863cbc44628b45b8 Mon Sep 17 00:00:00 2001 From: Alexis Mignon Date: Fri, 31 May 2013 18:06:47 +0200 Subject: [PATCH 1/3] Modified 'denoise_bilateral':\n1) check that image max value is not zero to avoid segmentation fault.\n2) initialize color_lut after sigma_range has been checked. --- skimage/filter/_denoise_cy.pyx | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/skimage/filter/_denoise_cy.pyx b/skimage/filter/_denoise_cy.pyx index 5a85e84a..aec6090b 100644 --- a/skimage/filter/_denoise_cy.pyx +++ b/skimage/filter/_denoise_cy.pyx @@ -98,6 +98,15 @@ def denoise_bilateral(image, Py_ssize_t win_size=5, sigma_range=None, """ image = np.atleast_3d(img_as_float(image)) + + # if image.max() is 0, then dist_scale can have an unverified value + # and color_lut[(dist * dist_scale)] may cause a segmentation fault + # so we verify we have a positive image and that the max is not 0.0. + if image.min() < 0.0: + raise ValueError("Image must contain only positive values") + + if image.max() == 0.0: + return image cdef: Py_ssize_t rows = image.shape[0] @@ -115,7 +124,8 @@ def denoise_bilateral(image, Py_ssize_t win_size=5, sigma_range=None, double* image_data = cimage.data double* out_data = out.data - double* color_lut = _compute_color_lut(bins, sigma_range, max_value) + double* color_lut # the value of sigma_range must be checked before + # initialization. double* range_lut = _compute_range_lut(win_size, sigma_spatial) Py_ssize_t r, c, d, wr, wc, kr, kc, rr, cc, pixel_addr @@ -131,6 +141,8 @@ def denoise_bilateral(image, Py_ssize_t win_size=5, sigma_range=None, else: csigma_range = sigma_range + color_lut = _compute_color_lut(bins, csigma_range, max_value) + if mode not in ('constant', 'wrap', 'reflect', 'nearest'): raise ValueError("Invalid mode specified. Please use " "`constant`, `nearest`, `wrap` or `reflect`.") From a80fd76ef6c11d10b9de75c27f45f96f955d4b51 Mon Sep 17 00:00:00 2001 From: Alexis Mignon Date: Sat, 1 Jun 2013 14:38:26 +0200 Subject: [PATCH 2/3] Deported variable initialization after the cdef block to allow verifications. --- skimage/filter/_denoise_cy.pyx | 45 ++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/skimage/filter/_denoise_cy.pyx b/skimage/filter/_denoise_cy.pyx index aec6090b..097a7596 100644 --- a/skimage/filter/_denoise_cy.pyx +++ b/skimage/filter/_denoise_cy.pyx @@ -105,43 +105,52 @@ def denoise_bilateral(image, Py_ssize_t win_size=5, sigma_range=None, if image.min() < 0.0: raise ValueError("Image must contain only positive values") - if image.max() == 0.0: - return image - cdef: Py_ssize_t rows = image.shape[0] Py_ssize_t cols = image.shape[1] Py_ssize_t dims = image.shape[2] Py_ssize_t window_ext = (win_size - 1) / 2 - double max_value = image.max() + double max_value + + cnp.ndarray[dtype=cnp.double_t, ndim=3, mode='c'] cimage + cnp.ndarray[dtype=cnp.double_t, ndim=3, mode='c'] out - cnp.ndarray[dtype=cnp.double_t, ndim=3, mode='c'] cimage = \ - np.ascontiguousarray(image) - cnp.ndarray[dtype=cnp.double_t, ndim=3, mode='c'] out = \ - np.zeros((rows, cols, dims), dtype=np.double) + double* image_data + double* out_data - double* image_data = cimage.data - double* out_data = out.data - - double* color_lut # the value of sigma_range must be checked before - # initialization. - double* range_lut = _compute_range_lut(win_size, sigma_spatial) + double* color_lut + double* range_lut Py_ssize_t r, c, d, wr, wc, kr, kc, rr, cc, pixel_addr double value, weight, dist, total_weight, csigma_range, color_weight, \ range_weight - double dist_scale = bins / dims / max_value - double* values = malloc(dims * sizeof(double)) - double* centres = malloc(dims * sizeof(double)) - double* total_values = malloc(dims * sizeof(double)) + double dist_scale + double* values + double* centres + double* total_values if sigma_range is None: csigma_range = image.std() else: csigma_range = sigma_range + max_value = image.max() + + cimage = np.ascontiguousarray(image) + + if max_value == 0.0: + raise ValueError("The maximum value found in the image was 0.") + + out = np.zeros((rows, cols, dims), dtype=np.double) + image_data = cimage.data + out_data = out.data color_lut = _compute_color_lut(bins, csigma_range, max_value) + range_lut = _compute_range_lut(win_size, sigma_spatial) + dist_scale = bins / dims / max_value + values = malloc(dims * sizeof(double)) + centres = malloc(dims * sizeof(double)) + total_values = malloc(dims * sizeof(double)) if mode not in ('constant', 'wrap', 'reflect', 'nearest'): raise ValueError("Invalid mode specified. Please use " From 28189c9a66c676fca43397ce8c884cf6bc200cc9 Mon Sep 17 00:00:00 2001 From: Alexis Mignon Date: Mon, 3 Jun 2013 10:03:57 +0200 Subject: [PATCH 3/3] Moved image conversion after the verification of the max_value --- skimage/filter/_denoise_cy.pyx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/skimage/filter/_denoise_cy.pyx b/skimage/filter/_denoise_cy.pyx index 097a7596..6fd95f03 100644 --- a/skimage/filter/_denoise_cy.pyx +++ b/skimage/filter/_denoise_cy.pyx @@ -137,11 +137,11 @@ def denoise_bilateral(image, Py_ssize_t win_size=5, sigma_range=None, max_value = image.max() - cimage = np.ascontiguousarray(image) - if max_value == 0.0: raise ValueError("The maximum value found in the image was 0.") + cimage = np.ascontiguousarray(image) + out = np.zeros((rows, cols, dims), dtype=np.double) image_data = cimage.data out_data = out.data