#include <vector>
#include <iostream>
#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
#include <math.h>
using namespace std;
using namespace cv;
int main(){
vector<vector<double>> pointSets;
vector<Point2i> centralPoints;
centralPoints.push_back(Point2i(50,50)); //生成的待聚类的点的期望中心
centralPoints.push_back(Point2i(300,250));
centralPoints.push_back(Point2i(100,300));
for(int i=0;i<1000;i++)
{
vector<double> xy;
int count=i%3;
xy.push_back(centralPoints[count].x+double(rand())/RAND_MAX*150);
xy.push_back(centralPoints[count].y+double(rand())/RAND_MAX*150);
pointSets.push_back(xy);
}
Mat img(500,500,CV_8UC3);
for(int i=0;i<img.cols;i++)
{
for(int j=0;j<img.rows;j++)
{
for(int k=0;k<3;k++)
{
img.at<Vec3b>(i,j)[k]=255;
}
}
}
for(int i=0;i<pointSets.size();i++)
{
circle(img,Point2i((int)pointSets[i][0],(int)pointSets[i][1]),3,Scalar(255,0,0),-1);
cout<< (int)pointSets[i][0]<<' '<<(int)pointSets[i][1]<<endl;
}
//Kmeans Starts
vector<Point2i> initPoints;
for(int i=0;i<3;i++)
{
initPoints.push_back(Point2i(double(rand())/RAND_MAX*500,double(rand())/RAND_MAX*500));
cout<< initPoints[i] << endl;
}
//Every point to The center ' s distance
vector<Point2i> tempPoints;
for(int k=0;k<initPoints.size();k++)
{
tempPoints.push_back(initPoints[k]);
}
vector<Point2i> LastPoints;
for(int k=0;k<initPoints.size();k++)
{
LastPoints.push_back(tempPoints[k]);
}
for(int i=0;i<100;i++){
int pointNum[]={1,1,1,1,1,1};
for(int i =0;i<pointSets.size();i++)
{
int MinDistance=5000000;
int flag=0;
for(int j=0;j<tempPoints.size();j++)
{
int distance=(pointSets[i][0]-LastPoints[j].x)*(pointSets[i][0]-LastPoints[j].x)+(pointSets[i][1]-LastPoints[j].y)*(pointSets[i][1]-LastPoints[j].y);
//cout<<distance;
if (distance<MinDistance)
{
MinDistance=distance;
flag=j;
}
}
cout << "flag=" << flag << endl;
pointNum[flag]+=1;
tempPoints[flag].x+=pointSets[i][0];
tempPoints[flag].y+=pointSets[i][1];
}
Mat imgcopy=img.clone();
for(int i=0;i<centralPoints.size();i++)
{
tempPoints[i].x/=pointNum[i];
tempPoints[i].y/=pointNum[i];
LastPoints[i].x=tempPoints[i].x;
LastPoints[i].y=tempPoints[i].y;
circle(imgcopy,Point2i(tempPoints[i].x,tempPoints[i].y),6,Scalar(255,0,255),-1);
}
cout <<tempPoints<<endl;
imshow("Kmeans",imgcopy);
waitKey(0);
}
return 0;
}
每按一次空格进行一次迭代,可以看到多次迭代过后中心趋于不变。