K-means

Kmeans又是一个以点到点距离为判断依据的算法,物理上的质心很好的形容了这个算法的目的。

说的没有做的理解深,还是实践一下。

#include "pch.h"
#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
#include "opencv2/imgcodecs.hpp"
#include <opencv2/highgui.hpp>
#include <opencv2/ml.hpp>
#include <iostream>

using namespace std;
using namespace cv;
using namespace cv::ml;

int main(int /*argc*/, char** /*argv*/)
{
	const int CLUSTERS_COUNT = 3; //3个聚类中心
	const int smpCount = 300; //300个样本点
	const int height = 500;
	Mat img(height, height, CV_8UC3);
	RNG rng(10000);
	int k, i;
	Mat points(smpCount, 1, CV_32FC2), labels;
	vector<Point2f> centers;
	Scalar colorTab[] =
	{
		Scalar(0, 0, 255),//红
		Scalar(0,255,0), //绿
		Scalar(255,0,0), //蓝
	};

	for (k = 0;k < CLUSTERS_COUNT;k++) {  //生成随机样本点
		Point center;
		center.x = rng.uniform(0, height);
		center.y = rng.uniform(0, height);
		Mat pointChunk = points.rowRange(k*smpCount / CLUSTERS_COUNT, (k+1)*smpCount / CLUSTERS_COUNT);
		rng.fill(pointChunk, RNG::NORMAL, Scalar(center.x, center.y), Scalar(height*0.05, height*0.05));
	}

	double compactness = kmeans(points, CLUSTERS_COUNT, labels, //执行kmeans算法
		TermCriteria(TermCriteria::EPS + TermCriteria::COUNT, 10, 1.0),
		3, KMEANS_PP_CENTERS, centers);

	img = Scalar::all(0);

	for (i = 0;i < smpCount;i++) {
		int clusterIdx = labels.at<int>(i);
		Point ipt = points.at<Point2f>(i);
		circle(img, ipt, 2, colorTab[clusterIdx], FILLED, LINE_AA); //将样本点绘制到img上

	}
	for (i = 0;i < (int)centers.size();i++) {
		Point2f c = centers[i];
		circle(img, c, 40, colorTab[i], i, LINE_AA); //画一个聚类中心为中心,半径为40的圆
	}

	imshow("kmeans", img);
	waitKey(0);
	return 0;
}

参考文章

https://blog.csdn.net/loveliuzz/article/details/78783773

https://zhuanlan.zhihu.com/p/27518705

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值