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

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


 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值