ENH addressed (hopefully all) of Tony's and Stefan's comments.

This commit is contained in:
Andreas Mueller
2012-08-20 20:22:06 +01:00
parent 37c0ffe072
commit fe2a4334fa
6 changed files with 48 additions and 47 deletions
+4 -5
View File
@@ -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
+15 -14
View File
@@ -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])
+14 -14
View File
@@ -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
+8 -8
View File
@@ -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
+4 -3
View File
@@ -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.
@@ -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)