上一篇博客写了k-means聚类算法和改进的k-means算法。这篇博客就贴出相应的MATLAB和C++代码。

下面是MATLAB代码,实现用k-means进行切割:

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
功能:实现怎样利用Kmeans聚类实现图像的切割。
时间:2015-07
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function kmeans_segmentation()
clear;close all;clc;
%% 读取測试图像
im = imread('city.jpg');
imshow(im), title('Imput image'); %%转换图像的颜色空间得到样本
cform = makecform('srgb2lab');
lab = applycform(im,cform);
ab = double(lab(:,:,2:3));
nrows = size(lab,1); ncols = size(lab,2);
X = reshape(ab,nrows*ncols,2)';
figure, scatter(X(1,:)',X(2,:)',3,'filled'),title('image 2'); box on; %显示颜色空间转换后的二维样本空间分布
%% 对样本空间进行Kmeans聚类
k = 5; % 聚类个数
max_iter = 100; %最大迭代次数
[centroids, labels] = run_kmeans(X, k, max_iter); %% 显示聚类切割结果
figure, scatter(X(1,:)',X(2,:)'3,labels,'filled'),title('image 3'); %显示二维样本空间聚类效果
hold on; scatter(centroids(1,:),centroids(2,:), 60,'r','filled')
hold on; scatter(centroids(1,:),centroids(2,:),30,'g','filled')
box on; hold off;
%print -dpdf 2D2.pdf pixel_labels = reshape(labels,nrows,ncols);
rgb_labels = label2rgb(pixel_labels);
figure, imshow(rgb_labels), title('Segmented Image');
%print -dpdf Seg.pdf
end function [centroids, labels] = run_kmeans(X, k, max_iter)
% 该函数实现Kmeans聚类
% 输入參数:
% X为输入样本集,dxN
% k为聚类中心个数
% max_iter为kemans聚类的最大迭代的次数
% 输出參数:
% centroids为聚类中心 dxk
% labels为样本的类别标记
%% 採用K-means++算法初始化聚类中心
centroids = X(:,1+round(rand*(size(X,2)-1)));
labels = ones(1,size(X,2));
for i = 2:k
D = X-centroids(:,labels);
D = cumsum(sqrt(dot(D,D,1)));
if D(end) == 0, centroids(:,i:k) = X(:,ones(1,k-i+1)); return; end
centroids(:,i) = X(:,find(rand < D/D(end),1));
[~,labels] = max(bsxfun(@minus,2*real(centroids'*X),dot(centroids,centroids,1).'));
end %% 标准Kmeans算法
for iter = 1:max_iter
for i = 1:k, l = labels==i; centroids(:,i) = sum(X(:,l),2)/sum(l); end
[~,labels] = max(bsxfun(@minus,2*real(centroids'*X),dot(centroids,centroids,1).'),[],1); end
end

实现效果例如以下:

上图图一是一张帅哥刘德华的JPG格式相片。图二是将RGB空间的图片转换为LAB空间的分布图;图三是对LAB空间的图像进行聚类,一共三类,图四是将聚类后的LAB图转换为原来的RGB图。

下面是VS+opencv实现:

#include "opencv2/highgui/highgui.hpp"
#include "opencv2/core/core.hpp"
#include <iostream> using namespace cv;
using namespace std; int main( int /*argc*/, char** /*argv*/ )
{
const int MAX_CLUSTERS = 5;
Scalar colorTab[] =
{
Scalar(0, 0, 255),
Scalar(0,255,0),
Scalar(255,100,100),
Scalar(255,0,255),
Scalar(0,255,255)
}; Mat img(500, 500, CV_8UC3);
RNG rng(12345); for(;;)
{
int k, clusterCount = rng.uniform(2, MAX_CLUSTERS+1);
int i, sampleCount = rng.uniform(1, 1001);
Mat points(sampleCount, 2, CV_32F), labels; clusterCount = MIN(clusterCount, sampleCount);
Mat centers; /* generate random sample from multigaussian distribution */
for( k = 0; k < clusterCount; k++ )
{
Point center;
center.x = rng.uniform(0, img.cols);
center.y = rng.uniform(0, img.rows);
Mat pointChunk = points.rowRange(k*sampleCount/clusterCount,
k == clusterCount - 1 ? sampleCount :(k+1)*sampleCount/clusterCount);
rng.fill(pointChunk, CV_RAND_NORMAL, Scalar(center.x, center.y), Scalar(img.cols*0.05, img.rows*0.05));
}
randShuffle(points, 1, &rng);
kmeans(points, clusterCount, labels,
TermCriteria( CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 10, 1.0),3, KMEANS_PP_CENTERS, centers);
img = Scalar::all(0); for( i = 0; i < sampleCount; i++ )
{
int clusterIdx = labels.at<int>(i);
Point ipt = points.at<Point2f>(i);
circle( img, ipt, 2, colorTab[clusterIdx], CV_FILLED, CV_AA );
}
imshow("clusters", img);
char key = (char)waitKey();
if( key == 27 || key == 'q' || key == 'Q' )
break;
}
return 0;
}



这是产生随机的样本点,再用k-means进行聚类。

代码较为简陋。如有问题欢迎交流~

參考资料:

1、视觉机器学习20讲

2、opencv学习例程(在opencv安装路径的source目录下)

k-means算法MATLAB和opencv代码的更多相关文章

  1. 基于GraphCuts图割算法的图像分割----OpenCV代码与实现

    转载请注明出处:http://blog.csdn.net/wangyaninglm/article/details/44151213, 来自:shiter编写程序的艺术 1.绪论 图切割算法是组合图论 ...

  2. KNN 与 K - Means 算法比较

    KNN K-Means 1.分类算法 聚类算法 2.监督学习 非监督学习 3.数据类型:喂给它的数据集是带label的数据,已经是完全正确的数据 喂给它的数据集是无label的数据,是杂乱无章的,经过 ...

  3. 光流算法:关于OpenCV读写middlebury网站给定的光流的代码

    Middlebury是每个研究光流算法的人不可能不使用的网站,Middlebury提供了许多标准的测试库,这极大地推进了光流算法的进展.Middlebury提供的标准库,其计算出的光流保存在后缀名为. ...

  4. K-means算法

    K-means算法很简单,它属于无监督学习算法中的聚类算法中的一种方法吧,利用欧式距离进行聚合啦. 解决的问题如图所示哈:有一堆没有标签的训练样本,并且它们可以潜在地分为K类,我们怎么把它们划分呢?  ...

  5. 机器学习算法及代码实现–K邻近算法

    机器学习算法及代码实现–K邻近算法 1.K邻近算法 将标注好类别的训练样本映射到X(选取的特征数)维的坐标系之中,同样将测试样本映射到X维的坐标系之中,选取距离该测试样本欧氏距离(两点间距离公式)最近 ...

  6. 时空上下文视觉跟踪(STC)算法的解读与代码复现(转)

    时空上下文视觉跟踪(STC)算法的解读与代码复现 zouxy09@qq.com http://blog.csdn.net/zouxy09 本博文主要是关注一篇视觉跟踪的论文.这篇论文是Kaihua Z ...

  7. 从K近邻算法谈到KD树、SIFT+BBF算法

    转自 http://blog.csdn.net/v_july_v/article/details/8203674 ,感谢july的辛勤劳动 前言 前两日,在微博上说:“到今天为止,我至少亏欠了3篇文章 ...

  8. mser 最大稳定极值区域(文字区域定位)算法 附完整C代码

    mser 的全称:Maximally Stable Extremal Regions 第一次听说这个算法时,是来自当时部门的一个同事, 提及到他的项目用它来做文字区域的定位,对这个算法做了一些优化. ...

  9. 标准差分进化算法matlab程序实现(转载)

    标准差分进化算法matlab程序实现 自适应差分演化算法方面的Matlab和C++代码及论文 差分进化算法 DE-Differential Evolution matlab练习程序(差异演化DE) [ ...

随机推荐

  1. libcurl断点下载遇到的问题

    最近游戏把资源(图片.配置.lua)的加载.更新全部改了 ,加载其实还好,就是不走之前的zip解压方式.   以前的大体流程: 下载 –> 启动 –> 解压 –> 更新 –> ...

  2. Windows下LuaJIT的编译和使用

    1.下载LuaJIT,download>> 2.编译 开始 –> 程序 –> Microsoft Visual Studio xx –> Visual Studio To ...

  3. ListView取消和自定义分割线的方法

    一.不显示分割线 XML android:footerDividersEnabled="false"即可. JAVA mListView.setDivider(null); 二.改 ...

  4. PreApplicationStartMethodAttribute程序启动扩展

    一.PreApplicationStartMethodAttribute 类简介 应用程序启动时提供的扩展的支持. 命名空间:   System.Web程序集:  System.Web(位于 Syst ...

  5. 如何使用LaTeX让自己不乱?

    虽然说LaTeX声称排版容易,只关注内容,可是混合着源代码的结构很难让我只关注内容,最后看得眼睛疼,找什么都找不到. 匿名用户 30 人赞同 立即想到的几个建议: 选择有折叠功能 (folding) ...

  6. Vim 常用操作、查找和替换

    这篇文章来详细介绍 Vim 中查找相关的设置和使用方法. 包括查找与替换.查找光标所在词.高亮前景/背景色.切换高亮状态.大小写敏感查找等. 查找 在normal模式下按下/即可进入查找模式,输入要查 ...

  7. Anaconda需要添加的环境变量

    F:\Anaconda3 F:\Anaconda3\Scripts F:\Anaconda3\Library\bin

  8. 在windows2012上安装MSSQL 2008 Manage Studio 出现错误

    在windows2012上安装MSSQL 2008 Manage Studio 出现错误: 解决方法:重新建立一个管理员账户,用另外一个账户登陆,然后安装. 原因:未知 --------------- ...

  9. Oracle简单的备份和恢复-导入和导出-目录

    ylbtech-Oracle:Oracle简单的备份和恢复-导入和导出-目录 Oracle安全运行离不开良好的备份和恢复机制,因为我们不是DBA.所以我们也就不过多的讲解DBA的备份和恢复.作为程序员 ...

  10. 第四章 dubbo内核之aop源码解析

    ExtensionLoader<Protocol> loader = ExtensionLoader.getExtensionLoader(Protocol.class); final P ...