Kmean聚类算法(c++实现)

#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;
}

每按一次空格进行一次迭代,可以看到多次迭代过后中心趋于不变。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值