k均值
2016-08-02 11:34
246 查看
算法流程如下:
1.输入数据集合和类别数K(由用户指定)。
2.随机分配类别中心点的位置。
3.将每个店放入离它最近的类别中心点所在的集合。
4.移动类别中心点到他所在集合的中心。
5.转到第三步,直到收敛。
opencv里提供的实例代码如下:
opencv实例代码中随机数占用了太多篇幅,不利用更快理解k均值算法,可以自己写一组数多进行测试感受下,比如:
1.输入数据集合和类别数K(由用户指定)。
2.随机分配类别中心点的位置。
3.将每个店放入离它最近的类别中心点所在的集合。
4.移动类别中心点到他所在集合的中心。
5.转到第三步,直到收敛。
opencv里提供的实例代码如下:
#include "StdAfx.h" #include "opencv2/highgui/highgui.hpp" #include "opencv2/core/core.hpp" #include <iostream> using namespace cv; using namespace std; // static void help() // { // cout << "\nThis program demonstrates kmeans clustering.\n" // "It generates an image with random points, then assigns a random number of cluster\n" // "centers and uses kmeans to move those cluster centers to their representitive location\n" // "Call\n" // "./kmeans\n" << endl; // } int main( int /*argc*/, char** /*argv*/ ) { const int MAX_CLUSTERS = 8; //类别个数上限 Scalar colorTab[] = //返回的类别显示的颜色 { Scalar(0, 0, 255), Scalar(0,255,0), Scalar(255,100,100), Scalar(255,0,255), Scalar(0,255,255) }; Mat img(500, 500, CV_8UC3); RNG rng(12345); for(;;) { 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; /* generate random sample from multigaussian distribution */ 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); rng.fill(pointChunk, CV_RAND_NORMAL, Scalar(center.x, center.y), Scalar(img.cols*0.05, img.rows*0.05)); } randShuffle(points, 1, &rng); 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 ); } imshow("clusters", img); char key = (char)waitKey(); if( key == 27 || key == 'q' || key == 'Q' ) // 'ESC' break; } return 0; }
opencv实例代码中随机数占用了太多篇幅,不利用更快理解k均值算法,可以自己写一组数多进行测试感受下,比如:
#include "StdAfx.h" #include "opencv2/highgui/highgui.hpp" #include "opencv2/core/core.hpp" #include <iostream> using namespace cv; using namespace std; // static void help() // { // cout << "\nThis program demonstrates kmeans clustering.\n" // "It generates an image with random points, then assigns a random number of cluster\n" // "centers and uses kmeans to move those cluster centers to their representitive location\n" // "Call\n" // "./kmeans\n" << endl; // } int main( int /*argc*/, char** /*argv*/ ) { const int MAX_CLUSTERS = 8; //类别个数上限 Scalar colorTab[] = //返回的类别显示的颜色 { Scalar(0, 0, 255), Scalar(0, 255, 0), Scalar(255, 100, 100), Scalar(255, 0, 255), Scalar(0, 255, 255) }; Mat img(500, 500, CV_8UC3); RNG rng(12345); //for (;;) //{ int k, clusterCount =3/* rng.uniform(2, MAX_CLUSTERS + 1)*/;//类别个数随机产生 int i, sampleCount = 6/*rng.uniform(1, 1001)*/; Mat points(sampleCount, 1, CV_32FC2), labels; //struct point_xy //{ //}; Point2f point_xy[6], center; center.x = 300; center.y =300; point_xy[0].x = 100 + center.x; point_xy[0].y = 100 + center.y; point_xy[1].x = 110 + center.x; point_xy[1].y = 120 + center.y; point_xy[2].x = 1 + center.x; point_xy[2].y = 1 + center.y; point_xy[3].x = 120 + center.x; point_xy[3].y = 120 + center.y; point_xy[4].x = 169 + center.x; point_xy[4].y = 140 + center.y; point_xy[5].x = 130 + center.x; point_xy[5].y = 130 + center.y; for (int j = 0; j < sampleCount;j++) { point_xy[j].x = point_xy[j].x; point_xy[j].y = point_xy[j].y; } for (int j = 0; j < sampleCount; j++) { points.at<Point2f>(j).x = point_xy[j].x ; points.at<Point2f>(j).y = point_xy[j].y ; } for (int j = 0; j < sampleCount; j++) { points.at<Point2f>(j) = point_xy[j]; } clusterCount = MIN(clusterCount, sampleCount); Mat centers; /* generate random sample from multigaussian distribution */ //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); // rng.fill(pointChunk, CV_RAND_NORMAL, Scalar(center.x, center.y), Scalar(img.cols*0.05, img.rows*0.05)); //} /*randShuffle(points, 1, &rng);*/ 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); } imshow("clusters", img); char key = (char)waitKey(); return 0; }
相关文章推荐
- swift -- 更改 tableview section header
- 进程间通信笔记(1)—简介
- JAVA动态代理用法与实现过程
- jsp标准标签库
- linux 用户和组管理相关的命令
- PHP关于二叉树的前序中序后序遍历操作
- iOS内存错误EXC_BAD_ACCESS的解决方法
- R 速学之篇二
- activity从底部弹出动画
- 极其蛋疼的if else 中的break用法
- 【2015-2016 ACM-ICPC, NEERC, Northern Subregional Contest D】---暑假三校训练
- .net4.6版本前设置window子窗口位置主窗口闪烁
- 大型网站技术架构:核心原理与案例分析—第三章:大型网站核心架构要素
- NoSuchMethodError: redis.clients.jedis.JedisShardInfo.setTimeout(I)V
- 单例模式内存分析
- poj 1258
- 掘金量化回测平台 - 1
- 当效率至关重要时map::operator[]与map.insert之间的选择
- 【LeetCode】 066. Plus One
- Android Storage Access Framework(存储访问框架)