Active contour updates. Now works with scipy<0.14

This commit is contained in:
Julius Bier Kirekgaard
2015-09-05 13:29:59 +01:00
parent 94b335fb2e
commit 8d344d090f
4 changed files with 51 additions and 32 deletions
+3 -3
View File
@@ -28,7 +28,7 @@ import matplotlib.pyplot as plt
from skimage.color import rgb2gray
from skimage import data
from skimage.filters import gaussian_filter
from skimage.segmentation import active_contour_model
from skimage.segmentation import active_contour
img = data.astronaut()
img = rgb2gray(img)
@@ -38,7 +38,7 @@ x = 220 + 100*np.cos(s)
y = 100 + 100*np.sin(s)
init = np.array([x, y]).T
snake = active_contour_model(gaussian_filter(img, 3),
snake = active_contour(gaussian_filter(img, 3),
init, alpha=0.015, beta=10, gamma=0.001)
fig = plt.figure(figsize=(7, 7))
@@ -65,7 +65,7 @@ x = np.linspace(5, 424, 100)
y = np.linspace(136, 50, 100)
init = np.array([x, y]).T
snake = active_contour_model(gaussian_filter(img, 1), init, bc='fixed',
snake = active_contour(gaussian_filter(img, 1), init, bc='fixed',
alpha=0.1, beta=1.0, w_line=-5, w_edge=0, gamma=0.1)
fig = plt.figure(figsize=(9, 5))
+2 -2
View File
@@ -1,5 +1,5 @@
from .random_walker_segmentation import random_walker
from .active_contour_model import active_contour_model
from .active_contour_model import active_contour
from ._felzenszwalb import felzenszwalb
from .slic_superpixels import slic
from ._quickshift import quickshift
@@ -9,7 +9,7 @@ from ._join import join_segmentations, relabel_from_one, relabel_sequential
__all__ = ['random_walker',
'active_contour_model',
'active_contour',
'felzenszwalb',
'slic',
'quickshift',
+34 -15
View File
@@ -1,13 +1,14 @@
import warnings
import numpy as np
from skimage import img_as_float
import scipy.linalg
from scipy.interpolate import RectBivariateSpline
from scipy.interpolate import RectBivariateSpline, interp2d
from skimage.filters import sobel
def active_contour_model(image, snake, alpha=0.01, beta=0.1,
w_line=0, w_edge=1, gamma=0.01,
bc='periodic', max_px_move=1.0,
max_iterations=2500, convergence=0.1):
def active_contour(image, snake, alpha=0.01, beta=0.1,
w_line=0, w_edge=1, gamma=0.01,
bc='periodic', max_px_move=1.0,
max_iterations=2500, convergence=0.1):
"""Active contour model.
Active contours by fitting snakes to features of images. Supports single
@@ -59,20 +60,28 @@ def active_contour_model(image, snake, alpha=0.01, beta=0.1,
--------
>>> from skimage.draw import circle_perimeter
>>> from skimage.filters import gaussian_filter
Create and smooth image:
>>> # Create and smooth image:
>>> img = np.zeros((100, 100))
>>> rr, cc = circle_perimeter(35, 45, 25)
>>> img[rr, cc] = 1
>>> img = gaussian_filter(img, 2)
Initiliaze spline:
>>>> # Initiliaze spline:
>>> s = np.linspace(0, 2*np.pi,100)
>>> init = 50*np.array([np.cos(s), np.sin(s)]).T+50
Fit spline to image:
>>> # Fit spline to image:
>>> snake = active_contour_model(img, init, w_edge=0, w_line=1)
>>> int(np.mean(np.sqrt((45-snake[:, 0])**2 + (35-snake[:, 1])**2)))
25
"""
scipy_version = map(int, scipy.__version__.split('.'))
new_scipy = scipy_version[0]>0 or \
(scipy_version[0]==0 and scipy_version[1]>=14)
if not new_scipy:
warnings.warn('You are using an old version of scipy. '
'Upgrading to a version newer than 0.14.0 '
'will signifcantly improve the performance '
'of this algorithm.')
max_iterations = int(max_iterations)
if max_iterations <= 0:
@@ -109,8 +118,13 @@ def active_contour_model(image, snake, alpha=0.01, beta=0.1,
img = w_line*img + w_edge*edge[0]
# Interpolate for smoothness:
intp = RectBivariateSpline(np.arange(img.shape[1]),
np.arange(img.shape[0]), img.T, kx=2, ky=2, s=0)
if new_scipy:
intp = RectBivariateSpline(np.arange(img.shape[1]),
np.arange(img.shape[0]), img.T, kx=2, ky=2, s=0)
else:
intp = np.vectorize(interp2d(np.arange(img.shape[1]),
np.arange(img.shape[0]), img, kind='cubic', copy=False,
bounds_error=False, fill_value=0))
x, y = snake[:, 0].copy(), snake[:, 1].copy()
xsave = np.empty((convergence_order, len(x)))
@@ -156,13 +170,17 @@ def active_contour_model(image, snake, alpha=0.01, beta=0.1,
A[-2, -4:] = [-1, 3, -3, 1]
efree = True
# Only one inversion is needed:
# Only one inversion is needed for implicit spline energy minimization:
inv = scipy.linalg.inv(A+gamma*np.eye(n))
# Explcit time stepping for image energy minimization:
# Explicit time stepping for image energy minimization:
for i in xrange(max_iterations):
fx = intp(x, y, dx=1, grid=False)
fy = intp(x, y, dy=1, grid=False)
if new_scipy:
fx = intp(x, y, dx=1, grid=False)
fy = intp(x, y, dy=1, grid=False)
else:
fx = intp(x, y, dx=1)
fy = intp(x, y, dy=1)
if sfixed:
fx[0] = 0
fy[0] = 0
@@ -190,7 +208,8 @@ def active_contour_model(image, snake, alpha=0.01, beta=0.1,
x[:] += dx
y[:] += dy
# Convergence criteria:
# Convergence criteria needs to compare to a number of previous
# configurations since oscillations can occur.
j = i%(convergence_order+1)
if j < convergence_order:
xsave[j, :] = x
@@ -2,7 +2,7 @@ import numpy as np
from skimage import data
from skimage.color import rgb2gray
from skimage.filters import gaussian_filter
from skimage.segmentation import active_contour_model
from skimage.segmentation import active_contour
from numpy.testing import assert_equal, assert_allclose, assert_raises
def test_periodic_reference():
@@ -12,7 +12,7 @@ def test_periodic_reference():
x = 220 + 100*np.cos(s)
y = 100 + 100*np.sin(s)
init = np.array([x, y]).T
snake = active_contour_model(gaussian_filter(img, 3), init,
snake = active_contour(gaussian_filter(img, 3), init,
alpha=0.015, beta=10, w_line=0, w_edge=1, gamma=0.001)
refx = [299, 298, 298, 298, 298, 297, 297, 296, 296, 295]
refy = [98, 99, 100, 101, 102, 103, 104, 105, 106, 108]
@@ -25,7 +25,7 @@ def test_fixed_reference():
x = np.linspace(5, 424, 100)
y = np.linspace(136, 50, 100)
init = np.array([x, y]).T
snake = active_contour_model(gaussian_filter(img, 1), init, bc='fixed',
snake = active_contour(gaussian_filter(img, 1), init, bc='fixed',
alpha=0.1, beta=1.0, w_line=-5, w_edge=0, gamma=0.1)
refx = [5, 9, 13, 17, 21, 25, 30, 34, 38, 42]
refy = [136, 135, 134, 133, 132, 131, 129, 128, 127, 125]
@@ -38,7 +38,7 @@ def test_free_reference():
x = np.linspace(5, 424, 100)
y = np.linspace(70, 40, 100)
init = np.array([x, y]).T
snake = active_contour_model(gaussian_filter(img, 3), init, bc='free',
snake = active_contour(gaussian_filter(img, 3), init, bc='free',
alpha=0.1, beta=1.0, w_line=-5, w_edge=0, gamma=0.1)
refx = [10, 13, 16, 19, 23, 26, 29, 32, 36, 39]
refy = [76, 76, 75, 74, 73, 72, 71, 70, 69, 69]
@@ -57,17 +57,17 @@ def test_RGB():
x = np.linspace(5, 424, 100)
y = np.linspace(136, 50, 100)
init = np.array([x, y]).T
snake = active_contour_model(imgR, init, bc='fixed',
snake = active_contour(imgR, init, bc='fixed',
alpha=0.1, beta=1.0, w_line=-5, w_edge=0, gamma=0.1)
refx = [5, 9, 13, 17, 21, 25, 30, 34, 38, 42]
refy = [136, 135, 134, 133, 132, 131, 129, 128, 127, 125]
assert_equal(np.array(snake[:10, 0], dtype=np.int32), refx)
assert_equal(np.array(snake[:10, 1], dtype=np.int32), refy)
snake = active_contour_model(imgG, init, bc='fixed',
snake = active_contour(imgG, init, bc='fixed',
alpha=0.1, beta=1.0, w_line=-5, w_edge=0, gamma=0.1)
assert_equal(np.array(snake[:10, 0], dtype=np.int32), refx)
assert_equal(np.array(snake[:10, 1], dtype=np.int32), refy)
snake = active_contour_model(imgRGB, init, bc='fixed',
snake = active_contour(imgRGB, init, bc='fixed',
alpha=0.1, beta=1.0, w_line=-5/3., w_edge=0, gamma=0.1)
assert_equal(np.array(snake[:10, 0], dtype=np.int32), refx)
assert_equal(np.array(snake[:10, 1], dtype=np.int32), refy)
@@ -80,15 +80,15 @@ def test_end_points():
x = 220 + 100*np.cos(s)
y = 100 + 100*np.sin(s)
init = np.array([x, y]).T
snake = active_contour_model(gaussian_filter(img, 3), init,
snake = active_contour(gaussian_filter(img, 3), init,
bc='periodic', alpha=0.015, beta=10, w_line=0, w_edge=1, gamma=0.001,
max_iterations=100)
assert np.sum(np.abs(snake[0, :]-snake[-1, :])) < 2
snake = active_contour_model(gaussian_filter(img, 3), init,
snake = active_contour(gaussian_filter(img, 3), init,
bc='free', alpha=0.015, beta=10, w_line=0, w_edge=1, gamma=0.001,
max_iterations=100)
assert np.sum(np.abs(snake[0, :]-snake[-1, :])) > 2
snake = active_contour_model(gaussian_filter(img, 3), init,
snake = active_contour(gaussian_filter(img, 3), init,
bc='fixed', alpha=0.015, beta=10, w_line=0, w_edge=1, gamma=0.001,
max_iterations=100)
assert_allclose(snake[0, :], [x[0], y[0]], atol=1e-5)
@@ -99,9 +99,9 @@ def test_bad_input():
x = np.linspace(5, 424, 100)
y = np.linspace(136, 50, 100)
init = np.array([x, y]).T
assert_raises(ValueError, active_contour_model, img, init,
assert_raises(ValueError, active_contour, img, init,
bc='wrong')
assert_raises(ValueError, active_contour_model, img, init,
assert_raises(ValueError, active_contour, img, init,
max_iterations=-15)