原文来自我的个人博客:http://www.yuanyong.org/blog/python/clustering-pixels-using-k-means
在前一篇文章K-Means Using Python 中,给出了一个用K-Means聚类的Tutorial,这个将K-Means用在具体图像像素聚类中,需要说明的是除了在很简单的图像上,单纯在像素值上应用K-Means给出的结果是毫无意义的。要产生有意义的结果,需要更多复杂的类模型或空间一致性而不是平均像素色彩。这里,我们仅仅在RGB三通道像素值上运用K-Means,关于图像分割问题会在后面的学习过程中给出一些笔记与示例。
这里,我们对两幅简单的图像利用K-Means进行像素聚类。下面代码先载入图像,然后用一个
100 × 100
的窗口在图像中滑动,在RGB三通道上,分别求窗口所在位置中窗口包含像素值的平均值作为特征,对这些特征利用K-Means进行聚类,然后进行向量量化,关于向量量化的解释及理解,可以参与[1,2],下面是完整的对一幅简单的图像利用K-Means进行像素聚类的完整code:
5 from scipy.cluster.vq import *
6 from scipy.misc import imresize
10 infile = 'D:\NutStore\Project\Translation\PCV\pcv_data\data\empire.jpg'
11 im = array(Image.open(infile))
12 dx = im.shape[0] / steps
13 dy = im.shape[1] / steps
16 for x in range(steps):
17 for y in range(steps):
18 R = mean(im[x * dx:(x + 1) * dx, y * dy:(y + 1) * dy, 0])
19 G = mean(im[x * dx:(x + 1) * dx, y * dy:(y + 1) * dy, 1])
20 B = mean(im[x * dx:(x + 1) * dx, y * dy:(y + 1) * dy, 2])
21 features.append([R, G, B])
22 features = array(features, 'f')
24 centroids, variance = kmeans(features, 3)
25 code, distance = vq(features, centroids)
27 codeim = code.reshape(steps, steps)
28 codeim = imresize(codeim, im.shape[:2], 'nearest')
31 ax1.set_title('Image')
35 ax2.set_title('Image after clustering')
上面两层for循环实现的就是窗口滑动时,窗口中三通道像素的平均值,并将求得的三通道上的平均值作为feature,后面的过程就是K-Means Using Python 中详解的内容,这里不再赘述。下面是像素聚类结果:
再次需要强调的是利用像素聚类的方法只能对一些简单的图像进行分割,对于复杂点的图像,我们可以采用图割的方法,后面会对这方面进行一些分析。
[1] http://www.data-compression.com/vq.shtml
[2] http://blog.youkuaiyun.com/zouxy09/article/details/9153255