From b0376721ebfede6904a351b69ae6a7c745a8ba67 Mon Sep 17 00:00:00 2001 From: Tony S Yu Date: Sat, 15 Oct 2011 04:23:37 -0400 Subject: [PATCH] Replace flip parameter in erode/dilate with shift_x and shift_y This change allows morphological open/close and white/black tophat to correctly use rectangular structuring element that has one even-numbered dimension. Note: dilate and erode functions flip the definitions of x/y and width/height, but it does so consistently so it doesn't really matter. --- scikits/image/morphology/cmorph.pyx | 14 ++++++----- scikits/image/morphology/grey.py | 38 +++++++++++++++-------------- 2 files changed, 28 insertions(+), 24 deletions(-) diff --git a/scikits/image/morphology/cmorph.pyx b/scikits/image/morphology/cmorph.pyx index 8ca24752..6870b500 100644 --- a/scikits/image/morphology/cmorph.pyx +++ b/scikits/image/morphology/cmorph.pyx @@ -23,12 +23,13 @@ cdef inline int int_min(int a, int b): return a if a <= b else b def dilate(np.ndarray[IMAGE_DTYPE_t, ndim=2] image not None, np.ndarray[IMAGE_DTYPE_t, ndim=2] selem not None, np.ndarray[IMAGE_DTYPE_t, ndim=2] out, - bool flip): + bool shift_x, bool shift_y): cdef int hw = selem.shape[0] // 2 cdef int hh = selem.shape[1] // 2 - if flip: - hw -= 1 + if shift_x: hh -= 1 + if shift_y: + hw -= 1 cdef int width = image.shape[0], height = image.shape[1] if out is None: @@ -71,12 +72,13 @@ def dilate(np.ndarray[IMAGE_DTYPE_t, ndim=2] image not None, def erode(np.ndarray[IMAGE_DTYPE_t, ndim=2] image not None, np.ndarray[IMAGE_DTYPE_t, ndim=2] selem not None, np.ndarray[IMAGE_DTYPE_t, ndim=2] out, - bool flip): + bool shift_x, bool shift_y): cdef int hw = selem.shape[0] // 2 cdef int hh = selem.shape[1] // 2 - if flip: - hw -= 1 + if shift_x: hh -= 1 + if shift_y: + hw -= 1 cdef int width = image.shape[0], height = image.shape[1] if out is None: diff --git a/scikits/image/morphology/grey.py b/scikits/image/morphology/grey.py index 463e55b2..dec12100 100644 --- a/scikits/image/morphology/grey.py +++ b/scikits/image/morphology/grey.py @@ -9,7 +9,7 @@ import numpy as np eps = np.finfo(float).eps -def greyscale_erode(image, selem, out=None, flip=False): +def greyscale_erode(image, selem, out=None, shift_x=False, shift_y=False): """ Performs a greyscale morphological erosion on an image given a flat structuring element. The eroded pixel at (i,j) is the minimum over all @@ -27,8 +27,8 @@ def greyscale_erode(image, selem, out=None, flip=False): The array to store the result of the morphology. If None is passed, a new array will be allocated. - flip : bool - Flip structuring element about center point. This only affects + shift_x, shift_y : bool + shift structuring element about center point. This only affects eccentric structuring elements (i.e. selem with even numbered sides). Returns @@ -40,12 +40,13 @@ def greyscale_erode(image, selem, out=None, flip=False): raise NotImplementedError("In-place erosion not supported!") try: import scikits.image.morphology.cmorph as cmorph - out = cmorph.erode(image, selem, out=out, flip=flip) + out = cmorph.erode(image, selem, out=out, + shift_x=shift_x, shift_y=shift_y) return out; except ImportError: raise ImportError("cmorph extension not available.") -def greyscale_dilate(image, selem, out=None, flip=False): +def greyscale_dilate(image, selem, out=None, shift_x=False, shift_y=False): """ Performs a greyscale morphological dilation on an image given a flat structuring element. The dilated pixel at (i,j) is the maximum over all @@ -64,8 +65,8 @@ def greyscale_dilate(image, selem, out=None, flip=False): The array to store the result of the morphology. If None, is passed, a new array will be allocated. - flip : bool - Flip structuring element about center point. This only affects + shift_x, shift_y : bool + shift structuring element about center point. This only affects eccentric structuring elements (i.e. selem with even numbered sides). Returns @@ -77,7 +78,8 @@ def greyscale_dilate(image, selem, out=None, flip=False): raise NotImplementedError("In-place dilation not supported!") try: from . import cmorph - out = cmorph.dilate(image, selem, out=out, flip=flip) + out = cmorph.dilate(image, selem, out=out, + shift_x=shift_x, shift_y=shift_y) return out; except ImportError: raise ImportError("cmorph extension not available.") @@ -106,12 +108,12 @@ def greyscale_open(image, selem, out=None): The result of the morphological opening. """ h, w = selem.shape - if (h % 2) == 0 and (w % 2) == 0: - flip = True - else: - flip = False + shift_x = True if (w % 2) == 0 else False + shift_y = True if (h % 2) == 0 else False + eroded = greyscale_erode(image, selem) - out = greyscale_dilate(eroded, selem, out=out, flip=flip) + out = greyscale_dilate(eroded, selem, out=out, + shift_x=shift_x, shift_y=shift_y) return out def greyscale_close(image, selem, out=None): @@ -137,12 +139,12 @@ def greyscale_close(image, selem, out=None): The result of the morphological opening. """ h, w = selem.shape - if (h % 2) == 0 and (w % 2) == 0: - flip = True - else: - flip = False + shift_x = True if (w % 2) == 0 else False + shift_y = True if (h % 2) == 0 else False + dilated = greyscale_dilate(image, selem) - out = greyscale_erode(dilated, selem, out=out, flip=flip) + out = greyscale_erode(dilated, selem, out=out, + shift_x=shift_x, shift_y=shift_y) return out def greyscale_white_top_hat(image, selem, out=None):