kmeans算法的原理参考:http://www.cnblogs.com/mikewolf2002/p/3368118.html

下面学习一下opencv中kmeans函数的使用。

     首先我们通过OpenCV中的随机数产生器RNG,生成一些均匀分布的随机点,这些点的位置对应一副图像中的像素位置,然后使用kmeans算法对这些随机点进行分类,并计算出分类簇的中心点。

     随机产生的簇的数量是2到5之间的值,采样点的数量范围是1-1000,一维矩阵centers存放kmeans算法结束后,各个簇的中心位置。

     

//簇的数量
int k, clusterCount = rng.uniform(2, MAX_CLUSTERS+1);
//采样点的数量
int i, sampleCount = rng.uniform(1, 1001);
Mat points(sampleCount, 1, CV_32FC2), labels;

clusterCount = MIN(clusterCount, sampleCount);
//中心点矩阵
Mat centers(clusterCount, 1, points.type());

printf("clusterCount=%d, sampleCount=%d\n", clusterCount, sampleCount);
//产生多高斯部分的随机采样点
for( k = 0; k < clusterCount; k++ )
    {
    Point center;
    center.x = rng.uniform(0, img.cols);
    center.y = rng.uniform(0, img.rows);
    Mat pointChunk = points.rowRange(k*sampleCount/clusterCount,
        k == clusterCount - 1 ? sampleCount :
        (k+1)*sampleCount/clusterCount);
    printf("rows start=%d rows end=%d\n", k*sampleCount/clusterCount, k == clusterCount - 1 ? sampleCount :
        (k+1)*sampleCount/clusterCount);

注意rng.fill函数,会以center点为中心,产生高斯分布的随机点(位置点),并把位置点保存在矩阵pointChunk中。
    //第三个参数中心,第四个参数偏移
    rng.fill(pointChunk, CV_RAND_NORMAL, Scalar(center.x, center.y), Scalar(img.cols*0.05, img.rows*0.05));
    }

//打乱points中值,第二个参数表示随机交换元素的数量的缩放因子,总的交换次数dst.rows*dst.cols*iterFactor,第三个参数是个随机发生器,决定选那两个元素交换。

randShuffle(points, 1, &rng);

      kmeans函数中points为输入矩阵,其中存储的是采样点,labels也是一个一维矩阵,它的size和points一样,里面存储的是每个采样点执行kmeans算法后属于属于那一个簇,值为0到clusterCount-1,centers中存放的是kmeans算法结束后每个簇的中心位置。

      flags(第7个参数)为KMEANS_PP_CENTERS 表示使用 kmeans++ center initialization by Arthur and Vassilvitskii [Arthur2007]算法决定簇的初始中心,否则就是采用随机值的方法决定初始中心。

     如果flags是CV_KMEANS_USE_INITIAL_LABELS,则需要初始化labels,就是初始指定点的分类。

     最后我们在图像中画出每个位置点对应的像素,中心位置用蓝色的圆圈表示。

//labels中放的是执行kmeans算法后sample中簇的索引
kmeans(points, clusterCount, labels,
    TermCriteria( CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 10, 1.0),
    3, KMEANS_PP_CENTERS, centers);

img = Scalar::all(0);

for( i = 0; i < sampleCount; i++ )
    {
    int clusterIdx = labels.at<int>(i);
    Point ipt = points.at<Point2f>(i);
    circle( img, ipt, 2, colorTab[clusterIdx], CV_FILLED, CV_AA );
    }

cout<<"Center: \n"<<centers<<endl;

//用蓝色画出每个聚类的中心
//有bug,不让我直接用centers.at<Point2f>(i);,会异常
for( i = 0; i < clusterCount; i++ )
    {
    Point ipt = Point(centers.at<float>(i*2), centers.at<float>(i*2+1));
    circle( img, ipt, 5, Scalar(255,0,0),CV_FILLED, CV_AA );

    }
imshow("clusters", img);

下面图像是5个簇的kmeans聚类结果。

源代码参考工程:FirstOpenCV15

OpenCV学习(22) opencv中使用kmeans算法的更多相关文章

  1. OpenCV学习笔记(27)KAZE 算法原理与源码分析(一)非线性扩散滤波

    http://blog.csdn.net/chenyusiyuan/article/details/8710462 OpenCV学习笔记(27)KAZE 算法原理与源码分析(一)非线性扩散滤波 201 ...

  2. 机器学习中的K-means算法的python实现

    <机器学习实战>kMeans算法(K均值聚类算法) 机器学习中有两类的大问题,一个是分类,一个是聚类.分类是根据一些给定的已知类别标号的样本,训练某种学习机器,使它能够对未知类别的样本进行 ...

  3. OpenCV学习笔记——OpenCV安装

    关于OpenCV安装 1.下载和安装OpenCV SDK 在官网:http://opencv.org/上找到OpenCV windows版下载 . 后得到一个 opencv-2.X.X.exe的文件, ...

  4. sklearn中的KMeans算法

    1.聚类算法又叫做“无监督分类”,其目的是将数据划分成有意义或有用的组(或簇).这种划分可以基于我们的业务需求或建模需求来完成,也可以单纯地帮助我们探索数据的自然结构和分布. 2.KMeans算法将一 ...

  5. OpenCV学习(35) OpenCV中的PCA算法

    PCA算法的基本原理可以参考:http://www.cnblogs.com/mikewolf2002/p/3429711.html     对一副宽p.高q的二维灰度图,要完整表示该图像,需要m = ...

  6. OpenCV学习(39) OpenCV中的LBP图像

    本章我们学习LBP图像的原理和使用,因为接下来教程我们要使用LBP图像的直方图来进行脸部识别. 参考资料: http://docs.opencv.org/modules/contrib/doc/fac ...

  7. OpenCV学习(3) OpenCV框架

          OpenCV是一个开源的视觉库,其中包括很多计算机视觉的算法实现.在版本2.2以后,OpenCV采用C++特征的API,在1.x版本中,OpenCV函数都是传统的C语言形式.       ...

  8. OpenCV学习(1) OpenCV的安装

    前沿 准备了好几天,终于开始了,不管怎样,接下来的这个月一定把这本书很好的啃下来.当然OpenCV可以在很多的IDE下安装与配置,我这里就只在VS2010和VC6.0下安装配置了,当然这篇博文主要讲在 ...

  9. OpenCV学习:OpenCV源码编译(vc9)

    安装后的OpenCV程序下的build文件夹中,只找到了vc10.vc11和vc12三种编译版本的dll和lib文件,需要VS2010及以上的IDE版本,而没有我们常用的VS2008版本. 于是,需要 ...

随机推荐

  1. Linux下MySQL主从同步故障:"Slave_SQL_Running:No"的解决方法

    故障现象: 进入slave服务器,运行: mysql> show slave status\G          .......              Relay_Log_File: loc ...

  2. Python并发编程-IO模型-非阻塞IO实现SocketServer

    Server.py import socket sk = socket.socket() sk.bind(('127.0.0.1',8080)) sk.setblocking(False) #把soc ...

  3. 跟厂长学PHP7内核(二):源码分析的环境与工具

    本文主要介绍分析源码的方式,其中包含环境的搭建.分析工具的安装以及源码调试的基本操作. 一.工具清单 PHP7.0.12 GDB CLion 二.源码下载及安装 $ wget http://php.n ...

  4. Java 中线程安全问题

    不好意思,一个国庆假期给我放的都不知道东西南北了,放松,很放松,差一点就弃更了,感谢那些催更的小伙伴们! 虽然没有更新,但是日常的学习还是有的,以后我尽量给大家分享一些通用知识,非技术. 但是本期还是 ...

  5. python获取文件

    第一种:使用os.walk: # -*- coding: utf-8 -*- import os def Test1(rootDir): list_dirs = os.walk(rootDir) fo ...

  6. 转 SSM框架整合to萌新

    作用: SSM框架是spring MVC ,spring和mybatis框架的整合,是标准的MVC模式,将整个系统划分为表现层,controller层,service层,DAO层四层 使用spring ...

  7. [ 转载 ] Java开发中的23种设计模式详解(转)

    Java开发中的23种设计模式详解(转)   设计模式(Design Patterns) ——可复用面向对象软件的基础 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类 ...

  8. python opencv3 窗口显示摄像头的帧

    git:https://github.com/linyi0604/Computer-Vision # coding:utf8 import cv2 """ 在窗口显示摄像 ...

  9. 【BZOJ 2986】 莫比乌斯函数+容斥原理

    2986: Non-Squarefree Numbers Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 337  Solved: 156 Descri ...

  10. [BZOJ3309]DZY Loves Math(莫比乌斯反演+线性筛)

    $\sum\limits_{T=1}^{n}\lfloor\frac{n}{T}\rfloor\lfloor\frac{m}{T}\rfloor\sum\limits_{d|T}f(d)\mu(\fr ...