图像分割是图像处理,计算机视觉领域里非常基础,非常重要的一个应用。今天介绍一种高效的分割算法,即 simple linear iterative clustering (SLIC) 算法,顾名思义,这是一种简单的迭代聚类算法,这个算法发表于 2012 年的 PAMI 上。

SLIC 算法有几个关键点,
1: 图像分割块的初始化,每一个图像块都是一个聚类,聚类的中心称为 superpixel,聚类的个数 k 是人为设定的,SLIC 算法先将图像分成大小大小一致的图像 patch,假设图像的像素个数为 N, 需要分割的图像 patch 个数为 k, 那么每个 patch 的大小为 S×S,S=N/k

2:聚类中心的初始化,在划分好的图像块里,随机采样一个点作为聚类的中心,为了避免采样的初始点是噪声或者是在边缘部分,算法做了一点变化,在采样点附近 3×3 的区域计算临近像素点的梯度,选择临近点中梯度最小的点为聚类中心。

3: 计算像素点到聚类中心的距离,图像分好块,选择好了每一个图像块的聚类中心,接下来就是计算图像中每一个像素点离聚类中心的距离了,这里与通常的聚类算法不一样,一般的聚类算法会计算像素点离每一个聚类中心的距离,换句话说,每一个聚类中心都要和所有的像素点计算距离,这个明显是费时,而且也是没有必要的,SLIC 算法简化了这一步,只计算每个聚类中心周围 2S×2S 范围类的像素点与该聚类中心的距离,这样可以节省很多的运算时间。

为了可以衡量距离,这个算法考虑了 空间距离 和 颜色距离 两种:

dc=(ljli)2+(ajai)2+(bjbi)2
ds=(xjxi)2+(yjyi)2
D=(dcm)2+(dsS)2

算法最后衡量距离的形式如下所示:

D=(dc)2+(dsS)2m2

在 CIELAB 颜色空间中,论文中提到 m 的取值范围大概是 [1, 40]

4:重新聚类,计算完距离之后,每一个像素点都会更新自己所属的图像块,将同一个图像块的像素点取平均,得到新的聚类中心,然后再重复前面的步骤,直到两次聚类中心的距离小于某个阈值。算法的流程图如下所示:

这里写图片描述

给出一段Python 的代码:

# import the necessary packages
from skimage.segmentation import slic
from skimage.segmentation import mark_boundaries
from skimage.util import img_as_float
from skimage import io
import matplotlib.pyplot as plt


# load the image and convert it to a floating point data type
image = img_as_float(io.imread("image.jpg"))

# loop over the number of segments
for numSegments in (100, 200, 300):
    # apply SLIC and extract (approximately) the supplied number
    # of segments
    segments = slic(image, n_segments = numSegments, sigma = 5)

    # show the output of SLIC
    fig = plt.figure("Superpixels -- %d segments" % (numSegments))
    ax = fig.add_subplot(1, 1, 1)
    ax.imshow(mark_boundaries(image, segments))
    plt.axis("off")

# show the plots
plt.show()

这里写图片描述

这里写图片描述

posted on 2017-12-04 20:43  未雨愁眸  阅读(912)  评论(0编辑  收藏  举报