OpenCV学习(22) opencv中使用kmeans算法

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

时间: 2024-09-14 14:11:55

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

OpenCV中的KMeans算法介绍与应用

一.KMeans算法介绍 KMeans算法是MacQueen在1967年提出的,是最简单与最常见的数据分类方法之一.它做为一种常见数据分析技术在机器学习.数据挖掘.模式识别.图像分析等领域都有应用.如果从分类角度看,KMeans属于硬分类即需要人为指定分类数目,而MeanSift分类方法则可以根据收敛条件自动决定分类数目.从学习方法上来说,KMeans属于非监督学习方法即整个学习过程中不需要人为干预的学习方法,自动完成整个数据集合分类.对于给定的数据集合DS (Data Set)与输入的分类数目

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

PCA算法的基本原理可以参考:http://www.cnblogs.com/mikewolf2002/p/3429711.html     对一副宽p.高q的二维灰度图,要完整表示该图像,需要m = p*q维的向量空间,比如100*100的灰度图像,它的向量空间为100*100=10000.下图是一个3*3的灰度图和表示它的向量表示: 该向量为行向量,共9维,用变量表示就是[v0, v1, v2, v3, v4, v5, v6, v7, v8],其中v0...v8,的范围都是0-255.    

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

本章我们学习LBP图像的原理和使用,因为接下来教程我们要使用LBP图像的直方图来进行脸部识别. 参考资料: http://docs.opencv.org/modules/contrib/doc/facerec/facerec_tutorial.html http://www.cnblogs.com/mikewolf2002/p/3438166.html       LBP的基本思想是以图像中某个像素为中心,对相邻像素进行阈值比较.如果中心像素的亮度大于等于它的相邻像素,把相邻像素标记为1,否则标

OpenCV学习(3) OpenCV框架

      OpenCV是一个开源的视觉库,其中包括很多计算机视觉的算法实现.在版本2.2以后,OpenCV采用C++特征的API,在1.x版本中,OpenCV函数都是传统的C语言形式.       OpenCV采用模块化的结构,每个模块都是由一些动态和静态库组成,该模块会实现一些特定的计算机视觉算法.要使用某个特定的库,我们必须在程序中先包含该库的头文件,并把该库的lib作为链接库. 例如要使用core和highgui库,则必须在程序源文件中包含: #include <opencv2/core

OpenCV学习(2) OpenCV的配置

      下面我们在VS2010中编写一个简单的OpenCV程序,来看看如何在程序中使用OpenCV. 创建一个新的Win32 控制台程序,附加选项为空工程(empty project),并添加一个cpp源文件main.cpp,内容如下: #include <opencv2/core/core.hpp> #include <opencv2/highgui//highgui.hpp> int main() { cv::Mat img = cv::imread("lenna

OpenCV学习(1) OpenCV的安装

1. 下载文件 下载最新的OpenCV windows版本: 链接:http://sourceforge.net/projects/opencvlibrary/files/opencv-win/       我下载的版本是2.46,下载后得到OpenCV-2.4.6.0.exe,自解压该文件到目录D:\opencv2.31\opencv2.46.自解压之后,会生成一个opencv的子目录,所有的opencv文件都在这个目录中. 2.编译文件 我使用CMake2.8来编译OpenCV:      

【原创】数据挖掘案例——ReliefF和K-means算法的医学应用

数据挖掘方法的提出,让人们有能力最终认识数据的真正价值,即蕴藏在数据中的信息和知识.数据挖掘 (DataMiriing),指的是从大型数据库或数据仓库中提取人们感兴趣的知识,这些知识是隐含的.事先未知的潜在有用信息,数据挖掘是目前国际上,数据库和信息决策领域的最前沿研究方向之一.因此分享一下很久以前做的一个小研究成果.也算是一个简单的数据挖掘处理的例子. 1.数据挖掘与聚类分析概述  数据挖掘一般由以下几个步骤:  (l)分析问题:源数据数据库必须经过评估确认其是否符合数据挖掘标准.以决定预期结

kmeans-用Mahout实现K-means算法

问题描述 用Mahout实现K-means算法 可以结合Hadoop平台在HDFS上传自己的数据实现Mahout中的kmeans吗? 怎么实现呢? 解决方案 一.介绍Mahout ? ? ? ? ?Mahout是Apache下的开源机器学习软件包,目前实现的机器学习算法主要包含有协同过滤/推荐引擎,聚类和分类三个部分.Mahout从设计开始就旨在建立可扩展的机器学习软件包,用于处理大数据机器学习的问题,当你正在研究的数据量大到不能在一台机器上运行时,就可以选择使用Mahout,让你的数据在Had

Python实现的Kmeans++算法实例_python

1.从Kmeans说起 Kmeans是一个非常基础的聚类算法,使用了迭代的思想,关于其原理这里不说了.下面说一下如何在matlab中使用kmeans算法. 创建7个二维的数据点: 复制代码 代码如下: x=[randn(3,2)*.4;randn(4,2)*.5+ones(4,1)*[4 4]]; 使用kmeans函数: 复制代码 代码如下: class = kmeans(x, 2); x是数据点,x的每一行代表一个数据:2指定要有2个中心点,也就是聚类结果要有2个簇. class将是一个具有7