您的位置:首页 > 运维架构

OpenCV学习 kmeans实现图像分割

2016-05-26 07:22 483 查看
using namespace std;using namespace cv;int main(){const int MAX_CLUSTERS = 5;Vec3b colorTab[] ={Vec3b(0, 0, 255),Vec3b(0, 255, 0),Vec3b(255, 100, 100),Vec3b(255, 0, 255),Vec3b(0, 255, 255)};Mat data, labels;Mat pic = imread("C:/Users/dell/Desktop/1.jpg");for (int i = 0; i < pic.rows; i++)for (int j = 0; j < pic.cols; j++){Vec3b point = pic.at<Vec3b>(i, j);Mat tmp = (Mat_<float>(1, 3) << point[0], point[1], point[2]);data.push_back(tmp);}//根据浏览图片,确定k=3kmeans(data, 4, labels, TermCriteria(TermCriteria::EPS + TermCriteria::COUNT, 10, 1.0),3, KMEANS_RANDOM_CENTERS);int n = 0;//显示聚类结果,不同的类别用不同的颜色显示for (int i = 0; i < pic.rows; i++)for (int j = 0; j < pic.cols; j++){int clusterIdx = labels.at<int>(n);pic.at<Vec3b>(i, j) = colorTab[clusterIdx];n++;}imshow("pic", pic);waitKey(0);return 0;}
基本算法步骤:初始化:从 n个数据对象任意选择 k 个对象作为初始聚类中心;迭代:    1. 根据每个聚类对象的均值(中心对象),计算每个对象与这些中心对象的距离;并根据最小距离重新对相应对象进行分类;    2. 由新的分类数据,重新计算每个(有变化)聚类的均值(中心对象);    3. 计算标准测度函数,当满足一定条件,如函数收敛时,则算法终止;如果条件不满足则循环执行。如opencv中,每次迭代,最大的聚类中心位移max_center_shift < criteria.epsilon小于精度要求时,就结束迭代。以及迭代次数超过设定的最大值时,也结束 iter >= criteria.maxCount。结束。计算方差,及labels每个对象的分类结果,返回。算法的时间复杂度上界为O(n*k*t), 其中t是迭代次数。属于非监督学习方法。OpenCV中增加了参数:attempts:使用不同的初始化条件,进行分类的次数flag: KMEANS_RANDOM_CENTERS, KMEANS_PP_CENTERS, KMEANS_USE_INITIAL_LABELS        kmeans算法的2个缺点:第一是必须人为指定所聚的类的个数k;第二是如果使用欧式距离来衡量相似度的话,可能会得到错误的结果,因为没有考虑到属性的重要性和相关性。为了减少这种错误,在使用kmeans距离时,一定要使样本的每一维数据归一化,不然的话由于样本的属性范围不同会导致错误的结果。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: