skimage.segmentation
#
将图像划分为有意义的区域或边界。
主动轮廓模型。 |
|
Chan-Vese 分割算法。 |
|
创建具有二进制值的棋盘格水平集。 |
|
清除连接到标签图像边界的对象。 |
|
创建具有二进制值的圆盘水平集。 |
|
在标签图像中扩展标签 |
|
计算 Felsenszwalb 的高效基于图的图像分割。 |
|
返回布尔数组,其中标记区域之间的边界为 True。 |
|
与洪水填充相对应的掩码。 |
|
对图像执行洪水填充。 |
|
梯度幅度的倒数。 |
|
返回两个输入分割的联合。 |
|
返回突出显示标记区域之间边界的图像。 |
|
无边界的形态主动轮廓(MorphACWE) |
|
形态测地线主动轮廓 (MorphGAC)。 |
|
使用颜色-(x,y) 空间中的快速移位聚类来分割图像。 |
|
来自标记的分割的随机游走算法。 |
|
将任意标签重新标记为 {offset, 。 |
|
使用颜色-(x,y,z) 空间中的 k 均值聚类分割图像。 |
|
找到从给定标记淹没的图像中的分水岭盆地。 |
- skimage.segmentation.active_contour(image, snake, alpha=0.01, beta=0.1, w_line=0, w_edge=1, gamma=0.01, max_px_move=1.0, max_num_iter=2500, convergence=0.1, *, boundary_condition='periodic')[source]#
主动轮廓模型。
通过将蛇拟合到图像特征来实现主动轮廓。 支持单通道和多通道 2D 图像。 蛇可以是周期性的(用于分割)或具有固定和/或自由端点。 输出蛇与输入边界的长度相同。 由于点数是固定的,请确保初始蛇具有足够的点来捕获最终轮廓的细节。
- 参数:
- image(M, N) 或 (M, N, 3) ndarray
输入图像。
- snake(K, 2) ndarray
初始蛇坐标。 对于周期性边界条件,端点不得重复。
- alphafloat,可选
蛇长度形状参数。 较高的值使蛇更快地收缩。
- betafloat,可选
蛇平滑度形状参数。 较高的值使蛇更平滑。
- w_linefloat,可选
控制对亮度的吸引力。 使用负值吸引到黑暗区域。
- w_edgefloat,可选
控制对边缘的吸引力。 使用负值将蛇排斥在边缘之外。
- gammafloat,可选
显式时间步长参数。
- max_px_movefloat,可选
每次迭代可以移动的最大像素距离。
- max_num_iterint,可选
优化蛇形状的最大迭代次数。
- convergencefloat,可选
收敛标准。
- boundary_conditionstring,可选
轮廓的边界条件。 可以是 ‘periodic’、‘free’、‘fixed’、‘free-fixed’ 或 ‘fixed-free’ 之一。 ‘periodic’ 连接蛇的两端,‘fixed’ 将端点固定到位,‘free’ 允许端点自由移动。 ‘fixed’ 和 ‘free’ 可以通过解析 ‘fixed-free’、‘free-fixed’ 来组合。 解析 ‘fixed-fixed’ 或 ‘free-free’ 分别产生与 ‘fixed’ 和 ‘free’ 相同的行为。
- 返回值:
- snake(K, 2) ndarray
优化的蛇,与输入参数形状相同。
参考文献
[1]Kass,M.;Witkin,A.;Terzopoulos,D. “Snakes:Active contour models”。 国际计算机视觉杂志 1 (4):321 (1988)。 DOI:10.1007/BF00133570
示例
>>> from skimage.draw import circle_perimeter >>> from skimage.filters import gaussian
创建并平滑图像
>>> img = np.zeros((100, 100)) >>> rr, cc = circle_perimeter(35, 45, 25) >>> img[rr, cc] = 1 >>> img = gaussian(img, sigma=2, preserve_range=False)
初始化样条曲线
>>> s = np.linspace(0, 2*np.pi, 100) >>> init = 50 * np.array([np.sin(s), np.cos(s)]).T + 50
将样条曲线拟合到图像
>>> snake = active_contour(img, init, w_edge=0, w_line=1) >>> dist = np.sqrt((45-snake[:, 0])**2 + (35-snake[:, 1])**2) >>> int(np.mean(dist)) 25
主动轮廓模型
- skimage.segmentation.chan_vese(image, mu=0.25, lambda1=1.0, lambda2=1.0, tol=0.001, max_num_iter=500, dt=0.5, init_level_set='checkerboard', extended_output=False)[source]#
Chan-Vese 分割算法。
通过演化水平集实现的主动轮廓模型。 可用于分割没有明确定义边界的对象。
- 参数:
- image(M, N) ndarray
要分割的灰度图像。
- mufloat,可选
‘边缘长度’ 权重参数。 较高的 mu 值将产生‘圆形’边缘,而接近零的值将检测更小的对象。
- lambda1float,可选
值为 ‘True’ 的输出区域的 ‘与平均值的差异’ 权重参数。 如果它低于 lambda2,则该区域的值范围将大于另一个区域。
- lambda2float,可选
值为 ‘False’ 的输出区域的 ‘与平均值的差异’ 权重参数。 如果它低于 lambda1,则该区域的值范围将大于另一个区域。
- tolfloat,正数,可选
每次迭代之间水平集变化的容差。 如果连续迭代的水平集之间的 L2 范数差除以图像的面积小于该值,则算法将假设已达到解。
- max_num_iteruint,可选
算法中断自身之前允许的最大迭代次数。
- dtfloat,可选
每次步骤计算中应用的乘法因子,用于加速算法。 虽然较高的值可能会加快算法,但它们也可能导致收敛问题。
- init_level_setstr 或 (M, N) ndarray,可选
定义算法使用的起始水平集。 如果输入字符串,将自动生成与图像大小匹配的水平集。 或者,可以定义自定义水平集,它应该是与 ‘image’ 形状相同的浮点值数组。 接受的字符串值如下。
- ‘checkerboard’
起始水平集定义为 sin(x/5*pi)*sin(y/5*pi),其中 x 和 y 是像素坐标。 此水平集收敛速度快,但可能无法检测隐式边缘。
- ‘disk’
起始水平集定义为图像中心距离的相反数减去图像宽度和图像高度之间最小值的二分之一。 这种方法速度稍慢,但更有可能正确检测隐式边缘。
- ‘small disk’
起始水平集定义为图像中心距离的相反数减去图像宽度和图像高度之间最小值的四分之一。
- extended_outputbool,可选
如果设置为 True,返回值将是一个元组,包含三个返回值(见下文)。 如果设置为 False,这是默认值,则只返回 ‘segmentation’ 数组。
- 返回值:
- segmentation(M, N) ndarray,bool
算法产生的分割。
- phi(M, N) ndarray of floats
算法计算的最终水平集。
- energies浮点数列表
显示算法每一步的“能量”演变。这应该可以用来检查算法是否收敛。
注释
Chan-Vese 算法旨在分割边界不明确的目标。该算法基于水平集,这些水平集通过迭代演化来最小化能量,能量由加权值定义,这些值对应于分割区域外部平均值之差的总和、分割区域内部平均值之差的总和以及依赖于分割区域边界长度的项。
该算法最初由 Tony Chan 和 Luminita Vese 在一篇名为“An Active Contour Model Without Edges” 的出版物中提出 [1]。
该算法的这种实现有一些简化,因为它没有实现原始论文中描述的面积因子“nu”,并且仅适用于灰度图像。
lambda1 和 lambda2 的典型值为 1。如果“背景”在分布方面与分割对象有很大不同(例如,具有不同强度数字的均匀黑色图像),那么这些值应该彼此不同。
mu 的典型值在 0 到 1 之间,尽管在处理轮廓非常模糊的形状时可以使用更高的值。
该算法试图最小化的“能量”定义为区域内平均值之差的平方和,并按“lambda”因子加权,再加上轮廓长度乘以“mu”因子。
仅支持二维灰度图像,并且没有实现原始文章中描述的面积项。
参考文献
[1]An Active Contour Model without Edges,Tony Chan 和 Luminita Vese,Scale-Space Theories in Computer Vision,1999,DOI:10.1007/3-540-48236-9_13
[2]Chan-Vese Segmentation,Pascal Getreuer Image Processing On Line,2 (2012),pp. 214-224,DOI:10.5201/ipol.2012.g-cv
[3]The Chan-Vese Algorithm - Project Report,Rami Cohen,2011 arXiv:1107.2782
Chan-Vese 分割
- skimage.segmentation.checkerboard_level_set(image_shape, square_size=5)[source]#
创建具有二进制值的棋盘格水平集。
- 参数:
- image_shape正整数元组
图像的形状。
- square_sizeint,可选
棋盘格方块的大小。默认为 5。
- 返回值:
- out形状为 image_shape 的数组
棋盘格的二元水平集。
另请参阅
形态蛇
- skimage.segmentation.clear_border(labels, buffer_size=0, bgval=0, mask=None, *, out=None)[source]#
清除连接到标签图像边界的对象。
- 参数:
- labels(M[, N[, …, P]]) 整型或布尔型数组
图像数据标签。
- buffer_sizeint,可选
检查的边框宽度。默认情况下,仅移除接触图像外部的物体。
- bgvalfloat 或 int,可选
已清除的物体将设置为该值。
- mask布尔型 ndarray,与 image 形状相同,可选。
图像数据掩码。标签图像中与掩码的 False 像素重叠的物体将被移除。如果已定义,则将忽略参数 buffer_size。
- outndarray
与 labels 形状相同的数组,输出将放置到其中。默认情况下,将创建一个新数组。
- 返回值:
- out(M[, N[, …, P]]) 数组
已清除边框的图像数据标签
示例
>>> import numpy as np >>> from skimage.segmentation import clear_border >>> labels = np.array([[0, 0, 0, 0, 0, 0, 0, 1, 0], ... [1, 1, 0, 0, 1, 0, 0, 1, 0], ... [1, 1, 0, 1, 0, 1, 0, 0, 0], ... [0, 0, 0, 1, 1, 1, 1, 0, 0], ... [0, 1, 1, 1, 1, 1, 1, 1, 0], ... [0, 0, 0, 0, 0, 0, 0, 0, 0]]) >>> clear_border(labels) array([[0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0, 0, 0, 0], [0, 0, 0, 1, 0, 1, 0, 0, 0], [0, 0, 0, 1, 1, 1, 1, 0, 0], [0, 1, 1, 1, 1, 1, 1, 1, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0]]) >>> mask = np.array([[0, 0, 1, 1, 1, 1, 1, 1, 1], ... [0, 0, 1, 1, 1, 1, 1, 1, 1], ... [1, 1, 1, 1, 1, 1, 1, 1, 1], ... [1, 1, 1, 1, 1, 1, 1, 1, 1], ... [1, 1, 1, 1, 1, 1, 1, 1, 1], ... [1, 1, 1, 1, 1, 1, 1, 1, 1]]).astype(bool) >>> clear_border(labels, mask=mask) array([[0, 0, 0, 0, 0, 0, 0, 1, 0], [0, 0, 0, 0, 1, 0, 0, 1, 0], [0, 0, 0, 1, 0, 1, 0, 0, 0], [0, 0, 0, 1, 1, 1, 1, 0, 0], [0, 1, 1, 1, 1, 1, 1, 1, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0]])
- skimage.segmentation.disk_level_set(image_shape, *, center=None, radius=None)[source]#
创建具有二进制值的圆盘水平集。
- 参数:
- image_shape正整数元组
图像的形状
- center正整数元组,可选
以 (行,列) 形式给出的圆盘中心的坐标。如果没有给出,则默认为图像的中心。
- radiusfloat,可选
圆盘的半径。如果没有给出,则将其设置为图像最小尺寸的 75%。
- 返回值:
- out形状为 image_shape 的数组
具有给定 radius 和 center 的圆盘的二元水平集。
- skimage.segmentation.expand_labels(label_image, distance=1, spacing=1)[source]#
在标签图像中扩展标签
distance
像素,而不会重叠。给定一个标签图像,
expand_labels
将标签区域(连通分量)向外扩展最多distance
个单位,而不会溢出到相邻区域。更具体地说,每个距离连接分量 <=distance
个像素的欧几里得距离内的背景像素都将被分配连接分量的标签。spacing 参数可用于指定用于为各向异性图像计算欧几里得距离的距离变换的间隔率。如果多个连通分量在distance
个像素内的一个背景像素内,则将分配最接近连接分量的标签值(有关多个标签在相等距离处的案例,请参见注释)。- 参数:
- label_imagedtype 为 int 的 ndarray
标签图像
- distancefloat
用于扩展标签的欧几里得距离(以像素为单位)。默认为 1。
- spacingfloat 或 float 序列,可选
每个维度上元素的间距。如果是序列,则必须与输入等级的长度相同;如果是单个数字,则将其用于所有轴。如果没有指定,则隐含单位网格间距。
- 返回值:
- enlarged_labelsdtype 为 int 的 ndarray
已标记的数组,其中所有连接区域都已扩大
注释
如果标签之间的距离大于
distance
个像素,则这等效于使用半径为distance
的圆盘或超球的形态膨胀。但是,与形态膨胀相反,expand_labels
不会将标签区域扩展到相邻区域。这种
expand_labels
的实现源自 CellProfiler [1],在那里它被称为模块“IdentifySecondaryObjects (Distance-N)” [2]。当一个像素到多个区域的距离相同时,存在一个重要的边缘案例,因为没有定义哪个区域会扩展到该空间。在这里,确切的行为取决于
scipy.ndimage.distance_transform_edt
的上游实现。参考文献
示例
>>> labels = np.array([0, 1, 0, 0, 0, 0, 2]) >>> expand_labels(labels, distance=1) array([1, 1, 1, 0, 0, 2, 2])
标签不会相互覆盖
>>> expand_labels(labels, distance=3) array([1, 1, 1, 1, 2, 2, 2])
在平局的情况下,行为是未定义的,但目前会解析为在词典顺序中距离
(0,) * ndim
最近的标签。>>> labels_tied = np.array([0, 1, 0, 2, 0]) >>> expand_labels(labels_tied, 1) array([1, 1, 1, 2, 2]) >>> labels2d = np.array( ... [[0, 1, 0, 0], ... [2, 0, 0, 0], ... [0, 3, 0, 0]] ... ) >>> expand_labels(labels2d, 1) array([[2, 1, 1, 0], [2, 2, 0, 0], [2, 3, 3, 0]]) >>> expand_labels(labels2d, 1, spacing=[1, 0.5]) array([[1, 1, 1, 1], [2, 2, 2, 0], [3, 3, 3, 3]])
扩展分割标签,不重叠
- skimage.segmentation.felzenszwalb(image, scale=1, sigma=0.8, min_size=20, *, channel_axis=-1)[source]#
计算 Felzenszwalb 的高效基于图的图像分割。
使用基于快速最小生成树的图像网格聚类,生成多通道(即 RGB)图像的过度分割。参数
scale
设置观测水平。更高的尺度意味着更少更大的段。sigma
是高斯核的直径,用于在分割之前对图像进行平滑处理。生成的段数及其大小只能通过
scale
间接控制。图像内的段大小可能会根据局部对比度而变化很大。对于 RGB 图像,该算法使用颜色空间中像素之间的欧氏距离。
- 参数:
- image(M, N[, 3]) ndarray
输入图像。
- scalefloat
自由参数。值越大,集群越大。
- sigmafloat
预处理中使用的 Gaussian 核的宽度(标准差)。
- min_sizeint
最小组件大小。使用后处理强制执行。
- channel_axisint 或 None,可选
如果为 None,则假设图像为灰度(单通道)图像。否则,此参数指示数组的哪个轴对应于通道。
版本 0.19 中添加:
channel_axis
在 0.19 中添加。
- 返回值:
- segment_mask(M, N) ndarray
表示段标签的整数掩码。
注释
原文中使用的 k 参数在这里重命名为 scale。
参考文献
[1]基于图的图像分割的有效方法,Felzenszwalb,P.F. 和 Huttenlocher,D.P. 国际计算机视觉杂志,2004 年
示例
>>> from skimage.segmentation import felzenszwalb >>> from skimage.data import coffee >>> img = coffee() >>> segments = felzenszwalb(img, scale=3.0, sigma=0.95, min_size=5)
分割和超像素算法的比较
- skimage.segmentation.find_boundaries(label_img, connectivity=1, mode='thick', background=0)[source]#
返回布尔数组,其中标记区域之间的边界为 True。
- 参数:
- label_imgint 或 bool 数组
一个数组,其中不同的区域用不同的整数或布尔值标记。
- connectivityint,取值范围为 {1, …, label_img.ndim},可选
如果任何相邻像素的标签不同,则像素被视为边界像素。connectivity 控制哪些像素被视为相邻像素。连接值为 1(默认)表示共享边(二维)或面的像素(三维)被视为相邻像素。连接值为 label_img.ndim 表示共享角点的像素被视为相邻像素。
- modestring,取值范围为 {‘thick’, ‘inner’, ‘outer’, ‘subpixel’}
如何标记边界
thick:任何不完全被相同标签(由 connectivity 定义)的像素包围的像素都将被标记为边界。这将导致厚度为 2 个像素的边界。
inner:在对象内部轮廓像素,使背景像素保持原样。
outer:在对象边界周围的背景中轮廓像素。当两个对象接触时,它们的边界也将被标记。
subpixel:返回一个加倍的图像,其中在适当的情况下,原始像素之间的像素被标记为边界。
- backgroundint,可选
对于模式 ‘inner’ 和 ‘outer’,需要定义一个背景标签。有关这些模式的描述,请参见 mode。
- 返回值:
- boundariesbool 数组,与 label_img 的形状相同
一个 bool 图像,其中
True
表示边界像素。对于 mode 等于 ‘subpixel’,boundaries.shape[i]
等于2 * label_img.shape[i] - 1
对于所有i
(在所有其他像素对之间插入一个像素)。
示例
>>> labels = np.array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0], ... [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], ... [0, 0, 0, 0, 0, 5, 5, 5, 0, 0], ... [0, 0, 1, 1, 1, 5, 5, 5, 0, 0], ... [0, 0, 1, 1, 1, 5, 5, 5, 0, 0], ... [0, 0, 1, 1, 1, 5, 5, 5, 0, 0], ... [0, 0, 0, 0, 0, 5, 5, 5, 0, 0], ... [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], ... [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]], dtype=np.uint8) >>> find_boundaries(labels, mode='thick').astype(np.uint8) array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 1, 1, 1, 0, 0], [0, 0, 1, 1, 1, 1, 1, 1, 1, 0], [0, 1, 1, 1, 1, 1, 0, 1, 1, 0], [0, 1, 1, 0, 1, 1, 0, 1, 1, 0], [0, 1, 1, 1, 1, 1, 0, 1, 1, 0], [0, 0, 1, 1, 1, 1, 1, 1, 1, 0], [0, 0, 0, 0, 0, 1, 1, 1, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]], dtype=uint8) >>> find_boundaries(labels, mode='inner').astype(np.uint8) array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 1, 1, 1, 0, 0], [0, 0, 1, 1, 1, 1, 0, 1, 0, 0], [0, 0, 1, 0, 1, 1, 0, 1, 0, 0], [0, 0, 1, 1, 1, 1, 0, 1, 0, 0], [0, 0, 0, 0, 0, 1, 1, 1, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]], dtype=uint8) >>> find_boundaries(labels, mode='outer').astype(np.uint8) array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 1, 1, 1, 0, 0], [0, 0, 1, 1, 1, 1, 0, 0, 1, 0], [0, 1, 0, 0, 1, 1, 0, 0, 1, 0], [0, 1, 0, 0, 1, 1, 0, 0, 1, 0], [0, 1, 0, 0, 1, 1, 0, 0, 1, 0], [0, 0, 1, 1, 1, 1, 0, 0, 1, 0], [0, 0, 0, 0, 0, 1, 1, 1, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]], dtype=uint8) >>> labels_small = labels[::2, ::3] >>> labels_small array([[0, 0, 0, 0], [0, 0, 5, 0], [0, 1, 5, 0], [0, 0, 5, 0], [0, 0, 0, 0]], dtype=uint8) >>> find_boundaries(labels_small, mode='subpixel').astype(np.uint8) array([[0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 1, 1, 1, 0], [0, 0, 0, 1, 0, 1, 0], [0, 1, 1, 1, 0, 1, 0], [0, 1, 0, 1, 0, 1, 0], [0, 1, 1, 1, 0, 1, 0], [0, 0, 0, 1, 0, 1, 0], [0, 0, 0, 1, 1, 1, 0], [0, 0, 0, 0, 0, 0, 0]], dtype=uint8) >>> bool_image = np.array([[False, False, False, False, False], ... [False, False, False, False, False], ... [False, False, True, True, True], ... [False, False, True, True, True], ... [False, False, True, True, True]], ... dtype=bool) >>> find_boundaries(bool_image) array([[False, False, False, False, False], [False, False, True, True, True], [False, True, True, True, True], [False, True, True, False, False], [False, True, True, False, False]])
- skimage.segmentation.flood(image, seed_point, *, footprint=None, connectivity=None, tolerance=None)[source]#
与洪水填充相对应的掩码。
从特定的 seed_point 开始,找到与种子值相等或在 tolerance 范围内的连接点。
- 参数:
- imagendarray
一个 n 维数组。
- seed_point元组或 int
用作洪水填充起点 image 中的点。如果图像为一维,则此点可以作为整数给出。
- footprintndarray,可选
用于确定每个评估像素的邻域的足迹(结构元素)。它必须只包含 1 和 0,并且具有与 image 相同的维数。如果没有给出,则所有相邻像素都被视为邻域的一部分(完全连接)。
- connectivityint,可选
用于确定每个评估像素的邻域的数字。与中心之间的平方距离小于或等于 connectivity 的相邻像素被视为相邻像素。如果 footprint 不为 None,则忽略。
- tolerancefloat 或 int,可选
如果为 None(默认),则相邻值必须严格等于 image 在 seed_point 处的初始值。这是最快的。如果给出值,则将在每个点进行比较,如果在容差范围内,则也将被填充(包括)。
- 返回值:
- maskndarray
返回一个与 image 形状相同的布尔数组,其中与种子点相连且等于(或在容差范围内的)区域为 True 值。所有其他值为 False。
注释
此操作的概念类比是许多光栅图形程序中的“油漆桶”工具。此函数仅返回表示填充的掩码。
如果由于内存原因需要索引而不是掩码,则用户只需对结果运行
numpy.nonzero
,保存索引,并丢弃此掩码。示例
>>> from skimage.morphology import flood >>> image = np.zeros((4, 7), dtype=int) >>> image[1:3, 1:3] = 1 >>> image[3, 0] = 1 >>> image[1:3, 4:6] = 2 >>> image[3, 6] = 3 >>> image array([[0, 0, 0, 0, 0, 0, 0], [0, 1, 1, 0, 2, 2, 0], [0, 1, 1, 0, 2, 2, 0], [1, 0, 0, 0, 0, 0, 3]])
用 5 填充连接的 1,完全连接(包括对角线)
>>> mask = flood(image, (1, 1)) >>> image_flooded = image.copy() >>> image_flooded[mask] = 5 >>> image_flooded array([[0, 0, 0, 0, 0, 0, 0], [0, 5, 5, 0, 2, 2, 0], [0, 5, 5, 0, 2, 2, 0], [5, 0, 0, 0, 0, 0, 3]])
用 5 填充连接的 1,不包括对角线点(连接性 1)
>>> mask = flood(image, (1, 1), connectivity=1) >>> image_flooded = image.copy() >>> image_flooded[mask] = 5 >>> image_flooded array([[0, 0, 0, 0, 0, 0, 0], [0, 5, 5, 0, 2, 2, 0], [0, 5, 5, 0, 2, 2, 0], [1, 0, 0, 0, 0, 0, 3]])
用容差填充
>>> mask = flood(image, (0, 0), tolerance=1) >>> image_flooded = image.copy() >>> image_flooded[mask] = 5 >>> image_flooded array([[5, 5, 5, 5, 5, 5, 5], [5, 5, 5, 5, 2, 2, 5], [5, 5, 5, 5, 2, 2, 5], [5, 5, 5, 5, 5, 5, 3]])
洪水填充
- skimage.segmentation.flood_fill(image, seed_point, new_value, *, footprint=None, connectivity=None, tolerance=None, in_place=False)[source]#
对图像执行洪水填充。
从特定的 seed_point 开始,找到与种子值相等或在 tolerance 范围内的连接点,然后将其设置为 new_value。
- 参数:
- imagendarray
一个 n 维数组。
- seed_point元组或 int
用作洪水填充起点 image 中的点。如果图像为一维,则此点可以作为整数给出。
- new_valueimage 类型
要设置整个填充的新值。这必须与 image 的 dtype 相一致。
- footprintndarray,可选
用于确定每个评估像素的邻域的足迹(结构元素)。它必须只包含 1 和 0,并且具有与 image 相同的维数。如果没有给出,则所有相邻像素都被视为邻域的一部分(完全连接)。
- connectivityint,可选
用于确定每个评估像素的邻域的数字。与中心之间的平方距离小于或等于 connectivity 的相邻像素被视为相邻像素。如果 footprint 不为 None,则忽略。
- tolerancefloat 或 int,可选
如果为 None(默认),则相邻值必须严格等于 image 在 seed_point 处的初始值才能被填充。这是最快的。如果提供容差,则在种子点正负容差范围内的相邻点将被填充(包括)。
- in_placebool,可选
如果为 True,则洪水填充将应用于 image 本身。如果为 False,则返回洪水填充的结果,而不修改输入 image(默认)。
- 返回值:
- filledndarray
返回一个与 image 形状相同的数组,其中与种子点相连且等于(或在容差范围内的)区域的值将被替换为 new_value。
注释
此操作的概念类比是许多光栅图形程序中的“油漆桶”工具。
示例
>>> from skimage.morphology import flood_fill >>> image = np.zeros((4, 7), dtype=int) >>> image[1:3, 1:3] = 1 >>> image[3, 0] = 1 >>> image[1:3, 4:6] = 2 >>> image[3, 6] = 3 >>> image array([[0, 0, 0, 0, 0, 0, 0], [0, 1, 1, 0, 2, 2, 0], [0, 1, 1, 0, 2, 2, 0], [1, 0, 0, 0, 0, 0, 3]])
用 5 填充连接的 1,完全连接(包括对角线)
>>> flood_fill(image, (1, 1), 5) array([[0, 0, 0, 0, 0, 0, 0], [0, 5, 5, 0, 2, 2, 0], [0, 5, 5, 0, 2, 2, 0], [5, 0, 0, 0, 0, 0, 3]])
用 5 填充连接的 1,不包括对角线点(连接性 1)
>>> flood_fill(image, (1, 1), 5, connectivity=1) array([[0, 0, 0, 0, 0, 0, 0], [0, 5, 5, 0, 2, 2, 0], [0, 5, 5, 0, 2, 2, 0], [1, 0, 0, 0, 0, 0, 3]])
用容差填充
>>> flood_fill(image, (0, 0), 5, tolerance=1) array([[5, 5, 5, 5, 5, 5, 5], [5, 5, 5, 5, 2, 2, 5], [5, 5, 5, 5, 2, 2, 5], [5, 5, 5, 5, 5, 5, 3]])
洪水填充
- skimage.segmentation.inverse_gaussian_gradient(image, alpha=100.0, sigma=5.0)[source]#
梯度幅度的倒数。
计算图像中梯度的幅度,然后将结果在 [0, 1] 范围内反转。平坦区域分配的值接近 1,而靠近边界的区域分配的值接近 0。
在调用
morphological_geodesic_active_contour
之前,应在图像上应用此函数或用户定义的类似函数作为预处理步骤。- 参数:
- image(M, N) 或 (L, M, N) 数组
灰度图像或体积。
- alphafloat,可选
控制反转的陡度。较大的值将使结果数组中平坦区域和边界区域之间的过渡更陡峭。
- sigmafloat,可选
应用于图像的 Gaussian 滤波器的标准差。
- 返回值:
- gimage(M, N) 或 (L, M, N) 数组
适用于
morphological_geodesic_active_contour
的预处理图像(或体积)。
- skimage.segmentation.join_segmentations(s1, s2, return_mapping: bool = False)[source]#
返回两个输入分割的联合。
S1 和 S2 的连接 J 定义为分割,其中两个体素位于同一分割中当且仅当它们在两个 S1 和 S2 中都位于同一分割中。
- 参数:
- s1, s2numpy 数组
s1 和 s2 是相同形状的标签字段。
- return_mappingbool,可选
如果为真,则返回连接的分割标签到原始标签的映射。
- 返回值:
- jnumpy 数组
s1 和 s2 的连接分割。
- map_j_to_s1ArrayMap,可选
从连接的分割 j 的标签到 s1 的标签的映射。
- map_j_to_s2ArrayMap,可选
从连接的分割 j 的标签到 s2 的标签的映射。
示例
>>> from skimage.segmentation import join_segmentations >>> s1 = np.array([[0, 0, 1, 1], ... [0, 2, 1, 1], ... [2, 2, 2, 1]]) >>> s2 = np.array([[0, 1, 1, 0], ... [0, 1, 1, 0], ... [0, 1, 1, 1]]) >>> join_segmentations(s1, s2) array([[0, 1, 3, 2], [0, 5, 3, 2], [4, 5, 5, 3]]) >>> j, m1, m2 = join_segmentations(s1, s2, return_mapping=True) >>> m1 ArrayMap(array([0, 1, 2, 3, 4, 5]), array([0, 0, 1, 1, 2, 2])) >>> np.all(m1[j] == s1) True >>> np.all(m2[j] == s2) True
查找两个分割的交集
- skimage.segmentation.mark_boundaries(image, label_img, color=(1, 1, 0), outline_color=None, mode='outer', background_label=0)[source]#
返回突出显示标记区域之间边界的图像。
- 参数:
- image(M, N[, 3]) 数组
灰度或 RGB 图像。
- label_img(M, N) 整数数组
标签数组,其中区域由不同的整数值标记。
- color长度为 3 的序列,可选
输出图像中边界的 RGB 颜色。
- outline_color长度为 3 的序列,可选
输出图像中边界周围的 RGB 颜色。如果为 None,则不绘制轮廓。
- mode字符串,{‘thick’,‘inner’,‘outer’,‘subpixel’} 中的一个,可选
查找边界的模式。
- background_labelint,可选
哪个标签被认为是背景(这仅对模式
inner
和outer
有用)。
- 返回值:
- marked(M, N, 3) 浮点数数组
在原始图像上叠加标签之间的边界的图像。
另请参阅
应用 maskSLIC 与 SLIC分割和超像素算法的比较区域邻接图 (RAG) 合并使用局部特征和随机森林的可训练分割评估分割指标
- skimage.segmentation.morphological_chan_vese(image, num_iter, init_level_set='checkerboard', smoothing=1, lambda1=1, lambda2=1, iter_callback=<function <lambda>>)[source]#
无边界的形态主动轮廓(MorphACWE)
使用形态学算子实现的无边缘主动轮廓。它可以用于分割图像和体积中的对象,而无需定义明确的边界。要求对象的内部平均看起来不同于外部(即,对象的内部区域平均应比外部区域暗或亮)。
- 参数:
- image(M, N) 或 (L, M, N) 数组
要分割的灰度图像或体积。
- num_iteruint
要运行的 num_iter 数量
- init_level_setstr,(M, N) 数组或 (L, M, N) 数组
初始水平集。如果给出数组,它将被二值化并用作初始水平集。如果给出字符串,它将定义生成具有 image 形状的合理初始水平集的方法。接受的值为 ‘checkerboard’ 和 ‘disk’。有关如何创建这些水平集的详细信息,请分别参见
checkerboard_level_set
和disk_level_set
的文档。- smoothinguint,可选
每次迭代应用平滑算子的次数。合理的数值约为 1-4。较大的值会导致更平滑的分割。
- lambda1float,可选
外部区域的权重参数。如果 lambda1 大于 lambda2,则外部区域将包含比内部区域更大的值范围。
- lambda2float,可选
内部区域的权重参数。如果 lambda2 大于 lambda1,则内部区域将包含比外部区域更大的值范围。
- iter_callback函数,可选
如果给出,此函数将在每次迭代时调用,当前水平集作为唯一参数。这对于调试或在演化过程中绘制中间结果非常有用。
- 返回值:
- out(M, N) 或 (L, M, N) 数组
最终分割(即最终水平集)
注释
这是 Chan-Vese 算法的一个版本,它使用形态学算子而不是求解偏微分方程 (PDE) 来演化轮廓。此算法中使用的形态学算子集被证明与 Chan-Vese PDE 无限小地等效(参见 [1])。但是,形态学算子不会像 PDE 中常见的那样出现数值稳定性问题(不需要找到演化的正确时间步长),并且在计算上更快。
该算法及其理论推导在 [1] 中描述。
参考文献
[1] (1,2)基于曲率的曲线和曲面演化的一种形态学方法,Pablo Márquez-Neila、Luis Baumela、Luis Álvarez。在 IEEE 模式分析与机器智能 (PAMI) 交易中,2014 年,DOI:10.1109/TPAMI.2013.106
形态蛇
- skimage.segmentation.morphological_geodesic_active_contour(gimage, num_iter, init_level_set='disk', smoothing=1, threshold='auto', balloon=0, iter_callback=<function <lambda>>)[source]#
形态测地线主动轮廓 (MorphGAC)。
使用形态学算子实现的测地线主动轮廓。它可以用于分割具有可见但噪声、杂乱、断裂边界的物体。
- 参数:
- gimage(M, N) 或 (L, M, N) 数组
要分割的预处理图像或体积。这很少是原始图像。相反,这通常是原始图像的预处理版本,它增强并突出显示要分割的对象的边界(或其他结构)。
morphological_geodesic_active_contour()
将尝试在 gimage 很小的区域停止轮廓演化。参见inverse_gaussian_gradient()
作为执行此预处理的示例函数。请注意,morphological_geodesic_active_contour()
的质量可能很大程度上取决于此预处理。- num_iteruint
要运行的 num_iter 数量。
- init_level_setstr,(M, N) 数组或 (L, M, N) 数组
初始水平集。如果给出数组,它将被二值化并用作初始水平集。如果给出字符串,它将定义生成具有 image 形状的合理初始水平集的方法。接受的值为 ‘checkerboard’ 和 ‘disk’。有关如何创建这些水平集的详细信息,请分别参见
checkerboard_level_set
和disk_level_set
的文档。- smoothinguint,可选
每次迭代应用平滑算子的次数。合理的数值约为 1-4。较大的值会导致更平滑的分割。
- thresholdfloat,可选
图像中值小于此阈值的区域将被视为边界。轮廓的演化将在这些区域停止。
- balloonfloat,可选
气球力来引导轮廓在图像的非信息区域,即图像梯度太小而无法将轮廓推向边界的区域。负值将缩小轮廓,而正值将在这些区域扩展轮廓。将其设置为零将禁用气球力。
- iter_callback函数,可选
如果给出,此函数将在每次迭代时调用,当前水平集作为唯一参数。这对于调试或在演化过程中绘制中间结果非常有用。
- 返回值:
- out(M, N) 或 (L, M, N) 数组
最终分割(即最终水平集)
注释
这是一种测地线活动轮廓 (GAC) 算法的版本,它使用形态学算子而不是求解偏微分方程 (PDE) 来演化轮廓。该算法中使用的形态学算子集合被证明与 GAC PDE 等效(见 [1])。但是,形态学算子不像 PDE 那样容易出现数值稳定性问题(例如,不需要为演化找到合适的时间步长),并且计算速度更快。
该算法及其理论推导在 [1] 中有描述。
参考文献
[1] (1,2)基于曲率的曲线和曲面演化的一种形态学方法,Pablo Márquez-Neila、Luis Baumela、Luis Álvarez。在 IEEE 模式分析与机器智能 (PAMI) 交易中,2014 年,DOI:10.1109/TPAMI.2013.106
- skimage.segmentation.quickshift(image, ratio=1.0, kernel_size=5, max_dist=10, return_tree=False, sigma=0, convert2lab=True, rng=42, *, channel_axis=-1)[source]#
使用颜色-(x,y) 空间中的快速移位聚类来分割图像。
使用快速移位模式搜索算法对图像进行过度分割。
- 参数:
- image(M, N, C) ndarray
输入图像。可以通过 channel_axis 参数指定对应于颜色通道的轴。
- ratiofloat, 可选,介于 0 和 1 之间
平衡颜色空间邻近度和图像空间邻近度。较高的值赋予颜色空间更大的权重。
- kernel_sizefloat, 可选
用于平滑样本密度的 Gaussian 核的宽度。数值越大,集群越少。
- max_distfloat, 可选
数据距离的截止点。数值越大,集群越少。
- return_treebool, 可选
是否返回完整的分割层次结构树和距离。
- sigmafloat,可选
Gaussian 平滑的宽度,作为预处理。零表示没有平滑。
- convert2labbool, 可选
输入图像在分割之前是否应该转换为 Lab 颜色空间。为此,假设输入为 RGB 格式。
- rng{
numpy.random.Generator
, int}, 可选 伪随机数生成器。默认情况下,使用 PCG64 生成器(参见
numpy.random.default_rng()
)。如果 rng 是整数,则它用于为生成器设置种子。PRNG 用于解决平局问题,默认情况下其种子为 42。
- channel_axisint, 可选
对应于颜色通道的 image 轴。默认为最后一个轴。
- 返回值:
- segment_mask(M, N) ndarray
表示段标签的整数掩码。
注释
作者建议在分割之前将图像转换为 Lab 颜色空间,尽管这不是严格必要的。要使此方法起作用,图像必须以 RGB 格式给出。
参考文献
[1]快速移位和内核方法用于模式搜索,Vedaldi,A. 和 Soatto,S. 欧洲计算机视觉会议,2008 年
分割和超像素算法的比较
- skimage.segmentation.random_walker(data, labels, beta=130, mode='cg_j', tol=0.001, copy=True, return_full_prob=False, spacing=None, *, prob_tol=0.001, channel_axis=None)[source]#
来自标记的分割的随机游走算法。
随机游走算法适用于灰度或多通道图像。
- 参数:
- data(M, N[, P][, C]) ndarray
要分阶段分割的图像。灰度 data 可以是二维或三维;多通道数据可以是三维或四维,其中 channel_axis 指定包含通道的维度。除非使用 spacing 关键字参数,否则假设数据间距是各向同性的。
- labels(M, N[, P]) 整数数组
种子标记数组,用不同的正整数标记不同的阶段。零标记的像素是未标记的像素。负标记对应于未考虑在内的非活动像素(它们从图中移除)。如果标记不是连续的整数,则将转换标记数组,使其标记连续。在多通道情况下,labels 应与 data 的单个通道具有相同的形状,即不包括表示通道的最终维度。
- betafloat,可选
随机游走运动的惩罚系数(beta 越大,扩散越难)。
- mode字符串,可用选项 {‘cg’, ‘cg_j’, ‘cg_mg’, ‘bf’}
用于在随机游走算法中求解线性系统的模式。
‘bf’(暴力):计算拉普拉斯算子的 LU 分解。对于小图像(<1024x1024)来说,这很快,但对于大图像(例如,3-D 体积)来说,速度非常慢且内存密集。
‘cg’(共轭梯度):使用 scipy.sparse.linalg 中的共轭梯度方法迭代地求解线性系统。对于大图像来说,这比暴力方法更节省内存,但速度相当慢。
‘cg_j’(带雅可比预条件器的共轭梯度):在共轭梯度方法迭代期间应用雅可比预条件器。这可能会加速 ‘cg’ 方法的收敛。
‘cg_mg’(带多重网格预条件器的共轭梯度):使用多重网格求解器计算预条件器,然后使用共轭梯度方法计算解。此模式要求安装 pyamg 模块。
- tolfloat, 可选
使用基于共轭梯度的方法(‘cg’,‘cg_j’ 和 ‘cg_mg’)求解线性系统时要达成的容差。
- copybool, 可选
如果 copy 为 False,则将用分割结果覆盖 labels 数组。如果要节省内存,请使用 copy=False。
- return_full_probbool, 可选
如果为 True,则将返回像素属于每个标记的概率,而不仅仅是最有可能的标记。
- spacing浮点数可迭代对象,可选
每个空间维度的体素间距。如果为 None,则假设每个维度的像素/体素间距为 1。
- prob_tolfloat, 可选
结果概率在区间 [0, 1] 内的容差。如果容差不满足,则会显示警告。
- channel_axisint 或 None,可选
如果为 None,则假设图像为灰度(单通道)图像。否则,此参数指示数组的哪个轴对应于通道。
版本 0.19 中添加:
channel_axis
在 0.19 中添加。
- 返回值:
- outputndarray
如果 return_full_prob 为 False,则为与 labels 具有相同形状和数据类型的整数数组,其中每个像素都根据通过各向异性扩散首先到达像素的标记进行标记。
如果 return_full_prob 为 True,则为形状为 (nlabels, labels.shape) 的浮点数数组。 output[label_nb, i, j] 是标记 label_nb 通过扩散首先到达像素 (i, j) 的概率。
另请参阅
skimage.segmentation.watershed
基于数学形态学和从标记“泛洪”区域的分割算法。
注释
多通道输入使用所有通道数据组合进行缩放。在运行此算法之前,确保所有通道都单独归一化。
spacing 参数专门针对各向异性数据集,其中数据点在某个或多个空间维度上的间距不同。各向异性数据在医学成像中很常见。
该算法最初在 [1] 中提出。
该算法在无限时间内求解扩散方程,以依次在每个阶段的标记上放置源。像素用首先通过各向异性扩散到达该像素的阶段进行标记。
通过最小化 x.T L x 为每个阶段求解扩散方程,其中 L 是图像加权图的拉普拉斯算子,x 是给定阶段的标记首先通过扩散到达像素的概率(x=1 在该阶段的标记上,x=0 在其他标记上,其他系数正在寻找)。每个像素都被赋予其 x 值最大的标签。图像的拉普拉斯算子 L 定义为
L_ii = d_i,像素 i 的邻居数量(i 的度数)
L_ij = -w_ij 如果 i 和 j 是相邻像素
权重 w_ij 是局部梯度范数的递减函数。这确保了在具有相似值的像素之间更容易扩散。
当拉普拉斯算子分解为标记和未标记像素的块时
L = M B.T B A
其中第一个索引对应于标记像素,然后对应于未标记像素,则最小化 x.T L x 为一个阶段量化为求解
A x = - B x_m
其中 x_m 在给定阶段的标记处为 1,而在其他标记处为 0。该线性系统在算法中使用直接方法针对小图像进行求解,而针对大图像则使用迭代方法进行求解。
参考文献
[1]Leo Grady,用于图像分割的随机游走,IEEE 模式分析与机器智能学报。2006 年 11 月;28(11):1768-83。 DOI:10.1109/TPAMI.2006.233.
示例
>>> rng = np.random.default_rng() >>> a = np.zeros((10, 10)) + 0.2 * rng.random((10, 10)) >>> a[5:8, 5:8] += 1 >>> b = np.zeros_like(a, dtype=np.int32) >>> b[3, 3] = 1 # Marker for first phase >>> b[6, 6] = 2 # Marker for second phase >>> random_walker(a, b) array([[1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 2, 2, 2, 1, 1], [1, 1, 1, 1, 1, 2, 2, 2, 1, 1], [1, 1, 1, 1, 1, 2, 2, 2, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]], dtype=int32)
随机游走分割
- skimage.segmentation.relabel_sequential(label_field, offset=1)[source]#
将任意标签重新标记为 {offset, … offset + 标签数量}。
此函数还返回前向映射(将原始标签映射到简化的标签)和反向映射(将简化的标签映射回原始标签)。
- 参数:
- label_fieldint 类型的 numpy 数组,任意形状
标签数组,必须为非负整数。
- offsetint,可选
返回的标签将从 offset 开始,该值应严格为正数。
- 返回值:
- relabeledint 类型的 numpy 数组,与 label_field 形状相同
输入标签字段,其中标签映射到 {offset, …, number_of_labels + offset - 1}。数据类型将与 label_field 相同,除非 offset + number_of_labels 导致当前数据类型溢出。
- forward_mapArrayMap
从原始标签空间到返回的标签空间的映射。可用于重新应用相同的映射。有关用法,请参见示例。输出数据类型将与 relabeled 相同。
- inverse_mapArrayMap
从新标签空间到原始空间的映射。可用于从重新标记的标签字段重建原始标签字段。输出数据类型将与 label_field 相同。
注释
标签 0 假定表示背景,永远不会重新映射。
对于某些输入,前向映射可能非常大,因为它的长度由标签字段的最大值给出。但是,在大多数情况下,
label_field.max()
比label_field.size
小得多,在这种情况下,前向映射保证小于输入或输出图像。示例
>>> from skimage.segmentation import relabel_sequential >>> label_field = np.array([1, 1, 5, 5, 8, 99, 42]) >>> relab, fw, inv = relabel_sequential(label_field) >>> relab array([1, 1, 2, 2, 3, 5, 4]) >>> print(fw) ArrayMap: 1 → 1 5 → 2 8 → 3 42 → 4 99 → 5 >>> np.array(fw) array([0, 1, 0, 0, 0, 2, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5]) >>> np.array(inv) array([ 0, 1, 5, 8, 42, 99]) >>> (fw[label_field] == relab).all() True >>> (inv[relab] == label_field).all() True >>> relab, fw, inv = relabel_sequential(label_field, offset=5) >>> relab array([5, 5, 6, 6, 7, 9, 8])
- skimage.segmentation.slic(image, n_segments=100, compactness=10.0, max_num_iter=10, sigma=0, spacing=None, convert2lab=None, enforce_connectivity=True, min_size_factor=0.5, max_size_factor=3, slic_zero=False, start_label=1, mask=None, *, channel_axis=-1)[source]#
使用颜色-(x,y,z) 空间中的 k 均值聚类分割图像。
- 参数:
- image(M, N[, P][, C]) ndarray
输入图像。可以是 2D 或 3D,以及灰度或多通道(请参见 channel_axis 参数)。输入图像必须是无 NaN 的,或者必须屏蔽 NaN。
- n_segmentsint,可选
分割输出图像中(近似)标签的数量。
- compactnessfloat,可选
平衡颜色接近度和空间接近度。较高的值赋予空间接近度更高的权重,使超像素形状更接近正方形/立方体。在 SLICO 模式下,这是初始紧凑度。此参数在很大程度上取决于图像对比度以及图像中对象的形状。建议在对数刻度上探索可能的值,例如,0.01、0.1、1、10、100,然后再围绕选定的值进行细化。
- max_num_iterint,可选
k 均值的迭代次数上限。
- sigmafloat 或 float 类型的数组,可选
图像每个维度预处理的 Gaussian 平滑核宽度。如果为标量值,则对每个维度应用相同的 sigma。零表示不进行平滑。请注意,如果 sigma 是标量,并且提供了手动体素间距(参见“备注”部分),则会自动缩放 sigma。如果 sigma 是数组,则其大小必须与
image
的空间维度数量匹配。- spacingfloat 类型的数组,可选
沿每个空间维度的体素间距。默认情况下,
slic
假设均匀间距(沿每个空间维度具有相同的体素分辨率)。此参数控制 k 均值聚类期间沿空间维度的距离权重。- convert2labbool, 可选
是否应该在分割之前将输入转换为 Lab 颜色空间。输入图像必须为 RGB。强烈推荐。当
channel_axis` is not None *and* ``image.shape[-1] == 3
时,此选项默认为True
。- enforce_connectivitybool,可选
生成的段是否连接。
- min_size_factorfloat,可选
相对于假定的段大小
`depth*width*height/n_segments`
,要移除的最小段大小的比例。- max_size_factorfloat,可选
最大连接段大小的比例。在大多数情况下,值为 3 可以正常工作。
- slic_zerobool,可选
运行 SLIC-zero,即 SLIC 的零参数模式。 [2]
- start_labelint,可选
标签索引的起点。应为 0 或 1。
在版本 0.17 中添加:
start_label
在 0.17 中引入。- maskndarray,可选
如果提供,则仅在 mask 为 True 的地方计算超像素,并使用 k 均值聚类策略在 mask 上均匀分布种子点。Mask 的维度数量必须等于图像的空间维度数量。
在版本 0.17 中添加:
mask
在 0.17 中引入。- channel_axisint 或 None,可选
如果为 None,则假设图像为灰度(单通道)图像。否则,此参数指示数组的哪个轴对应于通道。
版本 0.19 中添加:
channel_axis
在 0.19 中添加。
- 返回值:
- labels2D 或 3D 数组
表示段标签的整数掩码。
- 引发:
- ValueError
如果
convert2lab
设置为True
,但最后一个数组维度长度不是 3。- ValueError
如果
start_label
不是 0 或 1。- ValueError
如果
image
包含未屏蔽的 NaN 值。- ValueError
如果
image
包含未屏蔽的无限值。- ValueError
如果
image
是 2D 但channel_axis
为 -1(默认值)。
注释
如果 sigma > 0,则在分割之前使用 Gaussian 核对图像进行平滑。
如果 sigma 是标量,并且提供了 spacing,则核宽度沿每个维度除以间距。例如,如果
sigma=1
且spacing=[5, 1, 1]
,则有效 sigma 为[0.2, 1, 1]
。这确保了针对各向异性图像的合理平滑。图像在处理之前重新缩放到 [0, 1](忽略屏蔽的值)。
默认情况下,形状为 (M, N, 3) 的图像被解释为 2D RGB 图像。要将其解释为具有长度为 3 的最后一个维度的 3D 图像,请使用 channel_axis=None。
start_label 被引入来处理问题 [4]。默认情况下,标签索引从 1 开始。
参考文献
[1]Radhakrishna Achanta,Appu Shaji,Kevin Smith,Aurelien Lucchi,Pascal Fua 和 Sabine Süsstrunk,SLIC 超像素与最先进的超像素方法的比较,TPAMI,2012 年 5 月。 DOI:10.1109/TPAMI.2012.120
[3]Irving,Benjamin。“maskSLIC:区域超像素生成及其在医学图像局部病理特征识别中的应用”,2016 年,arXiv:1606.09518
示例
>>> from skimage.segmentation import slic >>> from skimage.data import astronaut >>> img = astronaut() >>> segments = slic(img, n_segments=100, compactness=10)
增加紧凑度参数会产生更接近正方形的区域。
>>> segments = slic(img, n_segments=100, compactness=20)
基于区域边界的区域邻接图 (RAG)区域邻接图 (RAG) 阈值化归一化割绘制区域邻接图 (RAG)应用 maskSLIC 与 SLIC分割和超像素算法的比较查找两个分割的交集区域邻接图 (RAG) 合并区域边界 RAG 的分层合并
- skimage.segmentation.watershed(image, markers=None, connectivity=1, offset=None, mask=None, compactness=0, watershed_line=False)[source]#
找到从给定标记淹没的图像中的分水岭盆地。
- 参数:
- image(M, N[, …]) ndarray
数据数组,其中最低值点标记为第一个。
- markersint,或 (M, N[, …]) ndarray of int,可选
所需的盆地数量,或一个数组,在标签矩阵中标记盆地,并指定要分配的值。零表示不是标记。如果为 None,则(默认)标记被确定为 image 的局部最小值。具体来说,计算等效于将
skimage.morphology.local_minima()
应用于 image,然后将skimage.measure.label()
应用于结果(使用相同的给定 connectivity)。一般来说,鼓励用户显式地传递标记。- connectivityint 或 ndarray,可选
邻域连通性。整数被解释为
scipy.ndimage.generate_binary_structure
中的含义,作为到达邻居的最大正交步数。数组直接被解释为足迹(结构元素)。默认值为 1。在二维中,1 给出 4-邻域,而 2 给出 8-邻域。- offsetarray_like of shape image.ndim,可选
足迹中心的坐标。
- mask(M, N[, …]) ndarray of bools 或 0’s 和 1’s,可选
与 image 形状相同的数组。只有在 mask == True 的点会被标记。
- compactnessfloat,可选
使用给定紧凑参数的紧凑分水岭 [1]。较高的值会导致更规则形状的分水岭盆地。
- watershed_linebool,可选
如果为 True,则一条像素宽的线将分水岭算法获得的区域隔开。这条线的标签为 0。请注意,用于添加此线的方法期望标记区域不邻接;分水岭线可能无法捕获相邻标记区域之间的边界。
- 返回值:
- outndarray
与 markers 类型和形状相同的标记矩阵。
另请参阅
skimage.segmentation.random_walker
一种基于各向异性扩散的分割算法,通常比分水岭算法慢,但在噪声数据和具有孔洞的边界上效果良好。
注释
此函数实现了一个分水岭算法 [2] [3],它将像素分配到标记的盆地。该算法使用优先级队列来保存像素,优先级队列的指标是像素值,然后是进入队列的时间——这有利于离标记最近的像素。
一些想法来自 [4]。论文中最重要的一点是,进入队列的时间解决了两个问题:像素应该分配给具有最大梯度的邻居,或者,如果没有梯度,则高原上的像素应该在两侧的标记之间分割。
此实现将所有参数转换为特定的、最低公分母类型,然后将它们传递给 C 算法。
标记可以手动确定,也可以使用例如图像梯度的局部最小值或距离函数到背景的局部最大值来自动确定,以分离重叠对象(参见示例)。
参考文献
[1]P. Neubert 和 P. Protzel,“紧凑分水岭和抢占式 SLIC:关于改进超像素分割算法权衡的研究”,2014 年第 22 届国际模式识别大会,瑞典斯德哥尔摩,2014 年,第 996-1001 页,DOI:10.1109/ICPR.2014.181 https://www.tu-chemnitz.de/etit/proaut/publications/cws_pSLIC_ICPR.pdf
[4]P. J. Soille 和 M. M. Ansoult,“使用数学形态学从数字高程模型中自动进行盆地划分”,信号处理,20(2):171-182,DOI:10.1016/0165-1684(90)90127-K
示例
分水岭算法对于分离重叠对象很有用。
我们首先生成一个具有两个重叠圆的初始图像。
>>> x, y = np.indices((80, 80)) >>> x1, y1, x2, y2 = 28, 28, 44, 52 >>> r1, r2 = 16, 20 >>> mask_circle1 = (x - x1)**2 + (y - y1)**2 < r1**2 >>> mask_circle2 = (x - x2)**2 + (y - y2)**2 < r2**2 >>> image = np.logical_or(mask_circle1, mask_circle2)
接下来,我们想分离这两个圆。我们在距离背景的最大值处生成标记。
>>> from scipy import ndimage as ndi >>> distance = ndi.distance_transform_edt(image) >>> from skimage.feature import peak_local_max >>> max_coords = peak_local_max(distance, labels=image, ... footprint=np.ones((3, 3))) >>> local_maxima = np.zeros_like(image, dtype=bool) >>> local_maxima[tuple(max_coords.T)] = True >>> markers = ndi.label(local_maxima)[0]
最后,我们在图像和标记上运行分水岭。
>>> labels = watershed(-distance, markers, mask=image)
该算法也适用于 3D 图像,并且可以用于例如分离重叠球体。
使用紧凑分水岭查找规则段扩展分割标签,不重叠分水岭分割分水岭变换的标记分割和超像素算法的比较查找两个分割的交集评估分割指标比较基于边缘和基于区域的分割分割人类细胞(处于有丝分裂状态)