From 8ad8946900527acf88c28210ee5e313de3dd28dc Mon Sep 17 00:00:00 2001 From: Neil Yager Date: Thu, 13 Oct 2011 09:51:27 +0100 Subject: [PATCH] Added more objects to skeletonize demo --- doc/examples/plot_skeleton.py | 28 +++++++++++++++++++++- scikits/image/morphology/skeletonize.py | 32 +++++++++++++++++++++---- 2 files changed, 55 insertions(+), 5 deletions(-) diff --git a/doc/examples/plot_skeleton.py b/doc/examples/plot_skeleton.py index 2c6fed27..68958c6d 100644 --- a/doc/examples/plot_skeleton.py +++ b/doc/examples/plot_skeleton.py @@ -1,15 +1,41 @@ +""" +=========== +Skeletonize +=========== + +An example of thinning a binary image using skeletonize. +""" from scikits.image.morphology import skeletonize +from scikits.image.draw import draw import numpy as np import matplotlib.pyplot as plt +# an empty image image = np.zeros((400, 400)) + +# foreground object 1 image[10:-10, 10:100] = 1 image[-100:-10, 10:-10] = 1 image[10:-10, -100:-10] = 1 +# foreground object 2 +rs, cs = draw.bresenham(250, 150, 10, 280) +for i in range(10): image[rs+i, cs] = 1 +rs, cs = draw.bresenham(10, 150, 250, 280) +for i in range(20): image[rs+i, cs] = 1 + +# foreground object 3 +ir, ic = np.indices(image.shape) +circle1 = (ic - 135)**2 + (ir - 150)**2 < 30**2 +circle2 = (ic - 135)**2 + (ir - 150)**2 < 20**2 +image[circle1] = 1 +image[circle2] = 0 + +# perform skeletonization skeleton = skeletonize.skeletonize(image) -plt.figure(figsize=(8,5)) +# display results +plt.figure(figsize=(10,6)) plt.subplot(121) plt.imshow(image, cmap=plt.cm.gray) diff --git a/scikits/image/morphology/skeletonize.py b/scikits/image/morphology/skeletonize.py index 325448a0..c5588370 100644 --- a/scikits/image/morphology/skeletonize.py +++ b/scikits/image/morphology/skeletonize.py @@ -1,4 +1,5 @@ -"""skeletonize.py - ??? +"""skeletonize.py - Use an iterative thinning algorithm to find the + skeletons of binary objects in an image. Original author: Neil Yager """ @@ -8,13 +9,32 @@ from scipy.ndimage import correlate def skeletonize(image): """ - Return a single pixel wide skeleton of all connected - components in a binary image + Return a single pixel wide skeleton of all connected components + in a binary image. + + The algorithm works by making successive passes of the image, + removing pixels on object borders. This continues until no + more pixels can be removed. The image is correlated with a + mask that assigns each pixel a number in the range [0...255] + corresponding to each possible pattern of its 8 neighbouring + pixels. A look up table is then used to assign the pixels a + value of 0, 1, 2 or 3, which are selectively removed during + the iterations. Parameters ---------- - image: + image: ndarray (2D) + A binary image containing the objects to be skeletonized. '1' + represents foreground, and '0' represents background. + + Notes + ----- + + This implementation gives different results than a medial + axis transforrmation, which can be can be implemented using + morphological operations. This implementation is generally much + faster. Returns ------- @@ -43,7 +63,11 @@ def skeletonize(image): 2,3,1,3,0,0,1,3,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 2,3,0,1,0,0,0,1,0,0,0,0,0,0,0,0,3,3,0,1,0,0,0,0,2,2,0,0,2,0,0,0] + # initialize the skeleton to the original image + # TODO: how to handle data types skeleton = image.copy().astype(np.int8) + + # create the mask that will assign a value based on neighbouring pixels mask = np.array([[ 1, 2, 4], [128, 0, 8], [ 64, 32, 16]], np.int8)