博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
OpenCV学习(22) opencv中使用kmeans算法
阅读量:6614 次
发布时间:2019-06-24

本文共 2375 字,大约阅读时间需要 7 分钟。

kmeans算法的原理参考:

下面学习一下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

转载于:https://www.cnblogs.com/mikewolf2002/p/3372846.html

你可能感兴趣的文章
java中文乱码解决之道(二)—–字符编码详解:基础知识 + ASCII + GB**
查看>>
《ANTLR 4权威指南》——2.5 语法分析树监听器和访问器
查看>>
02_JNI中Java代码调用C代码,Android中使用log库打印日志,javah命令的使用,Android.mk文件的编写,交叉编译...
查看>>
IE 将支持 HSTS 安全机制
查看>>
《沟通的技术——让交流、会议与演讲更有效》一导读
查看>>
TIOBE 2016 年 5 月编程语言排行榜:Ruby 排名创历史新高
查看>>
《异构信息网络挖掘: 原理和方法(1)》一第1章 引言
查看>>
8 种提升 ASP.NET Web API 性能的方法 【已翻译100%】
查看>>
《Node.js区块链开发》——1.5 总结
查看>>
《深入理解Elasticsearch(原书第2版)》一1.1.1 熟悉Lucene
查看>>
这些国货,在阿里平台上被美国剁手党抢疯了
查看>>
《Excel 职场手册:260招菜鸟变达人》一第 2 招 常用快捷键Windows与Mac对照
查看>>
《Python自动化运维:技术与最佳实践》一1.2 实用的IP地址处理模块IPy
查看>>
《IP组播(第1卷)》一2.6 IGMP版本
查看>>
《Greenplum企业应用实战》一第1章 Greenplum简介1.1 Greenplum的起源和发展历程
查看>>
开源世界已成围城:成本让企业蜂拥而来,也让企业退缩转投
查看>>
这些废弃的 HTML 标签不要用
查看>>
嵌入式实时应用开发实战(原书第3版)》——3.3 保护模式架构
查看>>
IE11 就这样不会再变了
查看>>
备战物联网平台 科技巨头打响开发者争夺战
查看>>