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. windows svn post-commit 报错解决 error resolving case

    在svn仓库目录下有个hooks目录,下面建一个 post-commit.cmd 文件,有代码提交到仓库,自动checkout到指定目录.   @echo onSET REPOS=%1SET USER ...

  2. 在Notepad++上搭建Windows下Shell运行环境

    1.安装NotePad++ 第一步是安装Notepad++. 2.安装 Cygwin64 Terminal Cygwin64 Terminal是在Windows环境下,模拟运行Linux命令的软件,很 ...

  3. 【原创】MySQL常用脚本整理

    #1.查看表容量空间 ) ) ) AS 'free_size(G)' FROM information_schema.tables WHERE TABLE_SCHEMA='test' AND TABL ...

  4. JAVAEE——宜立方商城03:Nginx负载均衡高可用、Keepalived+Nginx实现主备

    1 nginx负载均衡高可用 1.1 什么是负载均衡高可用 nginx作为负载均衡器,所有请求都到了nginx,可见nginx处于非常重点的位置,如果nginx服务器宕机后端web服务将无法提供服务, ...

  5. C#拖拽操作

    C#的拖拽 本文将以Winform为例 有两个主要的事件: DragEnter 拖拽到区域中触发的事件 DragDrop 当拖拽落下的时候出发此事件 饮水思源 参考博客: http://www.cnb ...

  6. 1036 Boys vs Girls (25)(25 point(s))

    problem This time you are asked to tell the difference between the lowest grade of all the male stud ...

  7. 【CF398B】B. Painting The Wall(期望)

    B. Painting The Wall time limit per test 1 second memory limit per test 256 megabytes input standard ...

  8. [BZOJ4567][SCOI2016]背单词(Trie+贪心)

    1.题意表述十分难以理解,简单说就是:有n个单词,确定一个背的顺序,使总代价最小. 2.因为第(1)种情况的代价是n*n,这个代价比任何一种不出现第(1)种情况的方案都要大,所以最后肯定不会出现“背某 ...

  9. [HihoCoder1596]Beautiful Sequence

    题目大意: \(n(n\le60)\)个数\(A_{1\sim n}\),将这些数随机打乱,问最后构成的数列满足对于所有的\(2\le i\le n-1\),都有\(2A_i\le A_{i-1}+A ...

  10. Android中利用ant进行多渠道循环批量打包

    公司负责Android开发的小伙伴学习能力稍微偏弱,交代给他的自动化打包的任务,弄了好久依然没有成效.无奈只好亲自出手. 没有想到过程很顺利,我完全按照如下文章的步骤进行: 主要参考: Android ...