首页 > 编程知识 正文

kmeans聚类原理介绍(k_means聚类的步骤)

时间:2023-05-06 03:25:42 阅读:90488 作者:1279

使用C++、opencv中的Kmeans进行图像分割

K-means算法的原理

k -均值算法是一种基于距离相似性的聚类算法,通过比较样本之间的相似性,将形式的样本分为相同的类别。 k均值算法的基本过程如下。

初始化常数,随机初始化k个集群中心。 重复计算以下流程,直到集群中心不再更改。 计算各样本与各集群中心的相似度,将样本分类为最相似的类别

计算被分类到各级的所有样本特征的平均值,将其平均值作为各级的新聚类中心

输出最终的集群中心和每个样本所属的类别。 k均值算法需要随机初始化k个簇中心,但是k均值算法对初始簇中心的选择非常敏感,如果所选簇中心不好,得到的簇结果会非常差,所以k -。

随机选择采样点作为数据集内第一个初始化的集群中心,然后选择剩下的集群中心。 计算采样中的各个采样点与初始化的簇中心的距离,选择其中最短的距离,选择概率上距离最大的采样作为新的簇中心,重复上述步骤直到确定簇中心

对于k个初始化的聚类中心,使用k均值算法计算最终的聚类中心。 有关k均值算法的原理,请参见https://www.cn blogs.com/pinard/p/6164214.html

359博客. csdn.net/loveliuzz/article /详细信息/78783773

opencv的Kmeans相关API :

Doublekmeans (输入数据,整数,输入基准,标准,输入标记,输出基准)

data:是需要自动聚类的数据,一般为Mat。 每个行为都有一个样本的浮点型矩阵。

k:分为几个类别,是比较重要的参数之一。

由bestLabels:返回的类标记。 是整数值。

criteria:算法结束的基准取得期待精度的反复最大次数

attempts:判断某个样本是某一类的最小聚类次数,例如,如果值为3,则即使某个样本被聚类三次,也确定该样本是同一类。

flags:确定如何计算群集的中心。 有三个值。 KMEANS_RANDOM_CENTERS表示将群集的中心随机初始化。 KMEANS_PP_CENTERS表示用kmeans算法初始化集群中心,KMEANS_USE_INITIAL_LABELS表示用户在第一个集群时指定的值初始化集群,之后

centers:用于初始化群集的中心。 与上一个flags参数的选择有关。 如果选择KMEANS_RANDOM_CENTERS来随机初始化群集的中心,则可以省略此参数。

使用聚类方法分割图像。 也就是说,图像的像素点值(通常使用彩色图像。 像素点值为3值数组(b,g,r ) () ) ) ) ) ) ) ) ) ) ) ) ),将图像中的所有点分类为n种,取得分割的效果,这里只显示代码效果,但实际上这可能有助于复杂的分割。

代码如下所示。

# #包括足球俱乐部

# #

# #包含iostream

# #包括匹配. h

# #包括向量机

# #包含地图

# #包括开放/CV.h

#include opencv/highgui.h

# #包括开放/核心. h

# #包括opencv2(opencv.HPP

//集群数宏定义

# #定义集群编号2

单一名称空间光碟;

单一名称空间固态硬盘;

//k均值聚类

最大群集(最大src )。

int row=src.rows;

英特尔公司=日本全国石油公司;

无符号长整型=低*酷;

//定义集群图像,存储各位置的类别标签

最大群集(大小,1,CV_32SC1);

//将源图转换为数据点

matsrcpoint (尺寸,1,CV_32FC3);

vec3f * src点_ p=(vec3f * ) src点.数据;

VEC3f*src_p=(VEC3f* ) src .数据;

无符号lo

ng int i; for (i = 0; i < size; i++) { *srcPoint_p = *src_p; srcPoint_p++; src_p++; } Mat center(ClusterNum, 1, CV_32FC3); //用不同的标记度量聚类中心距离和的紧密度 double compactness; compactness = kmeans(srcPoint, ClusterNum, clusters, cvTermCriteria(CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 10, 0.1), ClusterNum, KMEANS_PP_CENTERS, center); cout << "center row:" << center.rows << " col:" << center.cols << endl; for (int y = 0; y < center.rows; y++) { Vec3f* imgData = center.ptr<Vec3f>(y); for (int x = 0; x < center.cols; x++) { cout << imgData[x].val[0] << " " << imgData[x].val[1] << " " << imgData[x].val[2] << endl; } cout << endl; } double minH, maxH; minMaxLoc(clusters, &minH, &maxH); cout << "H-channel min:" << minH << " max:" << maxH << endl; int* clusters_p = (int*)clusters.data; Mat label(src.size(), CV_32SC1); int* label_p = (int*)label.data; //将类别分配给Mat标签 for (i = 0; i < size; i++) { *label_p = *clusters_p; label_p++; clusters_p++; } Mat label_show; label.convertTo(label_show, CV_8UC1); normalize(label_show, label_show, 255, 0, CV_MINMAX); imshow("label", label_show); map<int, int> count; map<int, Vec3f> avg; for (int y = 0; y < row; y++) { const Vec3f* imgData = src.ptr<Vec3f>(y); int* idx = label.ptr<int>(y); for (int x = 0; x < col; x++) { avg[idx[x]] += imgData[x]; count[idx[x]] ++; } } //output the average value (clustering center) //计算所得的聚类中心与kmean函数中center的第一列一致, //以后可以省去后面这些繁复的计算,直接利用center, //但是仍然不理解center的除第一列以外的其他列所代表的意思 for (i = 0; i < ClusterNum; i++) { avg[i] /= count[i]; if (avg[i].val[0]>0 && avg[i].val[1]>0 && avg[i].val[2]>0) { cout << i << ": " << avg[i].val[0] << " " << avg[i].val[1] << " " << avg[i].val[2] << " count:" << count[i] << endl; } } //显示聚类图像 Mat showImg(src.size(), CV_32FC3); for (int y = 0; y < row; y++) { Vec3f* imgData = showImg.ptr<Vec3f>(y); int *idx = label.ptr<int>(y); for (int x = 0; x < col; x++) { int id = idx[x]; imgData[x].val[0] = avg[id].val[0]; imgData[x].val[1] = avg[id].val[1]; imgData[x].val[2] = avg[id].val[2]; } } normalize(showImg, showImg, 1, 0, CV_MINMAX);//标准化 imshow("show", showImg); waitKey(); return label;//返回聚类后的标签 } int main() { //读取图像 Mat img = imread("D:\1.jpg", 1); if (!img.data) { cout << "src image load failed!" << endl; return -1; } imshow("src", img); //高斯滤波降噪 GaussianBlur(img, img, Size(3, 3), 0); //转换图片类型 img.convertTo(img, CV_32FC3); //聚类操作 Mat pixId = clustering(img); }

源图:

标签图(分类后的结果,代码中分为2类):

结果图:

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。