diff --git a/scikits/image/morphology/cmorph.pyx b/scikits/image/morphology/cmorph.pyx index dc4769b9..fb190f83 100644 --- a/scikits/image/morphology/cmorph.pyx +++ b/scikits/image/morphology/cmorph.pyx @@ -18,8 +18,10 @@ ctypedef np.uint8_t IMAGE_DTYPE_t cdef inline int int_max(int a, int b): return a if a >= b else b cdef inline int int_min(int a, int b): return a if a <= b else b -@cython.boundscheck(False) -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): +@cython.boundsgcheck(False) +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): cdef int hw = selem.shape[0] / 2 cdef int hh = selem.shape[1] / 2 cdef int width = image.shape[0], height = image.shape[1] @@ -46,13 +48,13 @@ def dilate(np.ndarray[IMAGE_DTYPE_t, ndim=2] image not None, np.ndarray[IMAGE_DT for x in range(width): for y in range(height): max_so_far = 0 - #for cx in range(int_max(0, x - hw), int_min(x + hw, out.shape[0])): - #for cy in range(int_max(0, y - hh), int_min(y + hh, out.shape[1])): for cx in range(0, sw): for cy in range(0, sh): ix = x + xinc[cx,cy] iy = y + yinc[cx,cy] - if ix>=0 and iy>=0 and ix < width and iy < height and selem[cx, cy] == 1 and image[ix,iy] > max_so_far: + if ix>=0 and iy>=0 and ix < width and iy < height \ + and selem[cx, cy] == 1 \ + and image[ix,iy] > max_so_far: max_so_far = image[ix,iy] out[x,y] = max_so_far @@ -60,7 +62,9 @@ def dilate(np.ndarray[IMAGE_DTYPE_t, ndim=2] image not None, np.ndarray[IMAGE_DT @cython.boundscheck(False) -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): +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): cdef int hw = selem.shape[0] / 2 cdef int hh = selem.shape[1] / 2 cdef int width = image.shape[0], height = image.shape[1] @@ -86,13 +90,13 @@ def erode(np.ndarray[IMAGE_DTYPE_t, ndim=2] image not None, np.ndarray[IMAGE_DTY for x in range(width): for y in range(height): min_so_far = 255 - #for cx in range(int_max(0, x - hw), int_min(x + hw, out.shape[0])): - #for cy in range(int_max(0, y - hh), int_min(y + hh, out.shape[1])): for cx in range(0, sw): for cy in range(0, sh): ix = x + xinc[cx,cy] iy = y + yinc[cx,cy] - if ix>=0 and iy>=0 and ix < width and iy < height and selem[cx, cy] == 1 and image[ix,iy] < min_so_far: + if ix>=0 and iy>=0 and ix < width \ + and iy < height and selem[cx, cy] == 1 \ + and image[ix,iy] < min_so_far: min_so_far = image[ix,iy] out[x,y] = min_so_far diff --git a/scikits/image/morphology/grey.py b/scikits/image/morphology/grey.py index 908881ce..64880ccf 100644 --- a/scikits/image/morphology/grey.py +++ b/scikits/image/morphology/grey.py @@ -3,11 +3,9 @@ :license: modified BSD """ -#__all__ = ['square', 'disk', 'diamond', 'line', 'ball', ] __docformat__ = 'restructuredtext en' import numpy as np -#from scipy.fftpack import fftshift, ifftshift eps = np.finfo(float).eps @@ -19,23 +17,23 @@ def greyscale_erode(image, selem, out=None): Parameters ---------- - image : ndarray - The image as an ndarray. + image : ndarray + The image as an ndarray. - selem : ndarray - The neighborhood expressed as a 2-D array of 1's and 0's. + selem : ndarray + The neighborhood expressed as a 2-D array of 1's and 0's. - out : ndarray - The array to store the result of the morphology. If None is - passed, a new array will be allocated. + out : ndarray + The array to store the result of the morphology. If None is + passed, a new array will be allocated. Returns ------- - eroded : ndarray - The result of the morphological erosion. + eroded : ndarray + The result of the morphological erosion. """ if image is out: - raise NotImplementedError("In-place morphological erosion not supported!") + raise NotImplementedError("In-place erosion not supported!") try: import cmorph out = cmorph.erode(image, selem, out=out) @@ -52,23 +50,23 @@ def greyscale_dilate(image, selem, out=None): Parameters ---------- - image : ndarray - The image as an ndarray. + image : ndarray + The image as an ndarray. - selem : ndarray - The neighborhood expressed as a 2-D array of 1's and 0's. + selem : ndarray + The neighborhood expressed as a 2-D array of 1's and 0's. - out : ndarray - The array to store the result of the morphology. If None, is - passed, a new array will be allocated. + out : ndarray + The array to store the result of the morphology. If None, is + passed, a new array will be allocated. Returns ------- - dilated : ndarray - The result of the morphological dilation. + dilated : ndarray + The result of the morphological dilation. """ if image is out: - raise NotImplementedError("In-place morphological dilation not supported!") + raise NotImplementedError("In-place dilation not supported!") try: import cmorph out = cmorph.dilate(image, selem, out=out) @@ -83,20 +81,20 @@ def greyscale_open(image, selem, out=None): Parameters ---------- - image : ndarray - The image as an ndarray. + image : ndarray + The image as an ndarray. - selem : ndarray - The neighborhood expressed as a 2-D array of 1's and 0's. + selem : ndarray + The neighborhood expressed as a 2-D array of 1's and 0's. - out : ndarray - The array to store the result of the morphology. If None - is passed, a new array will be allocated. + out : ndarray + The array to store the result of the morphology. If None + is passed, a new array will be allocated. Returns ------- - opening : ndarray - The result of the morphological opening. + opening : ndarray + The result of the morphological opening. """ eroded = greyscale_erode(image, selem) out = greyscale_dilate(eroded, selem, out=out) @@ -109,20 +107,20 @@ def greyscale_close(image, selem, out=None): Parameters ---------- - image : ndarray - The image as an ndarray. + image : ndarray + The image as an ndarray. - selem : ndarray - The neighborhood expressed as a 2-D array of 1's and 0's. + selem : ndarray + The neighborhood expressed as a 2-D array of 1's and 0's. - out : ndarray - The array to store the result of the morphology. If None, - is passed, a new array will be allocated. + out : ndarray + The array to store the result of the morphology. If None, + is passed, a new array will be allocated. Returns ------- - opening : ndarray - The result of the morphological opening. + opening : ndarray + The result of the morphological opening. """ dilated = greyscale_dilate(image, selem) out = greyscale_erode(dilated, selem, out=out) @@ -134,20 +132,20 @@ def greyscale_white_top_hat(image, selem, out=None): Parameters ---------- - image : ndarray - The image as an ndarray. + image : ndarray + The image as an ndarray. - selem : ndarray - The neighborhood expressed as a 2-D array of 1's and 0's. + selem : ndarray + The neighborhood expressed as a 2-D array of 1's and 0's. - out : ndarray - The array to store the result of the morphology. If None - is passed, a new array will be allocated. + out : ndarray + The array to store the result of the morphology. If None + is passed, a new array will be allocated. Returns ------- - opening : ndarray - The result of the morphological white top hat. + opening : ndarray + The result of the morphological white top hat. """ if image is out: raise NotImplementedError("Cannot perform white top hat in place.") @@ -163,20 +161,20 @@ def greyscale_black_top_hat(image, selem, out=None): Parameters ---------- - image : ndarray - The image as an ndarray. + image : ndarray + The image as an ndarray. - selem : ndarray - The neighborhood expressed as a 2-D array of 1's and 0's. + selem : ndarray + The neighborhood expressed as a 2-D array of 1's and 0's. - out : ndarray - The array to store the result of the morphology. If None - is passed, a new array will be allocated. + out : ndarray + The array to store the result of the morphology. If None + is passed, a new array will be allocated. Returns ------- - opening : ndarray - The result of the black top filter. + opening : ndarray + The result of the black top filter. """ if image is out: raise NotImplementedError("Cannot perform white top hat in place.") diff --git a/scikits/image/morphology/selem.py b/scikits/image/morphology/selem.py index 417dac19..7ac33240 100644 --- a/scikits/image/morphology/selem.py +++ b/scikits/image/morphology/selem.py @@ -5,7 +5,7 @@ import numpy as np -def square(width, dtype='uint8'): +def square(width, dtype=np.uint8): """ Generates a flat, square-shaped structuring element. Every pixel along the perimeter has a chessboard distance no greater than radius @@ -13,25 +13,24 @@ def square(width, dtype='uint8'): Parameters ---------- - width : int - The width and height of the square + width : int + The width and height of the square Additional Parameters --------------------- - dtype : string - The data type of the structuring element. + dtype : string + The data type of the structuring element. Returns ------- - selem : ndarray - - A structuring element consisting only of ones, i.e. every - pixel belongs to the neighborhood. + selem : ndarray + A structuring element consisting only of ones, i.e. every + pixel belongs to the neighborhood. """ return np.ones((width, width), dtype=dtype) -def rectangle(width, height, dtype='uint8'): +def rectangle(width, height, dtype=np.uint8): """ Generates a flat, rectangular-shaped structuring element of a given width and height. Every pixel in the rectangle belongs @@ -39,52 +38,55 @@ def rectangle(width, height, dtype='uint8'): Parameters ---------- - width : int - The width of the rectangle + width : int + The width of the rectangle - height : int - The height of the rectangle + height : int + The height of the rectangle Additional Parameters --------------------- - - dtype : string - The data type of the structuring element. + + dtype : string + The data type of the structuring element. Returns ------- - selem : ndarray + selem : ndarray - A structuring element consisting only of ones, i.e. every - pixel belongs to the neighborhood. + A structuring element consisting only of ones, i.e. every + pixel belongs to the neighborhood. """ return np.ones((width, height), dtype=dtype) -def diamond(radius, dtype='uint8'): +def diamond(radius, dtype=np.uint8): """ Generates a flat, diamond-shaped structuring element of a given radius. A pixel is part of the neighborhood (i.e. labeled 1) iff the city block/manhattan distance between it and the center of the neighborhood is no greater than radius. - *Parameters*: - radius : string - The radius of the disk-shaped structuring element. + Parameters + ---------- + radius : string + The radius of the disk-shaped structuring element. - dtype : string - The data type of the structuring element. + dtype : string + The data type of the structuring element. - *Returns*: - selem : ndarray - The structuring element where elements of the neighborhood - are 1 and 0 otherwise. + Returns + ------- + + selem : ndarray + The structuring element where elements of the neighborhood + are 1 and 0 otherwise. """ half = radius (I, J) = np.meshgrid(xrange(0, radius*2+1), xrange(0, radius*2+1)) s = np.abs(I-half)+np.abs(J-half) return np.array(s <= radius, dtype=dtype) -def disk(radius, N=0, dtype='uint8'): +def disk(radius, N=0, dtype=np.uint8): """ Generates a flat, disk-shaped structuring element of a given radius. A pixel is within the neighborhood iff the euclidean distance between @@ -92,18 +94,17 @@ def disk(radius, N=0, dtype='uint8'): Parameters ---------- - radius : string - The radius of the disk-shaped structuring element. + radius : string + The radius of the disk-shaped structuring element. - dtype : string - The data type of the structuring element. + dtype : string + The data type of the structuring element. Returns ------- - selem : ndarray - The structuring element where elements of the neighborhood - are 1 and 0 otherwise. - + selem : ndarray + The structuring element where elements of the neighborhood + are 1 and 0 otherwise. """ half = radius (I, J) = np.meshgrid(xrange(0, radius*2+1), xrange(0, radius*2+1)) @@ -111,34 +112,37 @@ def disk(radius, N=0, dtype='uint8'): s = (I-half)**2.+(J-half)**2. #print s else: - raise NotImplementedError("scikits.image.morphology.disk: approximations not implemented. Try N=0 for now.") + raise NotImplementedError(""" + scikits.image.morphology.disk: approximations not implemented. + + Try N=0 for now. + """) return np.array(s <= radius * radius, dtype=dtype) -def ellipse(size, angle, ratio=0.5, dtype='uint8'): +def ellipse(size, angle, ratio=0.5, dtype=np.uint8): """ Generates an elliptically-shaped structuring element of a given angle, ratio, and kernel size. Parameters ---------- - size : int - The half-width of the kernel. The kernel size is 2*size+1. + size : int + The half-width of the kernel. The kernel size is 2*size+1. - angle : float - The angle of rotation of the ellipse in radians. + angle : float + The angle of rotation of the ellipse in radians. - ratio : float - The aspect ratio of the ellipse. - - dtype : string - The data type of the structuring element. + ratio : float + The aspect ratio of the ellipse. + + dtype : string + The data type of the structuring element. Returns ------- - selem : ndarray - The structuring element where elements of the neighborhood - are 1 and 0 otherwise. - + selem : ndarray + The structuring element where elements of the neighborhood + are 1 and 0 otherwise. """ structure = np.zeros((2*size+1, 2*size+1), dtype=dtype) @@ -158,41 +162,42 @@ def ellipse(size, angle, ratio=0.5, dtype='uint8'): structure[i, j] = 1 return structure -def strel(shape='disk', N=0, radius=3, width=3, height=3, angle=0., length=3, dtype='uint8', out=None): +def strel(shape='disk', N=0, radius=3, width=3, height=3, angle=0., length=3, + dtype=np.uint8, out=None): """ Generates a structuring element for greyscale or binary morphology. The interface of this function is similar to MATLAB(TM)'s strel function. Parameters ---------- - shape : string - A string identifier for the shape of the structuring element, - which can be any of the following: 'arbitrary', 'ball', - 'diamond', 'disk', 'pair', 'rectangle', 'square'. + shape : string + A string identifier for the shape of the structuring element, + which can be any of the following: 'arbitrary', 'ball', + 'diamond', 'disk', 'pair', 'rectangle', 'square'. - N : int - When non-zero, the number of lines to approximate the - structuring element. (not implemented) + N : int + When non-zero, the number of lines to approximate the + structuring element. (not implemented) - radius : int - The radius for disk or diamond structuring elements. + radius : int + The radius for disk or diamond structuring elements. - width : int - The height for square, ball or rectangle-shaped structuring elements. + width : int + The height for square, ball or rectangle-shaped structuring elements. - height : int - The height for ball or rectangle-shaped structuring elements. + height : int + The height for ball or rectangle-shaped structuring elements. - size : int - The half-width of an elliptical structuring element. + size : int + The half-width of an elliptical structuring element. - aspect : float - The aspect ratio of an ellipse. + aspect : float + The aspect ratio of an ellipse. Returns ------- - neighborhood : ndarray - The structuring element. + neighborhood : ndarray + The structuring element. """ shape = shape.lower().strip() if shape == 'disk':