非常教程

Scikit image参考手册

分割 | segmentation

segmentation

skimage.segmentation.active_contour(图片,蛇)

主动轮廓模型。

skimage.segmentation.clear_border(标签,...)

清除连接到标签图像边界的对象。

skimage.segmentation.felzenszwalb(image,...)

计算Felsenszwalb的基于有效图的图像分割。

skimage.segmentation.find_boundaries(label_img)

返回标签区域之间的边界为True的布尔数组。

skimage.segmentation.join_segmentations(s1,s2)

返回两个输入分段的连接。

skimage.segmentation.mark_boundaries(image,...)

返回带有标记区域之间边界的图像。

skimage.segmentation.quickshift(image,...)

在Color-(x,y)空间中使用快速转换聚类来分段图像。

skimage.segmentation.random_walker(数据,标签)

用于从标记分割的随机游走算法。

skimage.segmentation.relabel_from_one(...)

弃用功能。改为使用relabel_sequential。

skimage.segmentation.relabel_sequential(...)

将任意标签重新标记为{offset,...

skimage.segmentation.slic(image,...)

在Color-(x,y,z)空间中使用k-means聚类来分割图像。

skimage.segmentation.watershed(图像,标记)

从给定的标记中发现图像中的流域盆地。

skimage.segmentation.active_contour_model

skimage.segmentation.boundaries

skimage.segmentation.random_walker_segmentation

随机游走分割算法

skimage.segmentation.slic_superpixels

active_contour

skimage.segmentation.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)[source]

主动轮廓模型。

通过将snake适配到图像的特征来实现主动轮廓。支持单通道和多通道2D图像。snake可以是周期性的(用于分割)或具有固定和/或自由端。输出snake具有与输入边界相同的长度。由于点数不变,请确保最初的snake有足够的点来捕获最终轮廓的细节。

参数:

图像:(N,M)或(N,M,3)ndarray输入图像。蛇:(N,2)ndarray snake 的初始化坐标。对于周期性的 snake ,它不应该包含重复的端点。alpha:float,可选的Snake长度形状参数。较高的值使蛇合约更快。beta:浮动,可选的Snake平滑度形状参数。更高的值使蛇更平滑。w_line:float,可选控制对亮度的吸引力。使用负值吸引黑暗地区。w_edge:float,可选控制对边缘的吸引力。使用负值从边缘排斥蛇。gamma:float,可选显式时间步进参数。bc:{'periodic','free','fixed'},可选的蠕虫边界条件。“周期性”连接 snake 的两端,“固定”将端点固定到位,“自由”允许端部自由移动。'fixed'和'free'可以通过解析'fixed-free','free-fixed'来结合。解析'fixed-fixed'或'free-free'分别产生与'fixed'和'free'相同的行为。max_px_move:float,可选每次迭代移动的最大像素距离。max_iterations:int,可选最大迭代来优化 snake 形状。收敛:浮动,可选收敛标准。

返回:

snake :(N,2)ndarray优化蛇,与输入参数形状相同。

参考

R449

Kass, M.; Witkin, A.; Terzopoulos, D. “Snakes: Active contour models”. International Journal of Computer Vision 1 (4): 321 (1988).

例子

>>> 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, 2)

初始样条:

>>> s = np.linspace(0, 2*np.pi,100)
>>> init = 50*np.array([np.cos(s), np.sin(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

clear_border

skimage.segmentation.clear_border(labels, buffer_size=0, bgval=0, in_place=False)[source]

清除连接到标签图像边界的对象。

Parameters:

labels : (M[, N, …, P]) array of int or bool Imaging data labels. buffer_size : int, optional The width of the border examined. By default, only objects that touch the outside of the image are removed. bgval : float or int, optional Cleared objects are set to this value. in_place : bool, optional Whether or not to manipulate the labels array in-place.

Returns:

out : (M[, N, …, P]) array Imaging data labels with cleared borders

例子

>>> import numpy as np
>>> from skimage.segmentation import clear_border
>>> labels = np.array([[0, 0, 0, 0, 0, 0, 0, 1, 0],
...                    [0, 0, 0, 0, 1, 0, 0, 0, 0],
...                    [1, 0, 0, 1, 0, 1, 0, 0, 0],
...                    [0, 0, 1, 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, 1, 1, 1, 1, 1, 0, 0],
       [0, 1, 1, 1, 1, 1, 1, 1, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0]])

felzenszwalb

skimage.segmentation.felzenszwalb(image, scale=1, sigma=0.8, min_size=20, multichannel=True)[source]

计算Felsenszwalb的基于有效图的图像分割。

使用基于图像网格的快速,最小生成树聚类生成多通道(即RGB)图像的过度分割。该参数scale设置观察级别。规模越大意味着越来越小的部分。sigma是高斯核的直径,用于在分割之前平滑图像。

生产环节的数量及其规模只能通过scale间接控制。根据局部对比度不同,图像中的分段大小可能会有很大差异。

对于RGB图像,该算法使用颜色空间中像素之间的欧式距离。

参数:

图像:(宽度,高度,3)或(宽度,高度)ndarray输入图像。scale:float可用参数。较高意味着较大的群集 sigma:float预处理中使用的高斯内核的宽度。min_size:int最小组件大小。使用后处理强制执行。多通道:bool,可选(默认值:True)图像的最后一个轴是否被解释为多个通道。对于3D图像,False的值目前不受支持。

返回:

segment_mask :(宽度,高度)ndarray整数掩码,指示段标签。

参考

R450

Efficient graph-based image segmentation, Felzenszwalb, P.F. and Huttenlocher, D.P. International Journal of Computer Vision, 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)

find_boundaries

skimage.segmentation.find_boundaries(label_img, connectivity=1, mode='thick', background=0)[source]

返回标签区域之间的边界为True的布尔数组。

参数:

label_img:int或bool的数组不同区域使用不同整数或布尔值标记的数组。连通性:int在{1,...,label\_img.ndim},可选如果某个像素中的任何邻居具有不同的标签,则该像素将被视为边界像素。连接控制哪些像素被认为是邻居。1(默认)的连接意味着共享边缘(2D)或面部(3D)的像素将被视为邻居。label_img.ndim的连通性意味着共享角落的像素将被视为邻居。模式:{'thick','inner','outer','subpixel'}中的字符串}如何标记边界:thick:任何没有被同一标签(由连通性定义)的像素完全包围的像素被标记为边界。这导致2像素厚的边界。内部:勾勒对象内部的像素,保持背景像素不变。外部:围绕对象边界的背景中的轮廓像素。当两个物体接触时,它们的边界也被标记。像素:返回一个加倍的图像,原始像素之间的像素标记为边界。背景:int,可选对于“内部”和“外部”模式,需要定义背景标签。有关这两者的描述,请参阅模式。

返回:

边界:布尔数组,与label_img形状相同其中True代表边界像素的布尔图像。对于等于'subpixel'的模式,对于所有i,边界.shapei等于2 * label_img.shapei - 1(像素插入所有其他像素对之间)。

  • thick:任何不完全被相同标签(由其定义connectivity)的像素所包围的像素被标记为边界。这导致2像素厚的边界。
  • inner:勾勒对象内部的像素,保持背景像素不变。
  • outer:围绕对象边界的背景中的轮廓像素。当两个物体接触时,它们的边界也被标记。
  • 子像素:返回一个加倍的图像,原始像素之间的像素在适当的位置标记为边界。

background: int, optional

对于模式“内部”和“外部”,需要定义背景标签。请参阅mode这两个的描述。

Returns:  **boundaries** : array of bool, same shape as `label_img`

True代表边界像素的布尔图像。 对于等于'subpixel'的模式,对于所有i(像素插入在所有其他像素对之间),boundary.shape [i]等于2 * label_img.shape [i] - 1。

例子

>>> 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=np.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]], dtype=bool)

join_segmentations

skimage.segmentation.join_segmentations(s1, s2)[source]

返回两个输入分段的连接。

S1和S2的连接J的定义为,其中两个体素在相同的段分割当且仅当它们在相同的段 S1和S2。

参数:

s1,s2:numpy数组s1和s2是相同形状的标签字段。

返回:

j:numpy数组s1和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]])

mark_boundaries

skimage.segmentation.mark_boundaries(image, label_img, color=(1, 1, 0), outline_color=None, mode='outer', background_label=0)[source]

返回带有标记区域之间边界的图像。

参数:

图像:(M,N,3)数组灰度或RGB图像。label_img:int标签数组中的(M,N)数组,其中区域由不同的整数值标记。颜色:长度为3的序列,输出图像中边界的可选RGB颜色。outline_color:长度为3的序列,输出图像中围绕边界的可选RGB颜色。如果没有,则不绘制轮廓。模式:{'thick','inner','outer','subpixel'}中的字符串,可选用于查找边界的模式。background_label:int,可选哪个标签要考虑背景(这只对模式内部和外部有用)。

返回:

标记:(M,N,3)浮点阵列图像中标签之间的边界叠加在原始图像上。

扩展内容

find_boundaries

quickshift

skimage.segmentation.quickshift(image, ratio=1.0, kernel_size=5, max_dist=10, return_tree=False, sigma=0, convert2lab=True, random_seed=42)[source]

在Color-(x,y)空间中使用快速转换聚类来分段图像。

使用快速转换模式搜索算法生成图像的超分块。

参数:

图像:(宽度,高度,通道)ndarray输入图像。ratio:float,可选,介于0和1之间平衡色彩空间接近度和图像空间接近度。较高的值会增加色彩空间的重量。kernel_size:float,可选用于平滑样本密度的高斯内核宽度。越高意味着越少的群集 max_dist:float,可选数据距离的切点。越高意味着越少的群集 return_tree:bool,可选是否返回完整的分割层次树和距离。sigma:float,高斯平滑作为预处理的可选宽度。零意味着不平滑。convert2lab:bool,可选是否在分割之前将输入转换为实验室颜色空间。为此,输入假定为RGB。random_seed:int,可选用于打破关系的随机种子。

返回:

segment_mask :(宽度,高度)ndarray整数掩码,指示段标签。

笔记

作者主张在分割之前将图像转换为Lab色彩空间,尽管这不是必须的。为此,图像必须以RGB格式提供。

参考

R451

Vedaldi,A。和Soatto,S.欧洲计算机视觉会议,2008年的模式寻求的快速转变和核心方法

random_walker

skimage.segmentation.random_walker(data, labels, beta=130, mode='bf', tol=0.001, copy=True, multichannel=False, return_full_prob=False, spacing=None)[source]

用于从标记分割的随机游走算法。

随机游走算法用于灰度或多通道图像。

参数:

数据:array_like图像被分段分段。灰度级数据可以是二维或三维的; 多通道数据可以是三维或四维(多通道=真),最高维度表示通道。除非使用了间距关键字参数,否则假定数据间距是各向同性的。标签:整数的数组,与无通道的数据具有相同的形状维数种子标记数组,标记了不同阶段的不同正整数。零标记像素是未标记像素。负标签对应于未考虑的非活动像素(将它们从图中移除)。如果标签不是连续的整数,标签数组将被转换,因此标签是连续的。在多通道的情况下,标签应该具有与单个数据通道相同的形状,即 没有表示渠道的最终维度。beta:float随机游走运动的惩罚系数(β越大,扩散越困难)。mode:string,available options {'cg_mg','cg','bf'}用于求解随机游走算法中线性系统的模式。如果没有给出偏好,自动尝试使用可用的最快选项(来自pyamg >>'cg'的'cg_mg'与UMFPACK>'bf')。'bf'(蛮力):计算拉普拉斯算子的LU分解。这对于小图像(<1024x1024)很快,但对于大图像(例如三维体)非常缓慢且需要大量内存。'cg'(共轭梯度):使用来自scipy.sparse.linalg的共轭梯度方法迭代地求解线性系统。这比大型图像的强力方法更节省内存,但速度很慢。'cg_mg'(带多重网格预处理器的共轭梯度):使用多重网格求解器计算预处理器,然后使用共轭梯度法计算解。该模式要求pyamg模块(http://pyamg.org/)已安装。对于尺寸> 512x512的图像,这是推荐的(最快)模式。tol:在cg'和'cg_mg'模式下求解线性系统时的浮点容差。copy:bool如果copy为False,则标签数组将被分割的结果覆盖。如果要保存在内存上,请使用copy = False。多通道:布尔型,默认为False如果为True,输入数据将被解析为多通道数据(在这种情况下,请参阅上面的“数据”以了解正确的输入格式)return_full_prob:bool,默认值False如果为True,则像素属于每个标签的概率将被退回,而不是只有最可能的标签。间距:浮点数可迭代每个空间维度中体素之间的间距。如果无,则假设每个维度中的像素/体素之间的间隔为1。

返回:

output:ndarray如果return_full_prob为False,则表示与数据形状相同的ints数组,其中每个像素已根据通过各向异性扩散首先到达像素的标记进行标记。如果return_full_prob为True,则形状浮点数组(nlabels,data.shape)。outputlabel_nb,i,j是标签label_nb首先到达像素(i,j)的概率。

  • 'bf'(蛮力):计算拉普拉斯算子的LU分解。这对于小图像(<1024x1024)很快,但对于大图像(例如三维体)非常缓慢且需要大量内存。
  • 'cg'(共轭梯度):使用来自scipy.sparse.linalg的共轭梯度方法迭代地求解线性系统。这比大型图像的强力方法更节省内存,但速度很慢。
  • 'cg_mg'(带多重网格预处理器的共轭梯度):使用多重网格求解器计算预处理器,然后使用共轭梯度法计算解。该模式要求安装pyamg模块(http://pyamg.org/)。对于尺寸> 512x512的图像,这是推荐的(最快)模式。

tol : float

在cg'和'cg_mg'模式下求解线性系统时的容差。

copy : bool

如果copy为False,则labels数组将被分段结果覆盖。如果要保存在内存上,请使用copy = False。

multichannel : bool, default False

如果为True,则将输入数据解析为多通道数据(请参阅上面的'数据'以获取正确的输入格式)

return_full_prob : bool, default False

如果为True,则返回一个像素属于每个标签的概率,而不仅仅是最可能的标签。

spacing : iterable of floats

每个空间维度中体素之间的间距。如果None,则假设每个维度中的像素/体素之间的间隔为1。

Returns:  **output** : ndarray
  • 如果return_full_prob是False,则表示形状相同的整数数组data,其中每个像素已根据通过各向异性扩散首先到达像素的标记进行标记。
  • 如果return_full_prob是True,则形状花车阵列(nlabels, data.shape)output[label_nb, i, j]是标签首先到达像素的概率(i, j)

扩展内容

skimage.morphology.watershed 分水岭分割基于数学形态学和来自标记的区域的“泛滥”的分割算法。

笔记

多通道输入与所有通道数据合并。在运行此算法之前,确保所有通道都分别归一化。

spacing论点特别针对各向异性数据集,其中数据点在一个或多个空间维度中间隔不同。各向异性数据通常在医学成像中遇到。

该算法最早是在随机游走图像分割,Leo Grady,IEEE Trans Pattern Anal Mach Intell中提出的。2006年11月; 28(11):1768-83。

该算法依次解决了放在每个相位标记上的源在无限时间的扩散方程。像素被标记为具有最大扩散到像素的最大可能性的相位。

通过最小化每个相位的xT L x来解决扩散方程,其中L是图像的加权图的拉普拉斯算子,并且x是给定相位的标记首先在像素处通过扩散到达的概率(x = 1在相位的标记上,其他标记上的x = 0,并且查找其他系数)。每个像素都归属于其最大值为x的标签。图像的拉普拉斯L定义为:

  • L_ii = d_i,像素i的邻居数(i的度数)
  • 如果i和j是相邻像素,则L_ij = -w_ij

权重w_ij是局部梯度范数的递减函数。这确保了类似值的像素之间的漫射更容易。

当拉普拉斯算子分解成标记和未标记像素块时:

L = M B.T
    B A

其中第一个索引对应于标记的像素,然后是未标记的像素,最小化一个相位量的xT L x来解决:

A x = - B x_m

其中在给定相的标记上x_m = 1,而在其他标记上为0。该线性系统在使用小图像的直接方法的算法中以及用于较大图像的迭代方法中解决。

例子

>>> np.random.seed(0)
>>> a = np.zeros((10, 10)) + 0.2 * np.random.rand(10, 10)
>>> a[5:8, 5:8] += 1
>>> b = np.zeros_like(a)
>>> 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)

relabel_from_one

skimage.segmentation.relabel_from_one(label_field)[source]

弃用功能relabel_sequential改为使用。

将任意标签字段中的标签转换为{1,... number_of_labels}。

此功能已弃用,请参阅relabel_sequential以获取更多信息。

relabel_sequential

skimage.segmentation.relabel_sequential(label_field, offset=1)[source]

将任意标签重新标签为{ offset,... offset+ number_of_labels}。

此函数还返回前向贴图(将原始标签映射到缩小的标签)和逆向贴图(将缩小后的标签映射回原始贴图)。

参数:

label_field:int的numpy数组,任意形状标签数组。偏移量:int,可选返回标签将从偏移量开始,这应该严格为正值。

返回:

重新标记:int的numpy数组,与label_field的形状相同标签映射到{offset,...,number_of_labels + offset - 1}的输入标签字段。forward_map:int的numpy数组,shape(label_field.max()+ 1,)从原始标签空间到返回标签空间的映射。可以用来重新应用相同的映射。查看使用示例。inverse_map:1D int的numpy数组,长度偏移量+标签数量从新标签空间到原始空间的映射。这可以用来从重新标记的字段重建原始标签字段。

笔记

标签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])
>>> 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])
>>> 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])

slic

skimage.segmentation.slic(image, n_segments=100, compactness=10.0, max_iter=10, sigma=0, spacing=None, multichannel=True, convert2lab=None, enforce_connectivity=True, min_size_factor=0.5, max_size_factor=3, slic_zero=False)[source]

在Color-(x,y,z)空间中使用k-means聚类来分割图像。

参数:

图像:2D,3D或4D ndarray输入图像,可以是2D或3D,也可以是灰度或多通道(请参阅多通道参数)。n_segments:int,可选分段输出图像中标签的(近似)数量。紧凑性:浮动,可选平衡色彩接近度和空间接近度。数值越高,空间接近度越重,使得超像素形状更加平方/立方。在SLICO模式下,这是最初的紧凑性。该参数强烈依赖于图像对比度和图像中物体的形状。我们建议您在对所选值进行精炼之前,先在对数标度上探索可能的值,例如0.01,0.1,1,10,100。max_iter:int,可选k-means的最大迭代次数。sigma:float或(3,)数组 - 像浮点数,可选高斯平滑内核的宽度,用于对图像的每个维度进行预处理。在标量值的情况下,相同的西格马适用于每个维度。零意味着不平滑。请注意,如果sigma是标量并提供了手动体素间距,则会自动缩放(请参阅注释部分)。间距:(3,)数组 - 类似于浮点数,可选沿每个图像维度的体素间距。默认情况下,切片假定均匀间距(沿z,y和x的体素分辨率相同)。此参数控制k均值聚类期间沿z,y和x的距离的权重。多通道:bool,可选是否将图像的最后一个轴解释为多个通道或另一个空间维度。convert2lab:bool,可选是否在分割之前将输入转换为实验室颜色空间。输入图像必须是RGB。强烈推荐。当multichannel = True和image.shape-1 == 3时,此选项默认为True。enforce_connectivity:bool,可选是否连接生成的段min_size_factor:float,可选要删除的最小段大小的比例假定的段大小depth\*width\*height/n\_segments max_size_factor:float,可选最大连接段大小的比例。在大多数情况下,值为3。slic_zero:bool,可选运行SLIC-zero,即SLIC的零参数模式。R453

返回:

标签:2D或3D数组整数掩码指示段标签。

举:

ValueError如果convert2lab设置为True,但最后一个数组维度长度不是3。

笔记

  • 如果sigma > 0在分割之前使用高斯内核对图像进行平滑处理。
  • 如果sigma是标量并且spacing被提供,则内核宽度沿着每个维度被间隔分开。例如,如果sigma=1spacing=[5, 1, 1],有效的sigma[0.2, 1, 1]。这确保了各向异性图像的合理平滑。
  • 在处理之前,图像被重新缩放到0,1。
  • 形状(M,N,3)的图像默认被解释为2D RGB图像。要将它们解释为3D,最后一个维度长度为3,请使用multichannel=False

参考

R452

TPAMI,2012年5月,Radhakrishna Achanta,Appu Shaji,Kevin Smith,Aurelien Lucchi,Pascal Fua和SabineSüsstrunk,SLIC Superpixels与最先进的超像素方法相比。

R453

(1, 2) http://ivrg.epfl.ch/research/superpixels#SLICO

例子

>>> 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)

watershed

skimage.segmentation.watershed(image, markers, connectivity=1, offset=None, mask=None, compactness=0, watershed_line=False)[source]

发现image从给定的淹没流域盆地markers

参数:

图像:整数的ndarray(2-D,3-D,...)数据数组,其中最低值的点首先标记。标记:int或int的ndarray,形状与image 所需数量的标记或标记盆地的数组,其中标记矩阵中要分配的值。零意味着不是一个标记。connectivity:ndarray,optional一个数组,其维数与图像的维数相同,其非零元素表示用于连接的邻居。遵循scipy惯例,默认值是图像维度的单连接数组。偏移量:形状image.ndim的array_like,连通性的可选偏移量(每个维度一个偏移量)mask:bools或0s和1s的ndarray,与图像形状相同的可选Array。只有在mask == True的地方才会被标记。紧凑性:浮动,可选使用紧凑分水岭R456与给定的紧凑性参数。较高的值会导致更加规则的流域盆地。watershed_line:bool,可选如果watershed_line为True,一个像素宽的线将分水岭算法获得的区域分开。该行的标签为0。

返回:

out:ndarray与标记相同类型和形状的标记矩阵

扩展内容

skimage.segmentation.random_walker 随机Walker分割基于各向异性扩散的分割算法,通常比分水岭慢,但对噪声数据和孔洞边界具有良好结果。

笔记

此功能实现了将像素分配到标记的盆地中的分水岭算法[R454] [R455]。该算法使用优先级队列来保存像素,其中优先级队列的度量是像素值,然后是进入队列的时间 - 这决定了最接近的标记。

Soille的一些想法,“使用数学形态学的数字高程模型的自动化盆地描述”,Signal Processing 20(1990)171-182

本文最重要的见解是入队时间到队列解决了两个问题:一个像素应该分配给最大梯度的邻居,或者如果没有梯度,平台上的像素应该在相反两侧的标记之间分开。

该实现将所有参数转换为特定的最低公分母类型,然后将这些参数传递给C算法。

可以手动确定标记,或者自动使用例如图像梯度的局部最小值或距离函数的局部最大值来分离重叠对象(参见示例)。

参考

R454

(1, 2) http://en.wikipedia.org/wiki/Watershed_%28image_processing%29

R455

(1, 2) http://cmm.ensmp.fr/~beucher/wtshed.html

R456

(1,2)Peer Neubert&Peter Protzel(2014)。紧凑流域和抢占式SLIC:提高超像素分割算法的权衡。ICPR 2014,pp 996-1001。DOI:10.1109 / ICPR.2014.181 https://www.tu-chemnitz.de/etit/proaut/forschung/rsrc/cws_pSLIC_ICPR.pdf

例子

分水岭算法对分离重叠对象很有用。

我们首先用两个重叠的圆圈生成一个初始图像:

>>> 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
>>> local_maxi = peak_local_max(distance, labels=image,
...                             footprint=np.ones((3, 3)),
...                             indices=False)
>>> markers = ndi.label(local_maxi)[0]

最后,我们在图像和标记上运行分水岭:

>>> labels = watershed(-distance, markers, mask=image)

该算法也适用于三维图像,可用于分离重叠球体。

分割 | segmentation相关

Scikit image

Scikit-image 是用于图像处理的 Python 包,使用原生的 NumPy 数组作为图像对象。

主页 http://scikit-image.org/
源码 https://github.com/scikit-image/scikit-image
发布版本 0.13.1