(本文很短)
关于kmeans详细算法见文末链接
直接上代码:
主函数:
#include"1.0kmeans.hpp"
int main()
{
int m=500;
bool is_iris=1;
kmeans k;
k.load_pic();
k.init_kmeans();
while(m--)
{
k.sort();
k.reload_z();
k.fenxi();
cv::waitKey(0);
}
return 0;
}
相关函数:
#include <stdio.h>
#include<string.h>
#include<math.h>
#include<eigen3/Eigen/Eigenvalues>
#include<eigen3/Eigen/Dense>
#include<iostream>
#include<opencv/cv.h>
#include<opencv2/highgui.hpp>
//using namespace cv;
using namespace std;
using namespace Eigen;
class kmeans
{
private:
//计数用
int tag_a,tag_b,tag_c;
//数据阈值(初始化中心时用到)
double yu_iris[4][2],yu_sonar[60][2];
//载入数据
int data[68160][4];
public:
double dis(int a[],int b[],int add_a,int add_b,int deep_a,int num);
public:
double point_iris[3][4],point_sonar[2][60];
int point[3][3];
//载入数据
void load_pic();
void init_kmeans();
void sort();
void reload_z();
void fenxi();
};
void kmeans::load_pic()
{
cv::Mat a=cv::imread("3.bmp",1);
cv::imshow("src",a);
int tag=0;
for(tag_a=0;tag_a<320;tag_a++)
for(tag_b=0;tag_b<213;tag_b++)
{
for(tag_c=0;tag_c<3;tag_c++)
{
data[tag][tag_c]=a.at<cv::Vec3b>(tag_b,tag_a)[tag_c];
}
tag++;
}
}
void kmeans::fenxi()
{
int tag=0;
cv::Mat fra=cv::Mat(cv::Size(320,213), CV_8UC3);
for(tag_a=0;tag_a<320;tag_a++)
for(tag_b=0;tag_b<213;tag_b++)
for(tag_c=0;tag_c<3;tag_c++)
{
fra.at<cv::Vec3b>(tag_b,tag_a)[tag_c]=0;
}
for(tag_a=0;tag_a<320;tag_a++)
for(tag_b=0;tag_b<213;tag_b++)
{
fra.at<cv::Vec3b>(tag_b,tag_a)[int(data[tag][3])]=255;
tag++;
}
cv::imshow("pic_new",fra);
}
void kmeans::reload_z()
{
//各类总数
int number[3]={0,0,0};
double cent[3][3]={0,0,0,0,0,0,0,0,0};
for(tag_a=0;tag_a<68160;tag_a++)
{
for(tag_b=0;tag_b<3;tag_b++)
cent[int(data[tag_a][3])][tag_b]+=data[tag_a][tag_b];
number[int(data[tag_a][3])]++;
}
for(tag_a=0;tag_a<3;tag_a++)
for(tag_b=0;tag_b<3;tag_b++)
if(number[tag_a]!=0)
point[tag_a][tag_b]=cent[tag_a][tag_b]/number[tag_a];
}
double kmeans::dis(int a[],int b[],int add_a,int add_b,int deep_a,int num)
{
double num_all=0;
for(int tag_a=0;tag_a<num;tag_a++)
{
num_all+=(a[add_a*deep_a+tag_a]-b[add_b*num+tag_a])*(a[add_a*deep_a+tag_a]-b[add_b*num+tag_a]);
}
return pow(num_all,0.5);
}
void kmeans::sort()
{
int(*p)[4]=data;
int(*p_1)[3]=point ;
for(tag_a=0;tag_a<68160;tag_a++)
{
if(dis(*p,*p_1,tag_a,0,4,4)<=dis(*p,*p_1,tag_a,1,4,3)&&dis(*p,*p_1,tag_a,0,4,3)<=dis(*p,*p_1,tag_a,2,4,3))
data[tag_a][3]=0;
else if(dis(*p,*p_1,tag_a,1,4,3)<=dis(*p,*p_1,tag_a,0,4,3)&&dis(*p,*p_1,tag_a,1,4,3)<=dis(*p,*p_1,tag_a,2,4,3))
data[tag_a][3]=1;
else data[tag_a][3]=2;
}
}
void kmeans::init_kmeans()
{
for(tag_a=0;tag_a<3;tag_a++)
for(tag_b=0;tag_b<3;tag_b++)
point[tag_a][tag_b]=rand()%255;
}
ps:注意图片路径,代码按键进行下一次迭代
效果
算法方面详细请见kmeans,FCM处理iris数据集