ITKeyword,专注技术干货聚合推荐

注册 | 登录

[opencv]K-means聚类算法分割图像

kingcooper 分享于 2016-03-04

推荐:opencv grabcut 分割算法

grabcut基于论文"GrabCut" - Interactive Foreground Extraction using Iterated Graph Cuts,是微软亚洲研究院04年的论文。 本代码摘自opencv的示例代码,自己

2020腾讯云“6.18”活动开始了!!!(巨大优惠重现!4核8G,5M带宽 1999元/3年),
地址https://cloud.tencent.com/act/cps/redirect?redirect=1059

2020阿里云最低价产品入口,含代金券(新老用户有优惠),
地址https://www.aliyun.com/minisite/goods

1.K-means算法

K-means是一种经典的无监督聚类算法。

算法原理: (1)从N个数据对象中取K个点作为聚类中心。 (2)计算N个数据对象到各个聚类中心的距离,将N个数据对象划分到距离最近的中心,形成K个聚类。 (3)计算每个聚类的中心,将新的中心代替原来的中心。 (4)检查新老聚类中心的距离,重复(2)-(3)直到距离小于规定阈值。

2.opencv函数

链接: http://www.opencv.org.cn/opencvdoc/2.3.2/html/modules/core/doc/clustering.html?highlight=kmeans#cv.KMeans2 cvKMeans2(const CvArr* samples, int nclusters, CvArr* labels, CvTermCriteria criteria, int attempts=1, CvRNG*rng=0, int flags=0, CvArr* centers=0, double* compactness=0)

kmeans(InputArray samples, int clusterCount, InputOutputArray labels, TermCriteria criteria, int attempts, int flags, OutputArray centers=noArray() )

Parameters:
  • samples – Floating-point matrix of input samples, one row per sample.
  • clusterCount – Number of clusters to split the set by.
  • labels – Input/output integer array that stores the cluster indices for every sample.
  • criteria – The algorithm termination criteria, that is, the maximum number of iterations and/or the desired accuracy. The accuracy is specified as criteria.epsilon. As soon as each of the cluster centers moves by less than criteria.epsilon on some iteration, the algorithm stops.
  • attempts – Flag to specify the number of times the algorithm is executed using different initial labelings. The algorithm returns the labels that yield the best compactness (see the last function parameter).
  • flags –

    Flag that can take the following values:

    • KMEANS_RANDOM_CENTERS Select random initial centers in each attempt.
    • KMEANS_PP_CENTERS Use kmeans++ center initialization by Arthur and Vassilvitskii [Arthur2007].
    • KMEANS_USE_INITIAL_LABELS During the first (and possibly the only) attempt, use the user-supplied labels instead of computing them from the initial centers. For the second and further attempts, use the random or semi-random centers. Use one of KMEANS_*_CENTERS flag to specify the exact method.
  • centers – Output matrix of the cluster centers, one row per each cluster center.
sample

输入样本的浮点矩阵,每个样本一行

clusterCount

给定的聚类数目 

labels

输出整数向量:每个样本对应的类别标识 

criteria

迭代终止条件:迭代最大次数和精度

attempts

运行K-means的次数,取结果最好的聚类为最终聚类,和flags一起使用

flags

KMEANS_RANDOM_CENTERS 每次尝试选取随机初始化中心

KMEANS_PP_CENTERS  使用Arthur and Vassilvitskii算法进行中心初始化

KMEANS_USE_INITIAL_LABELS使用用户自定义初始点

3.实现

处理图像:

将图像的颜色数据进行K-means聚类,这里有黑、白、红三色,所以分为3类进行效果测试。

将图像每个像素三通道值按行存给样本samples。

	for (int i = 0; i < img->width;i++)
	{
		for (int j = 0; j < img->height;j++)
		{
			CvScalar s;
			s.val[0] = (float)cvGet2D(img, j, i).val[0];
			s.val[1] = (float)cvGet2D(img, j, i).val[1];
			s.val[2] = (float)cvGet2D(img, j, i).val[2];
			cvSet2D(samples,k++,0,s);
		}
	}
nCluster定义为3。

进行K-means聚类分析

推荐:学习opencv ,图像分割中分水岭算法的感性认识及cvWatershed例子

cvWatershed例子: [cpp]  view plain copy #include<cv.h>   #include<highgui.h>   #include<iostream>      using namespace  std;      IplImage* marker_ma

	cvKMeans2(samples,nCluster,clusters,cvTermCriteria(CV_TERMCRIT_ITER,100,1.0));
保存结果给clusters,这里是根据图像坐标对应颜色的聚类结果分别标志为0,1,2。

测试分类效果:

将图像基于聚类标签结果进行提取。

(1)提取标签0

	k = 0;
	int val = 0;

	for (int i = 0; i < img->width;i++)
	{
		for (int j = 0; j < img->height;j++)
		{
			val = (int)clusters->data.i[k++];

			CvScalar s1;
			if (val == 0)
			{
				s1.val[0] = 255;
			}
			else
			{
				s1.val[0] = 0;
			}
			cvSet2D(bin,j,i,s1);
		}
	}
将图像基于bin进行mask复制,显示标签0对应的区域

	cvThreshold(bin,bin,200,255,CV_THRESH_BINARY);
	IplImage *img1=cvCreateImage(cvSize(img->width,img->height),img->depth,img->nChannels);
	cvCopy(img,img1,bin);
	cvShowImage("原图", img);
	cvShowImage("bin",bin);
	cvShowImage("聚类图像",img1);
	cvWaitKey(0);

得到图像效果如下:



(2)提取标签1

将val改为1,得到图像效果如下:



(3)提取标签2

将val改为2,得到图像效果如下:









推荐:[置顶] 基于kmeans聚类算法的图像分割

Kmeans之前已经讲过了,其图像分割只不过是把之前的高斯数对换成图像二维像素点,彩色图像每个像素点有rgb三个分量,灰度图像只有一个分量。 1编程实现   <span

1.K-means算法 K-means是一种经典的无监督聚类算法。 算法原理: (1)从N个数据对象中取K个点作为聚类中心。 (2)计算N个数据对象到各个聚类中心的距离,将N个数据对象划分到距离最近的中心,形成K

相关阅读排行


相关内容推荐

最新文章

×

×

请激活账号

为了能正常使用评论、编辑功能及以后陆续为用户提供的其他产品,请激活账号。

您的注册邮箱: 修改

重新发送激活邮件 进入我的邮箱

如果您没有收到激活邮件,请注意检查垃圾箱。