您的位置:首页 > 编程语言 > Python开发

Opencv Python版学习笔记(七)k均值-k-means

2013-07-04 13:08 585 查看
k-均值是一种基于形心得技术,首先从对象中随机选择k个对象,每个对象代表簇的初始均值或中心。对剩下的每个对象,根据其与各个簇中心的欧式距离,将它分配到最相似的簇。然后,k-均值算法迭代地盖伞簇内变差。对于每个簇,它使用上次迭代分配到的该簇对象,计算新的均值。然后,使用更新的均值最为新的簇的中心,重新分配所有对象。迭代继续,知道分配稳定,即本轮形成的簇与前一轮形成的簇相同。

k-均值通常对离群点比较敏感,被分配到任何一个簇都会对这个簇的均值产生扭曲。k-中心点比较适合存在噪声和离群点的情况,但是其计算复杂度高于k-均值

函数原型:cv.KMeans2(samples, nclusters, labels, termcrit, attempts=1, flags=0, centers=None)

参数说明:samples 输入的浮点矩阵,每一行为一个样例

nclusters 选定初始分类的数目

labels 输出的样例分类标记

termcrit 迭代终止条件,最大迭代次数或者精度

attempts 算法执行次数,也就是选择不同的初始中心的次数

flags KMEANS_RANDOM_CENTERS 随机选择初始中心
KMEANS_PP_CENTERS
使用kmeans++初始化中心 KMEANS_USE_INITIAL_LABELS第一次使用标记的中心,之后采用随机中心

centers 输出的聚类中心

代码及注释说明:

#decoding:utf-8
#!/usr/bin/python
import urllib2
import cv2.cv as cv
from random import randint
MAX_CLUSTERS = 5

if __name__ == "__main__":

color_tab = [
cv.CV_RGB(255, 0,0),
cv.CV_RGB(0, 255, 0),
cv.CV_RGB(100, 100, 255),
cv.CV_RGB(255, 0,255),
cv.CV_RGB(255, 255, 0)]
img = cv.CreateImage((500, 500), 8, 3)
rng = cv.RNG(-1)#随机种子

cv.NamedWindow("clusters", 1)

while True:
cluster_count = randint(2, MAX_CLUSTERS)#随机数(2-5)--簇的个数
sample_count = randint(1, 1000)#随机数1-1000--随机点的个数
points = cv.CreateMat(sample_count, 1, cv.CV_32FC2)
clusters = cv.CreateMat(sample_count, 1, cv.CV_32SC1)

# generate random sample from multigaussian distribution
for k in range(cluster_count):
center = (cv.RandInt(rng)%img.width, cv.RandInt(rng)%img.height)#随机产生聚类中心
first = k*sample_count/cluster_count#找到每个簇的第一个点
last = sample_count
if k != cluster_count:
last = (k+1)*sample_count/cluster_count#每个簇的最后一个点

point_chunk = cv.GetRows(points, first, last)
#以标准高斯分布的形式产生点序列,均值为center,存储在point_chunk里
cv.RandArr(rng, point_chunk, cv.CV_RAND_NORMAL,
cv.Scalar(center[0], center[1], 0, 0),
cv.Scalar(img.width*0.1, img.height*0.1, 0, 0))

# shuffle samples
cv.RandShuffle(points, rng)#打乱数组内的元素

cv.KMeans2(points, cluster_count, clusters,
(cv.CV_TERMCRIT_EPS + cv.CV_TERMCRIT_ITER, 10, 1.0))

cv.Zero(img)#生成一个全黑图像

for i in range(sample_count):
cluster_idx = int(clusters[i, 0])#获取点的类标识
pt = (cv.Round(points[i, 0][0]), cv.Round(points[i, 0][1]))
cv.Circle(img, pt, 2, color_tab[cluster_idx], cv.CV_FILLED, cv.CV_AA, 0)#根据类别选择颜色画点

cv.ShowImage("clusters", img)

key = cv.WaitKey(0) % 0x100
if key in [27, ord('q'), ord('Q')]:
break

cv.DestroyWindow("clusters")
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: