注意
转到末尾下载完整的示例代码。或通过 Binder 在您的浏览器中运行此示例
主动轮廓模型#
主动轮廓模型是一种将开放或闭合样条拟合到图像中的线条或边缘的方法 [1]。它的工作原理是最小化能量,该能量部分由图像定义,部分由样条的形状定义:长度和平滑度。最小化在形状能量中隐式完成,在图像能量中显式完成。
在以下两个示例中,使用了主动轮廓模型(1)通过将闭合曲线拟合到面部的边缘来从图像的其余部分分割人脸,(2)在两个固定点之间找到最暗的曲线,同时遵守平滑度考虑。通常,最好在分析之前稍微平滑一下图像,如下例所示。
我们在宇航员的脸周围初始化一个圆,并使用默认边界条件 boundary_condition='periodic'
来拟合闭合曲线。默认参数 w_line=0, w_edge=1
将使曲线朝边缘搜索,例如脸部的边界。
import numpy as np
import matplotlib.pyplot as plt
from skimage.color import rgb2gray
from skimage import data
from skimage.filters import gaussian
from skimage.segmentation import active_contour
img = data.astronaut()
img = rgb2gray(img)
s = np.linspace(0, 2 * np.pi, 400)
r = 100 + 100 * np.sin(s)
c = 220 + 100 * np.cos(s)
init = np.array([r, c]).T
snake = active_contour(
gaussian(img, sigma=3, preserve_range=False),
init,
alpha=0.015,
beta=10,
gamma=0.001,
)
fig, ax = plt.subplots(figsize=(7, 7))
ax.imshow(img, cmap=plt.cm.gray)
ax.plot(init[:, 1], init[:, 0], '--r', lw=3)
ax.plot(snake[:, 1], snake[:, 0], '-b', lw=3)
ax.set_xticks([]), ax.set_yticks([])
ax.axis([0, img.shape[1], img.shape[0], 0])
plt.show()
这里我们在两个点 (5, 136)
和 (424, 50)
之间初始化一条直线,并通过给出边界条件 boundary_condition='fixed'
来要求样条在那里有它的端点。我们还通过给出负的 w_line
值来使算法搜索暗线。
img = data.text()
r = np.linspace(136, 50, 100)
c = np.linspace(5, 424, 100)
init = np.array([r, c]).T
snake = active_contour(
gaussian(img, sigma=1, preserve_range=False),
init,
boundary_condition='fixed',
alpha=0.1,
beta=1.0,
w_line=-5,
w_edge=0,
gamma=0.1,
)
fig, ax = plt.subplots(figsize=(9, 5))
ax.imshow(img, cmap=plt.cm.gray)
ax.plot(init[:, 1], init[:, 0], '--r', lw=3)
ax.plot(snake[:, 1], snake[:, 0], '-b', lw=3)
ax.set_xticks([]), ax.set_yticks([])
ax.axis([0, img.shape[1], img.shape[0], 0])
plt.show()
脚本的总运行时间: (0 分钟 2.480 秒)