Main Content

本页翻译不是最新的。点击此处可查看最新英文版本。

activecontour

使用主动轮廓 (snake) 区域增长方法将图像分割成前景和背景

说明

主动轮廓方法,也称为 snake,是一种迭代式区域增长图像分割算法。使用主动轮廓算法,您可以在图像上指定初始曲线,然后使用 activecontour 函数使曲线向对象边界演化。

示例

BW = activecontour(A,mask) 使用主动轮廓将图像 A 分割成前景(对象)和背景区域。

mask 参数是一个指定主动轮廓初始状态的二值图像。mask 中对象区域(白色)的边界定义轮廓演化的初始轮廓位置,以用于分割图像。输出图像 BW 是一个二值图像,前景为白色(逻辑 true),背景为黑色(逻辑 false)。

要获得更快、更准确的分割结果,请指定靠近所需对象边界的初始轮廓位置。

BW = activecontour(A,mask,n) 通过最多迭代 n 次的轮廓演化来分割图像。

示例

BW = activecontour(A,mask,method) 将用于分割的主动轮廓方法指定为 "Chan-Vese""edge"。对于 RGB 图像,该方法必须为 "Chan-Vese"

BW = activecontour(A,mask,n,method) 使用指定的 method,通过最多迭代 n 次的轮廓演化来分割图像。

BW = activecontour(___,Name,Value) 指定控制分割各个方面的名称-值对组参数。

示例

全部折叠

读取并显示灰度图像。

I = imread('coins.png');
imshow(I)
title('Original Image')

Figure contains an axes object. The axes object with title Original Image contains an object of type image.

指定感兴趣对象周围的初始轮廓。显示该轮廓。

mask = zeros(size(I));
mask(25:end-25,25:end-25) = 1;
imshow(mask)
title('Initial Contour Location')

Figure contains an axes object. The axes object with title Initial Contour Location contains an object of type image.

使用 activecontour 函数分割图像。默认情况下,该函数通过 100 次迭代进行分割演化。

bw = activecontour(I,mask);

显示结果。经过 100 次迭代后,对象并未从背景中完全分割出来,因为原始轮廓没有接近对象边界。

imshow(bw)
title('Segmented Image, 100 Iterations')

Figure contains an axes object. The axes object with title Segmented Image, 100 Iterations contains an object of type image.

要继续进行分割演化,请增加迭代次数。经过 300 次迭代,对象从背景中完全分割出来。

bw = activecontour(I,mask,300);
imshow(bw)
title('Segmented Image, 300 Iterations')

Figure contains an axes object. The axes object with title Segmented Image, 300 Iterations contains an object of type image.

读取并显示灰度图像。

I = imread('toyobjects.png');
imshow(I)

使用 drawrectangle 函数在感兴趣的对象附近绘制初始轮廓。绘制轮廓后,使用 createMask 函数创建掩膜。

r = drawrectangle;

mask = createMask(r);

使用 'edge' 方法和 200 次迭代来分割图像。

bw = activecontour(I,mask,200,'edge');

以红色显示原始图像上的最终轮廓。

hold on;
visboundaries(bw,'Color','r'); 

显示对原始图像进行分割的结果。前景中的对象具有蓝色。

figure
imshow(labeloverlay(I,bw));

加载三维体图像数据,删除单一维度。

D = load('mri.mat');
A  = squeeze(D.D);

为初始种子点创建二维掩膜。

seedLevel = 10;
seed = A(:,:,seedLevel) > 75;
figure
imshow(seed)

Figure contains an axes object. The axes object contains an object of type image.

创建一个空的三维种子掩膜,并将种子点放入其中。

mask = zeros(size(A));
mask(:,:,seedLevel) = seed;

使用主动轮廓执行分割,指定种子掩膜。

bw = activecontour(A,mask,300);

显示三维分割后的图像。

figure;
p = patch(isosurface(double(bw)));
p.FaceColor = 'red';
p.EdgeColor = 'none';
daspect([1 1 27/128]);
camlight; 
lighting phong

Figure contains an axes object. The axes object contains an object of type patch.

输入参数

全部折叠

要分割的图像,指定为二维数值矩阵或三维数值数组。

数据类型: single | double | int8 | int16 | int32 | uint8 | uint16 | uint32

分割开始演化时的初始轮廓,指定为与 A 大小相同的二值图像。对于二维和三维灰度图像,mask 的大小必须与图像 A 的大小相匹配。对于彩色图像和多通道图像,mask 必须为二维逻辑数组,其中前两个维度与图像 A 的前两个维度相匹配。

您可以使用 ROI 对象以交互方式创建掩膜。例如,使用 drawpolygon 函数绘制一个多边形 ROI,然后使用 createMask 函数从该 ROI 创建掩膜。

数据类型: logical

分割演化中要执行的最大迭代次数,指定为正整数。当主动轮廓达到最大迭代次数时,activecontour 停止主动轮廓的演化。如果当前迭代中的轮廓位置与最近五次迭代之一中的轮廓位置相同,activecontour 也会停止演化。

如果初始轮廓位置(由 mask 指定)远离对象边界,请指定较大的 n 值以获得所需的分割结果。

分割所使用的主动轮廓方法,指定为 "Chan-Vese""edge"[1] 中介绍了基于 Chan-Vese 区域的能源模型。[2] 中介绍了基于边缘的模型,该模型类似于测地线主动轮廓。

对于 RGB 图像,该方法必须为 "Chan-Vese"

数据类型: char | string

名称-值参数

将可选的参数对组指定为 Name1=Value1,...,NameN=ValueN,其中 Name 是参数名称,Value 是对应的值。名称-值参数必须出现在其他参数后,但对各个参数对组的顺序没有要求。

示例: SmoothFactor=1.5

如果使用的是 R2021a 之前的版本,请使用逗号分隔每个名称和值,并用引号将 Name 引起来。

示例: "SmoothFactor",1.5

分割区域边界的平滑度或规则性,指定为非负数。值越高,生成的区域边界越平滑,但也可能会平滑掉较细微的细节。值越低,生成的区域边界越不规则(平滑处理越少),但可以捕获较细微的细节。"Chan-Vese" 方法的默认平滑度值为 0"edge" 方法的默认平滑度值为 1

数据类型: single | double | int8 | int16 | int32 | uint8 | uint16 | uint32

轮廓向外扩展或向内收缩的趋势,指定为数字。正值使轮廓偏向内缩(收缩)。负值使轮廓偏向外张(扩张)。此参数无法保证轮廓收缩(或扩展)。即使此参数为正值,轮廓实际上也可能会扩张。但是,与无偏差轮廓相比,指定偏差可以减缓扩展。此参数的值通常介于 -1 和 1 之间。"Chan-Vese" 方法的默认收缩偏差为 0"edge" 方法的默认收缩偏差为 0.3

数据类型: single | double | int8 | int16 | int32 | uint8 | uint16 | uint32

输出参数

全部折叠

分割后的图像,以与输入图像 A 大小相同的逻辑数组形式返回。前景是白色(逻辑 true),背景是黑色(逻辑 false)。

数据类型: logical

提示

  • activecontour 使用 mask 中区域的边界作为演化开始时轮廓的初始状态。掩膜上的孔洞可能会导致不可预测的结果。请使用 imfill 填充 mask 区域中的孔洞。

  • 如果某个区域触及图像边界,则 activecontour 在进一步处理之前,会从该区域中删除单像素层,以便该区域不会触及图像边界。

  • 要获得更快、更准确的结果,请指定靠近所需对象边界的初始轮廓位置,特别是对于 "edge" 方法。

  • 对于 "edge" 方法,主动轮廓会自然内缩(收缩)。在没有任何图像梯度的情况下,主动轮廓会自行收缩。相反,在 "Chan-Vese" 方法中,轮廓是无偏差的,轮廓可以根据图像特征自由收缩或扩展。

  • 要使用 "edge" 方法实现精确分割,请指定位于对象边界之外的初始轮廓。默认情况下,使用 "edge" 方法的主动轮廓会偏向收缩。

  • 如果对象区域具有明显不同的灰度强度,则 "Chan-Vese" 方法 [1] 可能不会分割图像中的所有对象。例如,如果图像同时包含比背景亮的对象和比背景暗的对象,"Chan-Vese" 方法通常只会分割出暗的对象或分割出亮的对象。

算法

activecontour 使用稀疏场水平集方法(类似于 [3] 中所述的方法)来实现主动轮廓演化。

参考

[1] T. F. Chan, L. A. Vese, Active contours without edges. IEEE Transactions on Image Processing, Volume 10, Issue 2, pp. 266-277, 2001.

[2] V. Caselles, R. Kimmel, G. Sapiro, Geodesic active contours. International Journal of Computer Vision, Volume 22, Issue 1, pp. 61-79, 1997.

[3] R. T. Whitaker, A level-set approach to 3d reconstruction from range data. International Journal of Computer Vision, Volume 29, Issue 3, pp. 203-231, 1998.

版本历史记录

在 R2013a 中推出