From bdb2df89c030a16bf9d59eb7dc3602d935a96d0f Mon Sep 17 00:00:00 2001 From: "Thouis (Ray) Jones" Date: Tue, 12 Feb 2013 14:32:08 -0500 Subject: [PATCH 1/8] use SSE to add/subtract histograms --- skimage/filter/_ctmf.pyx | 35 +++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/skimage/filter/_ctmf.pyx b/skimage/filter/_ctmf.pyx index c133d8d6..d24a9693 100644 --- a/skimage/filter/_ctmf.pyx +++ b/skimage/filter/_ctmf.pyx @@ -17,6 +17,13 @@ cimport cython from libc.stdlib cimport malloc, free from libc.string cimport memset +cdef extern from "emmintrin.h": + ctypedef long __m128i + __m128i _mm_load_si128 (__m128i *p) + __m128i _mm_adds_epu16 (__m128i a, __m128i b) + __m128i _mm_subs_epu16 (__m128i a, __m128i b) + void _mm_store_si128 (__m128i *p, __m128i a) + np.import_array() ############################################################################## @@ -342,14 +349,30 @@ cdef inline np.int32_t trailing_edge_colidx(Histograms *ph, np.int32_t colidx): # TO_DO - optimize using SIMD instructions # cdef inline void add16(np.uint16_t *dest, np.uint16_t *src): - cdef int i - for i in range(16): - dest[i] += src[i] + cdef __m128i d, s, *pd, *ps + pd = <__m128i *> dest + ps = <__m128i *> src + d = _mm_load_si128(pd) + s = _mm_load_si128(ps) + d = _mm_adds_epu16 (d, s) + _mm_store_si128(pd, d) + d = _mm_load_si128(pd + 1) + s = _mm_load_si128(ps + 1) + d = _mm_adds_epu16 (d, s) + _mm_store_si128(pd + 1, d) cdef inline void sub16(np.uint16_t *dest, np.uint16_t *src): - cdef int i - for i in range(16): - dest[i] -= src[i] + cdef __m128i d, s, *pd, *ps + pd = <__m128i *> dest + ps = <__m128i *> src + d = _mm_load_si128(pd) + s = _mm_load_si128(ps) + d = _mm_subs_epu16 (d, s) + _mm_store_si128(pd, d) + d = _mm_load_si128(pd + 1) + s = _mm_load_si128(ps + 1) + d = _mm_subs_epu16 (d, s) + _mm_store_si128(pd + 1, d) ############################################################################ # From 32c0b1ca979fcfd201a435f13851666c01247941 Mon Sep 17 00:00:00 2001 From: "Thouis (Ray) Jones" Date: Tue, 12 Feb 2013 15:40:43 -0500 Subject: [PATCH 2/8] Rewrite histogram operations to remove GPL license on Perreault's code --- skimage/filter/_ctmf.pyx | 42 ++----------- skimage/filter/_histogram.h | 119 ++++++++++++++++++++++++++++++++++++ skimage/filter/setup.py | 2 +- 3 files changed, 124 insertions(+), 39 deletions(-) create mode 100644 skimage/filter/_histogram.h diff --git a/skimage/filter/_ctmf.pyx b/skimage/filter/_ctmf.pyx index d24a9693..8133efb0 100644 --- a/skimage/filter/_ctmf.pyx +++ b/skimage/filter/_ctmf.pyx @@ -17,12 +17,10 @@ cimport cython from libc.stdlib cimport malloc, free from libc.string cimport memset -cdef extern from "emmintrin.h": - ctypedef long __m128i - __m128i _mm_load_si128 (__m128i *p) - __m128i _mm_adds_epu16 (__m128i a, __m128i b) - __m128i _mm_subs_epu16 (__m128i a, __m128i b) - void _mm_store_si128 (__m128i *p, __m128i a) +cdef extern from "_histogram.h": + ctypedef unsigned short int uint16_t + void add16(uint16_t *dest, uint16_t *src) + void sub16(uint16_t *dest, uint16_t *src) np.import_array() @@ -341,38 +339,6 @@ cdef inline np.int32_t leading_edge_colidx(Histograms *ph, np.int32_t colidx): cdef inline np.int32_t trailing_edge_colidx(Histograms *ph, np.int32_t colidx): return (colidx + 3*ph.radius - 1) % ph.stripe_length -# -# add16 - add 16 consecutive integers -# -# Add an array of 16 16-bit integers to an accumulator of 16 16-bit integers -# -# TO_DO - optimize using SIMD instructions -# -cdef inline void add16(np.uint16_t *dest, np.uint16_t *src): - cdef __m128i d, s, *pd, *ps - pd = <__m128i *> dest - ps = <__m128i *> src - d = _mm_load_si128(pd) - s = _mm_load_si128(ps) - d = _mm_adds_epu16 (d, s) - _mm_store_si128(pd, d) - d = _mm_load_si128(pd + 1) - s = _mm_load_si128(ps + 1) - d = _mm_adds_epu16 (d, s) - _mm_store_si128(pd + 1, d) - -cdef inline void sub16(np.uint16_t *dest, np.uint16_t *src): - cdef __m128i d, s, *pd, *ps - pd = <__m128i *> dest - ps = <__m128i *> src - d = _mm_load_si128(pd) - s = _mm_load_si128(ps) - d = _mm_subs_epu16 (d, s) - _mm_store_si128(pd, d) - d = _mm_load_si128(pd + 1) - s = _mm_load_si128(ps + 1) - d = _mm_subs_epu16 (d, s) - _mm_store_si128(pd + 1, d) ############################################################################ # diff --git a/skimage/filter/_histogram.h b/skimage/filter/_histogram.h new file mode 100644 index 00000000..968b664f --- /dev/null +++ b/skimage/filter/_histogram.h @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2013 Thouis "Ray" Jones + * Modified from code + * Copyright (C) 2006 Simon Perreault + * + * Reference: S. Perreault and P. Hébert, "Median Filtering in Constant Time", + * IEEE Transactions on Image Processing, September 2007. + * + */ + +/* Intrinsic declarations */ +#if defined(__SSE2__) +#include +#elif defined(__MMX__) +#include +#elif defined(__ALTIVEC__) +#include +#endif + +/* Compiler peculiarities */ +#if defined(__GNUC__) +#include +#elif defined(_MSC_VER) +#define inline __inline +#endif + +/** + * Add 16 unsigned 16-bit integers using SSE2, MMX or Altivec, if + * available. + */ +#if defined(__SSE2__) +static inline void add16(uint16_t *dest, uint16_t *src) +{ + __m128i *d, *s; + d = (__m128i *) dest; + s = (__m128i *) src; + *d = _mm_add_epi16(*d, *s); + d++; s++; + *d = _mm_add_epi16(*d, *s); +} +#elif defined(__MMX__) +static inline void add16(uint16_t *dest, uint16_t *src) +{ + __m64 *d, *s; + d = (__m64 *) dest; + s = (__m64 *) src; + *d = _mm_add_pi16(*d, *s); + d++; s++; + *d = _mm_add_pi16(*d, *s); + d++; s++; + *d = _mm_add_pi16(*d, *s); + d++; s++; + *d = _mm_add_pi16(*d, *s); +} +#elif defined(__ALTIVEC__) +static inline void add16(uint16_t *dest, uint16_t *src) +{ + vector unsigned short *d, *s; + d = (vector unsigned short *) dest; + s = (vector unsigned short *) src; + *d = vec_add(*d, *s); + d++; s++; + *d = vec_add(*d, *s); +} +#else +static inline void add16(uint16_t *dest, uint16_t *src) +{ + int i; + + for (i = 0; i < 16; i++) dest[i] += src[i]; +} +#endif + +/** + * Subtract 16 unsigned 16-bit integers using SSE2, MMX or Altivec, if + * available. + */ +#if defined(__SSE2__) +static inline void sub16(uint16_t *dest, uint16_t *src) +{ + __m128i *d, *s; + d = (__m128i *) dest; + s = (__m128i *) src; + *d = _mm_sub_epi16(*d, *s); + d++; s++; + *d = _mm_sub_epi16(*d, *s); +} +#elif defined(__MMX__) +static inline void sub16(uint16_t *dest, uint16_t *src) +{ + __m64 *d, *s; + d = (__m64 *) dest; + s = (__m64 *) src; + *d = _mm_sub_pi16(*d, *s); + d++; s++; + *d = _mm_sub_pi16(*d, *s); + d++; s++; + *d = _mm_sub_pi16(*d, *s); + d++; s++; + *d = _mm_sub_pi16(*d, *s); +} +#elif defined(__ALTIVEC__) +static inline void sub16(uint16_t *dest, uint16_t *src) +{ + vector unsigned short *d, *s; + d = (vector unsigned short *) dest; + s = (vector unsigned short *) src; + *d = vec_sub(*d, *s); + d++; s++; + *d = vec_sub(*d, *s); +} +#else +static inline void sub16(uint16_t *dest, uint16_t *src) +{ + int i; + + for (i = 0; i < 16; i++) dest[i] -= src[i]; +} +#endif diff --git a/skimage/filter/setup.py b/skimage/filter/setup.py index 650a26a6..cfcb0794 100644 --- a/skimage/filter/setup.py +++ b/skimage/filter/setup.py @@ -25,7 +25,7 @@ def configuration(parent_package='', top_path=None): cython(['rank/percentile_rank.pyx'], working_path=base_path) cython(['rank/bilateral_rank.pyx'], working_path=base_path) - config.add_extension('_ctmf', sources=['_ctmf.c'], + config.add_extension('_ctmf', sources=['_ctmf.c', '_histogram.h'], include_dirs=[get_numpy_include_dirs()]) config.add_extension('_denoise_cy', sources=['_denoise_cy.c'], include_dirs=[get_numpy_include_dirs(), '../_shared']) From b5b99d8872649e5fddb7d9307985d6e3cbbebab7 Mon Sep 17 00:00:00 2001 From: "Thouis (Ray) Jones" Date: Tue, 19 Feb 2013 16:05:31 -0500 Subject: [PATCH 3/8] fix UTF-8 --- skimage/filter/_histogram.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/skimage/filter/_histogram.h b/skimage/filter/_histogram.h index 968b664f..3df3a70d 100644 --- a/skimage/filter/_histogram.h +++ b/skimage/filter/_histogram.h @@ -3,7 +3,7 @@ * Modified from code * Copyright (C) 2006 Simon Perreault * - * Reference: S. Perreault and P. Hébert, "Median Filtering in Constant Time", + * Reference: S. Perreault and P. Hébert, "Median Filtering in Constant Time", * IEEE Transactions on Image Processing, September 2007. * */ From b41bfba22f4c92e8d5910bc73971f43238c89f30 Mon Sep 17 00:00:00 2001 From: "Thouis (Ray) Jones" Date: Tue, 19 Feb 2013 16:41:25 -0500 Subject: [PATCH 4/8] remove typedef, use numpy type in its place --- skimage/filter/_ctmf.pyx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/skimage/filter/_ctmf.pyx b/skimage/filter/_ctmf.pyx index 8133efb0..f5cd5fd0 100644 --- a/skimage/filter/_ctmf.pyx +++ b/skimage/filter/_ctmf.pyx @@ -18,9 +18,8 @@ from libc.stdlib cimport malloc, free from libc.string cimport memset cdef extern from "_histogram.h": - ctypedef unsigned short int uint16_t - void add16(uint16_t *dest, uint16_t *src) - void sub16(uint16_t *dest, uint16_t *src) + void add16(np.uint16_t *dest, np.uint16_t *src) + void sub16(np.uint16_t *dest, np.uint16_t *src) np.import_array() From 4af05245edb0537037b4fda3dc81efa01f1f4977 Mon Sep 17 00:00:00 2001 From: "Thouis (Ray) Jones" Date: Tue, 19 Feb 2013 16:41:54 -0500 Subject: [PATCH 5/8] add casts to suppress compiler warnings --- skimage/filter/_ctmf.pyx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/skimage/filter/_ctmf.pyx b/skimage/filter/_ctmf.pyx index f5cd5fd0..87e4a8b9 100644 --- a/skimage/filter/_ctmf.pyx +++ b/skimage/filter/_ctmf.pyx @@ -327,17 +327,17 @@ cdef void set_stride(Histograms *ph, SCoord *psc): # ############################################################################ cdef inline np.int32_t tl_br_colidx(Histograms *ph, np.int32_t colidx): - return (colidx + 3*ph.radius + ph.current_row) % ph.stripe_length + return (colidx + 3*ph.radius + ph.current_row) % ph.stripe_length cdef inline np.int32_t tr_bl_colidx(Histograms *ph, np.int32_t colidx): - return (colidx + 3*ph.radius + ph.row_count-ph.current_row) % \ + return (colidx + 3*ph.radius + ph.row_count-ph.current_row) % \ ph.stripe_length cdef inline np.int32_t leading_edge_colidx(Histograms *ph, np.int32_t colidx): - return (colidx + 5*ph.radius) % ph.stripe_length + return (colidx + 5*ph.radius) % ph.stripe_length cdef inline np.int32_t trailing_edge_colidx(Histograms *ph, np.int32_t colidx): - return (colidx + 3*ph.radius - 1) % ph.stripe_length + return (colidx + 3*ph.radius - 1) % ph.stripe_length ############################################################################ # @@ -612,7 +612,7 @@ cdef inline np.uint8_t find_median(Histograms *ph): if ph.accumulator_count == 0: return 0 - pixels_below = ((ph.accumulator_count * ph.percent + 50) + pixels_below = ((ph.accumulator_count * ph.percent + 50) / 100) # +50 for roundoff if pixels_below > 0: pixels_below -= 1 @@ -774,8 +774,8 @@ def median_filter( raise ValueError('Data shape (%d, %d) is not output shape (%d, %d)' % (data.shape[0], data.shape[1], output.shape[0], output.shape[1])) - if c_median_filter(data.shape[0], data.shape[1], - data.strides[0], data.strides[1], + if c_median_filter( data.shape[0], data.shape[1], + data.strides[0], data.strides[1], radius, percent, data.data, mask.data, From ba1d27b35761b168ef6eedfcc2c7092a498a6eb2 Mon Sep 17 00:00:00 2001 From: "Thouis (Ray) Jones" Date: Tue, 19 Feb 2013 21:44:06 -0500 Subject: [PATCH 6/8] move _histogram.h to _shared/vectorized_ops.h, and copyright info to CONTRIBUTORS.txt --- CONTRIBUTORS.txt | 3 +++ .../{filter/_histogram.h => _shared/vectorized_ops.h} | 10 ---------- skimage/filter/_ctmf.pyx | 2 +- 3 files changed, 4 insertions(+), 11 deletions(-) rename skimage/{filter/_histogram.h => _shared/vectorized_ops.h} (90%) diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index d582ab63..38e2ea32 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -132,3 +132,6 @@ - François Boulogne Andres Method for circle perimeter, ellipse perimeter drawing. + +- Thouis Jones + Vectorized operators for arrays of 16-bit ints. diff --git a/skimage/filter/_histogram.h b/skimage/_shared/vectorized_ops.h similarity index 90% rename from skimage/filter/_histogram.h rename to skimage/_shared/vectorized_ops.h index 3df3a70d..e426c86e 100644 --- a/skimage/filter/_histogram.h +++ b/skimage/_shared/vectorized_ops.h @@ -1,13 +1,3 @@ -/* - * Copyright (C) 2013 Thouis "Ray" Jones - * Modified from code - * Copyright (C) 2006 Simon Perreault - * - * Reference: S. Perreault and P. Hébert, "Median Filtering in Constant Time", - * IEEE Transactions on Image Processing, September 2007. - * - */ - /* Intrinsic declarations */ #if defined(__SSE2__) #include diff --git a/skimage/filter/_ctmf.pyx b/skimage/filter/_ctmf.pyx index 87e4a8b9..75c1b47a 100644 --- a/skimage/filter/_ctmf.pyx +++ b/skimage/filter/_ctmf.pyx @@ -17,7 +17,7 @@ cimport cython from libc.stdlib cimport malloc, free from libc.string cimport memset -cdef extern from "_histogram.h": +cdef extern from "../_shared/vectorized_ops.h": void add16(np.uint16_t *dest, np.uint16_t *src) void sub16(np.uint16_t *dest, np.uint16_t *src) From 1580c466c17409ee47d0fca1d36865256e3d6eaf Mon Sep 17 00:00:00 2001 From: "Thouis (Ray) Jones" Date: Wed, 20 Feb 2013 10:35:51 -0500 Subject: [PATCH 7/8] pep8 --- skimage/filter/_ctmf.pyx | 108 +++++++++++++++++++-------------------- 1 file changed, 53 insertions(+), 55 deletions(-) diff --git a/skimage/filter/_ctmf.pyx b/skimage/filter/_ctmf.pyx index 75c1b47a..5a81cb98 100644 --- a/skimage/filter/_ctmf.pyx +++ b/skimage/filter/_ctmf.pyx @@ -62,11 +62,11 @@ cdef struct HistogramPiece: np.uint16_t fine[256] cdef struct Histogram: - HistogramPiece top_left # top-left corner - HistogramPiece top_right # top-right corner - HistogramPiece edge # leading/trailing edge - HistogramPiece bottom_left # bottom-left corner - HistogramPiece bottom_right # bottom-right corner + HistogramPiece top_left # top-left corner + HistogramPiece top_right # top-right corner + HistogramPiece edge # leading/trailing edge + HistogramPiece bottom_left # bottom-left corner + HistogramPiece bottom_right # bottom-right corner # The pixel count has the number of pixels histogrammed in # each of the five compartments for this position. This changes @@ -127,16 +127,16 @@ cdef struct Histograms: # # x --> # - SCoord last_top_left # (-) left side of octagon's top - 1 row - SCoord top_left # (+) -1 row from trailing edge top - SCoord last_top_right # (-) right side of octagon's top - 1 col - 1 row - SCoord top_right # (+) -1 col -1 row from leading edge top - SCoord last_leading_edge # (-) leading edge (right) top stride - 1 row - SCoord leading_edge # (+) leading edge bottom stride - SCoord last_bottom_right # (-) leading edge bottom - 1 col - SCoord bottom_right # (+) right side of octagon's bottom - 1 col - SCoord last_bottom_left # (-) trailing edge bottom - 1 col - SCoord bottom_left # (+) left side of octagon's bottom - 1 col + SCoord last_top_left # (-) left side of octagon's top - 1 row + SCoord top_left # (+) -1 row from trailing edge top + SCoord last_top_right # (-) right side of octagon's top - 1 col - 1 row + SCoord top_right # (+) -1 col -1 row from leading edge top + SCoord last_leading_edge # (-) leading edge (right) top stride - 1 row + SCoord leading_edge # (+) leading edge bottom stride + SCoord last_bottom_right # (-) leading edge bottom - 1 col + SCoord bottom_right # (+) right side of octagon's bottom - 1 col + SCoord last_bottom_left # (-) trailing edge bottom - 1 col + SCoord bottom_left # (+) left side of octagon's bottom - 1 col np.int32_t row_stride # stride between one row and the next np.int32_t col_stride # stride between one column and the next @@ -185,25 +185,25 @@ cdef Histograms *allocate_histograms(np.int32_t rows, SCoord *psc memory_size = (adjusted_stripe_length * - (sizeof(Histogram) + sizeof(PixelCount))+ - sizeof(Histograms)+32) + (sizeof(Histogram) + sizeof(PixelCount)) + + sizeof(Histograms) + 32) ptr = malloc(memory_size) memset(ptr, 0, memory_size) - ph = ptr + ph = ptr if not ptr: return ph ph.memory = ptr - ptr = (ph+1) - ph.pixel_count = ptr - ptr = (ph.pixel_count + adjusted_stripe_length) + ptr = (ph + 1) + ph.pixel_count = ptr + ptr = (ph.pixel_count + adjusted_stripe_length) # # Align histogram memory to a 32-byte boundary # - roundoff = ptr + roundoff = ptr roundoff += 31 roundoff -= roundoff % 32 - ptr = roundoff - ph.histogram = ptr + ptr = roundoff + ph.histogram = ptr # # Fill in the statistical things we keep around # @@ -232,7 +232,7 @@ cdef Histograms *allocate_histograms(np.int32_t rows, # a_2 is the offset from the center to each of the octagon # corners # - a = (radius * 2.0 / 2.414213) + a = ( radius * 2.0 / 2.414213) a_2 = a / 2 if a_2 == 0: a_2 = 1 @@ -327,17 +327,18 @@ cdef void set_stride(Histograms *ph, SCoord *psc): # ############################################################################ cdef inline np.int32_t tl_br_colidx(Histograms *ph, np.int32_t colidx): - return (colidx + 3*ph.radius + ph.current_row) % ph.stripe_length + return (colidx + 3 * ph.radius + ph.current_row) % \ + ph.stripe_length cdef inline np.int32_t tr_bl_colidx(Histograms *ph, np.int32_t colidx): - return (colidx + 3*ph.radius + ph.row_count-ph.current_row) % \ - ph.stripe_length + return (colidx + 3 * ph.radius + ph.row_count - ph.current_row) % \ + ph.stripe_length cdef inline np.int32_t leading_edge_colidx(Histograms *ph, np.int32_t colidx): - return (colidx + 5*ph.radius) % ph.stripe_length + return (colidx + 5 * ph.radius) % ph.stripe_length cdef inline np.int32_t trailing_edge_colidx(Histograms *ph, np.int32_t colidx): - return (colidx + 3*ph.radius - 1) % ph.stripe_length + return (colidx + 3 * ph.radius - 1) % ph.stripe_length ############################################################################ # @@ -528,9 +529,9 @@ cdef inline void update_histogram(Histograms *ph, y = last_coord.y + current_row stride = current_stride+last_coord.stride - if (x >= 0 and x < column_count and - y >= 0 and y < row_count and - ph.mask[stride]): + if (x >= 0 and x < column_count and \ + y >= 0 and y < row_count and \ + ph.mask[stride]): value = ph.data[stride] pixel_count[0] -= 1 hist_piece.fine[value] -= 1 @@ -540,9 +541,9 @@ cdef inline void update_histogram(Histograms *ph, y = coord.y + current_row stride = current_stride + coord.stride - if (x >= 0 and x < column_count and - y >= 0 and y < row_count and - ph.mask[stride]): + if (x >= 0 and x < column_count and \ + y >= 0 and y < row_count and \ + ph.mask[stride]): value = ph.data[stride] pixel_count[0] += 1 hist_piece.fine[value] += 1 @@ -613,7 +614,7 @@ cdef inline np.uint8_t find_median(Histograms *ph): if ph.accumulator_count == 0: return 0 pixels_below = ((ph.accumulator_count * ph.percent + 50) - / 100) # +50 for roundoff + / 100) # +50 for roundoff if pixels_below > 0: pixels_below -= 1 @@ -625,7 +626,7 @@ cdef inline np.uint8_t find_median(Histograms *ph): accumulator -= ph.accumulator.coarse[i] update_fine(ph, i) - for j in range(i*16,(i+1)*16): + for j in range(i * 16, (i + 1) * 16): accumulator += ph.accumulator.fine[j] if accumulator > pixels_below: return j @@ -659,9 +660,7 @@ cdef int c_median_filter(np.int32_t rows, cdef: Histograms *ph Histogram *phistogram - int row - int col - int i + int row, col, i np.int32_t top_left_off np.int32_t top_right_off np.int32_t bottom_left_off @@ -670,7 +669,7 @@ cdef int c_median_filter(np.int32_t rows, ph = allocate_histograms(rows, columns, row_stride, col_stride, radius, percent, data, mask, output) if not ph: - return 1 + return 1 for row in range(-radius, rows): # @@ -709,7 +708,7 @@ cdef int c_median_filter(np.int32_t rows, # Update locations and coarse accumulator for the octagon # for points before 0 # - for col in range(-radius, 0 if row >=0 else columns+radius): + for col in range(-radius, 0 if row >= 0 else columns+radius): ph.current_column = col ph.current_stride = row * row_stride + col * col_stride update_current_location(ph) @@ -730,16 +729,15 @@ cdef int c_median_filter(np.int32_t rows, ph.current_stride = row * row_stride + col * col_stride update_current_location(ph) - free_histograms(ph) return 0 -def median_filter( - np.ndarray[dtype=np.uint8_t, ndim=2, negative_indices=False, mode='c'] data, - np.ndarray[dtype=np.uint8_t, ndim=2, negative_indices=False, mode='c'] mask, - np.ndarray[dtype=np.uint8_t, ndim=2, negative_indices=False, mode='c'] output, - int radius, - np.int32_t percent): + +def median_filter(np.ndarray[dtype=np.uint8_t, ndim=2, negative_indices=False, mode='c'] data, + np.ndarray[dtype=np.uint8_t, ndim=2, negative_indices=False, mode='c'] mask, + np.ndarray[dtype=np.uint8_t, ndim=2, negative_indices=False, mode='c'] output, + int radius, + np.int32_t percent): """Median filter with octagon shape and masking. Parameters @@ -761,10 +759,10 @@ def median_filter( """ if percent < 0: - raise ValueError('Median filter percent = %d is less than zero' % \ + raise ValueError('Median filter percent = %d is less than zero' % percent) if percent > 100: - raise ValueError('Median filter percent = %d is greater than 100' % \ + raise ValueError('Median filter percent = %d is greater than 100' % percent) if data.shape[0] != mask.shape[0] or data.shape[1] != mask.shape[1]: raise ValueError('Data shape (%d, %d) is not mask shape (%d, %d)' % @@ -777,7 +775,7 @@ def median_filter( if c_median_filter( data.shape[0], data.shape[1], data.strides[0], data.strides[1], radius, percent, - data.data, - mask.data, - output.data): + data.data, + mask.data, + output.data): raise MemoryError('Failed to allocate scratchpad memory') From d2b98a93e9d578c86d8bd7cd440f0996dbdf3821 Mon Sep 17 00:00:00 2001 From: "Thouis (Ray) Jones" Date: Thu, 21 Feb 2013 11:45:32 -0500 Subject: [PATCH 8/8] remove _histogram.h from setup.py, it's been moved to _shared --- skimage/filter/setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/skimage/filter/setup.py b/skimage/filter/setup.py index cfcb0794..650a26a6 100644 --- a/skimage/filter/setup.py +++ b/skimage/filter/setup.py @@ -25,7 +25,7 @@ def configuration(parent_package='', top_path=None): cython(['rank/percentile_rank.pyx'], working_path=base_path) cython(['rank/bilateral_rank.pyx'], working_path=base_path) - config.add_extension('_ctmf', sources=['_ctmf.c', '_histogram.h'], + config.add_extension('_ctmf', sources=['_ctmf.c'], include_dirs=[get_numpy_include_dirs()]) config.add_extension('_denoise_cy', sources=['_denoise_cy.c'], include_dirs=[get_numpy_include_dirs(), '../_shared'])