From 2bc8538f9fdc7c3bf489a6a2452202f3ee60e63b Mon Sep 17 00:00:00 2001 From: Evgeni Burovski Date: Sat, 6 Feb 2016 18:46:12 +0000 Subject: [PATCH] MAINT: address review comments * typos in comments * handle the corner case of width-1 2D image * vanity * change up leftover <= to correct == --- CONTRIBUTORS.txt | 3 +++ skimage/morphology/_skeletonize_3d.py | 5 ++++ skimage/morphology/_skeletonize_3d_cy.pyx.in | 24 ++++++++------------ 3 files changed, 18 insertions(+), 14 deletions(-) diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index 9e028354..f2a75b33 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -221,3 +221,6 @@ - Egor Panfilov Inpainting with biharmonic equation + +- Evgeni Burovski + Adaptation of ImageJ 3D skeletonization algorithm. diff --git a/skimage/morphology/_skeletonize_3d.py b/skimage/morphology/_skeletonize_3d.py index 2a419bf4..d041f643 100644 --- a/skimage/morphology/_skeletonize_3d.py +++ b/skimage/morphology/_skeletonize_3d.py @@ -56,6 +56,11 @@ def skeletonize_3d(img): # make an in image 3D pad w/ zeros to simplify dealing w/ boundaries # NB: careful to not clobber the original *and* minimize copying if img.ndim == 2: + + if img.shape[0] == 1 or img.shape[1] == 1: + # nothing to do, image is already thin. Bail out. + return img.copy() + img_o = np.pad(img[None, ...], pad_width=1, mode='constant') else: img_o = np.pad(img, pad_width=1, mode='constant') diff --git a/skimage/morphology/_skeletonize_3d_cy.pyx.in b/skimage/morphology/_skeletonize_3d_cy.pyx.in index 5926e10a..e8637799 100644 --- a/skimage/morphology/_skeletonize_3d_cy.pyx.in +++ b/skimage/morphology/_skeletonize_3d_cy.pyx.in @@ -16,16 +16,12 @@ The original Java code [IAC15]_ carries the following message: * @version 1.0 11/13/2015 (unique BSD licensed version for scikit-image) * @author Ignacio Arganda-Carreras (iargandacarreras at gmail.com) -Porting to Cython was done by Evgeni Burovski (evgeny.burovskiy@gmail.com). - References ---------- - .. [Lee94] T.-C. Lee, R.L. Kashyap and C.-N. Chu, Building skeleton models via 3-D medial surface/axis thinning algorithms. Computer Vision, Graphics, and Image Processing, 56(6):462-478, 1994. - .. [IAC15] Ignacio Arganda-Carreras, 2015. Skeletonize3D plugin for ImageJ(C). http://fiji.sc/Skeletonize3D @@ -50,7 +46,7 @@ def _compute_thin_image(pixel_type[:, :, ::1] img not None): those point which can be removed without changing local connectivity in the 3x3x3 neighborhood of a point. - This routine implements the two-pass algorthim of [Lee94]_. Namely, + This routine implements the two-pass algorithm of [Lee94]_. Namely, for each of the six border types (positive and negative x-, y- and z-), the algorithm first collects all possibly deletable points, and then performs a sequential rechecking. @@ -58,7 +54,7 @@ def _compute_thin_image(pixel_type[:, :, ::1] img not None): The input, `img`, is assumed to be a 3D binary image in the (p, r, c) format [i.e., C ordered array], filled by zeros (background) and ones. Furthermore, `img` is assumed to be padded by zeros from all - directions --- this way the zero boundary conditions are authomatic + directions --- this way the zero boundary conditions are automatic and there is need to guard against out-of-bounds access. """ @@ -69,7 +65,7 @@ def _compute_thin_image(pixel_type[:, :, ::1] img not None): bint no_change list simple_border_points - Py_ssize_t num_simple_points, i, j + Py_ssize_t num_border_points, i, j (npy_intp, npy_intp, npy_intp) point pixel_type neighb[27] @@ -146,12 +142,12 @@ cdef list _loop_through(pixel_type[:, :, ::1] img, if img[p, r, c] != 1: continue - is_border_pt = (curr_border == 1 and img[p, r, c-1] <= 0 or #N - curr_border == 2 and img[p, r, c+1] <= 0 or #S - curr_border == 3 and img[p, r+1, c] <= 0 or #E - curr_border == 4 and img[p, r-1, c] <= 0 or #W - curr_border == 5 and img[p+1, r, c] <= 0 or #U - curr_border == 6 and img[p-1, r, c] <= 0) #B + is_border_pt = (curr_border == 1 and img[p, r, c-1] == 0 or #N + curr_border == 2 and img[p, r, c+1] == 0 or #S + curr_border == 3 and img[p, r+1, c] == 0 or #E + curr_border == 4 and img[p, r-1, c] == 0 or #W + curr_border == 5 and img[p+1, r, c] == 0 or #U + curr_border == 6 and img[p-1, r, c] == 0) #B if not is_border_pt: # current point is not deletable continue @@ -271,7 +267,7 @@ cdef bint is_Euler_invariant(pixel_type neighbors[], int[::1] lut): """Check if a point is Euler invariant. - Calculate Euler characteristc for each octant and sum up. + Calculate Euler characteristic for each octant and sum up. Parameters ----------