diff --git a/doc/examples/plot_segmentations.py b/doc/examples/plot_segmentations.py index 8830cebb..09012bbd 100644 --- a/doc/examples/plot_segmentations.py +++ b/doc/examples/plot_segmentations.py @@ -28,13 +28,13 @@ Quickshift image segmentation Quickshift is a relatively recent 2d image segmentation algorithm, based on an approximation of kernelized mean-shift. Therefore it belongs to the family of local mode-seeking algorithms and is applied to the 5d space consisting of -color information and image location. see [2]_. +color information and image location [2]_. One of the benefits of quickshift is that it actually computes a hierarchical segmentation on multiple scales simultaneously. -Quickshift has three parameters: ``sigma`` controls the scale of the local -density approximation, ``max_dist`` other selecting a level in the hierarchical +Quickshift has two main parameters: ``sigma`` controls the scale of the local +density approximation, ``max_dist`` selects a level in the hierarchical segmentation that is produced. There is also a trade-off between distance in color-space and distance in image-space, given by ``ratio``. @@ -45,7 +45,7 @@ color-space and distance in image-space, given by ``ratio``. SLIC - K-Means based image segmentation --------------------------------------- -This algorithm simply performs K-kmeans in the 5d space of color information +This algorithm simply performs K-means in the 5d space of color information and image location and is therefore closely related to quickshift. As the clustering method is simpler, it is very efficient. It is essential for this algorithm to work in Lab color space to obtain good results. The algorithm @@ -57,7 +57,6 @@ of Quickshift, while ``n_segments`` chooses the number of centers for kmeans. Pascal Fua, and Sabine Suesstrunk, SLIC Superpixels Compared to State-of-the-art Superpixel Methods, TPAMI, May 2012. """ -print __doc__ import matplotlib.pyplot as plt import numpy as np diff --git a/skimage/segmentation/_felzenszwalb.py b/skimage/segmentation/_felzenszwalb.py index f84f3e56..5729bd95 100644 --- a/skimage/segmentation/_felzenszwalb.py +++ b/skimage/segmentation/_felzenszwalb.py @@ -17,24 +17,24 @@ def felzenszwalb(image, scale=1, sigma=0.8, min_size=20): controlled indirectly through ``scale``. Segment size within an image can vary greatly depending on local contrast. - Calls the algorithm on each channel separately, then combines - using "and", i.e. two pixels are in the same segment if they are - in the same segment for each channel. + For RGB images, the algorithm computes a separate segmentation for each + channel and then combines these. The combined segmentation is the + intersection of the separate segmentations on the color channels. Parameters ---------- - image: (width, height) ndarray - Input image - scale: float + image : (width, height, 3) or (width, height) ndarray + Input image. + scale : float Free parameter. Higher means larger clusters. - sigma: float + sigma : float Width of Gaussian kernel used in preprocessing. - min_size: int + min_size : int Minimum component size. Enforced using postprocessing. Returns ------- - segment_mask: ndarray, [width, height] + segment_mask : (width, height) ndarray Integer mask indicating segment labels. References @@ -49,20 +49,21 @@ def felzenszwalb(image, scale=1, sigma=0.8, min_size=20): return _felzenszwalb_grey(image, scale=scale, sigma=sigma) elif image.ndim != 3: - raise ValueError("Got image with ndim=%d, don't know" - " what to do." % image.ndim) + raise ValueError("Felzenswalb segmentation can only operate on RGB and" + " grey images, but input array of ndim %d given." + % image.ndim) # assume we got 2d image with multiple channels n_channels = image.shape[2] if n_channels != 3: warnings.warn("Got image with %d channels. Is that really what you" - " wanted?" % image.shape[2]) + " wanted?" % image.shape[2]) segmentations = [] # compute quickshift for each channel for c in xrange(n_channels): channel = np.ascontiguousarray(image[:, :, c]) s = _felzenszwalb_grey(channel, scale=scale, sigma=sigma, - min_size=min_size) + min_size=min_size) segmentations.append(s) # put pixels in same segment only if in the same segment in all images @@ -70,7 +71,7 @@ def felzenszwalb(image, scale=1, sigma=0.8, min_size=20): n0 = segmentations[0].max() + 1 n1 = segmentations[1].max() + 1 segmentation = (segmentations[0] + segmentations[1] * n0 - + segmentations[2] * n0 * n1) + + segmentations[2] * n0 * n1) # make segment labels consecutive numbers starting at 0 labels = np.unique(segmentation, return_inverse=True)[1] return labels.reshape(image.shape[:2]) diff --git a/skimage/segmentation/_quickshift.pyx b/skimage/segmentation/_quickshift.pyx index a924d72f..57009ad1 100644 --- a/skimage/segmentation/_quickshift.pyx +++ b/skimage/segmentation/_quickshift.pyx @@ -26,30 +26,30 @@ def quickshift(image, ratio=1., float kernel_size=5, max_dist=10, return_tree=Fa Parameters ---------- - image: (width, height, channels) ndarray - Input image - ratio: float, between 0 and 1. + image : (width, height, channels) ndarray + Input image. + ratio : float, between 0 and 1. Balances color-space proximity and image-space proximity. Higher values give more weight to color-space. - kernel_size: float + kernel_size : float Width of Gaussian kernel used in smoothing the - sample density. Higher means less clusters. - max_dist: float + sample density. Higher means fewer clusters. + max_dist : float Cut-off point for data distances. - Higher means less clusters. - return_tree: bool + Higher means fewer clusters. + return_tree : bool Whether to return the full segmentation hierarchy tree and distances. - sigma: float + sigma : float Width for Gaussian smoothing as preprocessing. Zero means no smoothing. - convert2lab: bool + convert2lab : bool Whether the input should be converted to Lab colorspace prior to - segmentation. For this purpose, the input is assumed to be RGB. - random_seed: None or int - Random seed used for breaking ties + segmentation. For this purpose, the input is assumed to be RGB. + random_seed : None or int + Random seed used for breaking ties. Returns ------- - segment_mask: ndarray, [width, height] + segment_mask : (width, height) ndarray Integer mask indicating segment labels. Notes diff --git a/skimage/segmentation/_slic.pyx b/skimage/segmentation/_slic.pyx index 684740d6..a4f37fb2 100644 --- a/skimage/segmentation/_slic.pyx +++ b/skimage/segmentation/_slic.pyx @@ -12,24 +12,24 @@ def slic(image, n_segments=100, ratio=10., max_iter=10, sigma=1, Parameters ---------- - image: (width, height, 3) ndarray - Input image + image : (width, height, 3) ndarray + Input image. ratio: float Balances color-space proximity and image-space proximity. Higher values give more weight to color-space. - max_iter: int - maximum number of iterations of k-means - sigma: float + max_iter : int + Maximum number of iterations of k-means. + sigma : float Width of Gaussian smoothing kernel for preprocessing. Zero means no smoothing. - convert2lab: bool + convert2lab : bool Whether the input should be converted to Lab colorspace prior to segmentation. For this purpose, the input is assumed to be RGB. Highly recommended. Returns ------- - segment_mask: ndarray, [width, height] + segment_mask : (width, height) ndarray Integer mask indicating segment labels. Notes @@ -100,7 +100,7 @@ def slic(image, n_segments=100, ratio=10., max_iter=10, sigma=1, mean_entry = current_mean dist_mean = 0 for c in range(5): - # you would think the compiler can optimize this + # you would think the compiler can optimize the squaring # itself. mine can't (with O2) tmp = current_pixel[0] - mean_entry[0] dist_mean += tmp * tmp diff --git a/skimage/segmentation/felzenszwalb_cy.pyx b/skimage/segmentation/felzenszwalb_cy.pyx index c5f3e705..d2c2e00a 100644 --- a/skimage/segmentation/felzenszwalb_cy.pyx +++ b/skimage/segmentation/felzenszwalb_cy.pyx @@ -14,7 +14,7 @@ def _felzenszwalb_grey(image, double scale=1, sigma=0.8, int min_size=20): """Felzenszwalb's efficient graph based segmentation for a single channel. Produces an oversegmentation of a 2d image using a fast, minimum spanning - tree based clustering on the image grid. + tree based clustering on the image grid. The number of produced segments as well as their size can only be controlled indirectly through ``scale``. Segment size within an image can vary greatly depending on local contrast. @@ -22,11 +22,12 @@ def _felzenszwalb_grey(image, double scale=1, sigma=0.8, int min_size=20): Parameters ---------- image: ndarray - Input image + Input image. scale: float Sets the obervation level. Higher means larger clusters. sigma: float - Width of Gaussian kernel used in preprocessing. + Width of Gaussian smoothing kernel used in preprocessing. + Larger sigma gives smother segment boundaries. min_size: int Minimum component size. Enforced using postprocessing. diff --git a/skimage/segmentation/tests/test_felzenszwalb.py b/skimage/segmentation/tests/test_felzenszwalb.py index fe68c443..ebda2a38 100644 --- a/skimage/segmentation/tests/test_felzenszwalb.py +++ b/skimage/segmentation/tests/test_felzenszwalb.py @@ -1,7 +1,7 @@ import numpy as np from numpy.testing import assert_equal, assert_array_equal from nose.tools import assert_greater -from skimage.segmentation import felzenszwalb_segmentation +from skimage.segmentation import felzenszwalb def test_grey(): @@ -10,7 +10,7 @@ def test_grey(): img[:10, 10:] = 0.2 img[10:, :10] = 0.4 img[10:, 10:] = 0.6 - seg = felzenszwalb_segmentation(img, sigma=0) + seg = felzenszwalb(img, sigma=0) # we expect 4 segments: assert_equal(len(np.unique(seg)), 4) # that mostly respect the 4 regions: @@ -25,7 +25,7 @@ def test_color(): img[:10, :10, 0] = 1 img[10:, :10, 1] = 1 img[10:, 10:, 2] = 1 - seg = felzenszwalb_segmentation(img, sigma=0) + seg = felzenszwalb(img, sigma=0) # we expect 4 segments: assert_equal(len(np.unique(seg)), 4) assert_array_equal(seg[:10, :10], 0)