k-means算法MATLAB和opencv代码
上一篇博客写了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代码的更多相关文章
- 基于GraphCuts图割算法的图像分割----OpenCV代码与实现
转载请注明出处:http://blog.csdn.net/wangyaninglm/article/details/44151213, 来自:shiter编写程序的艺术 1.绪论 图切割算法是组合图论 ...
- KNN 与 K - Means 算法比较
KNN K-Means 1.分类算法 聚类算法 2.监督学习 非监督学习 3.数据类型:喂给它的数据集是带label的数据,已经是完全正确的数据 喂给它的数据集是无label的数据,是杂乱无章的,经过 ...
- 光流算法:关于OpenCV读写middlebury网站给定的光流的代码
Middlebury是每个研究光流算法的人不可能不使用的网站,Middlebury提供了许多标准的测试库,这极大地推进了光流算法的进展.Middlebury提供的标准库,其计算出的光流保存在后缀名为. ...
- K-means算法
K-means算法很简单,它属于无监督学习算法中的聚类算法中的一种方法吧,利用欧式距离进行聚合啦. 解决的问题如图所示哈:有一堆没有标签的训练样本,并且它们可以潜在地分为K类,我们怎么把它们划分呢? ...
- 机器学习算法及代码实现–K邻近算法
机器学习算法及代码实现–K邻近算法 1.K邻近算法 将标注好类别的训练样本映射到X(选取的特征数)维的坐标系之中,同样将测试样本映射到X维的坐标系之中,选取距离该测试样本欧氏距离(两点间距离公式)最近 ...
- 时空上下文视觉跟踪(STC)算法的解读与代码复现(转)
时空上下文视觉跟踪(STC)算法的解读与代码复现 zouxy09@qq.com http://blog.csdn.net/zouxy09 本博文主要是关注一篇视觉跟踪的论文.这篇论文是Kaihua Z ...
- 从K近邻算法谈到KD树、SIFT+BBF算法
转自 http://blog.csdn.net/v_july_v/article/details/8203674 ,感谢july的辛勤劳动 前言 前两日,在微博上说:“到今天为止,我至少亏欠了3篇文章 ...
- mser 最大稳定极值区域(文字区域定位)算法 附完整C代码
mser 的全称:Maximally Stable Extremal Regions 第一次听说这个算法时,是来自当时部门的一个同事, 提及到他的项目用它来做文字区域的定位,对这个算法做了一些优化. ...
- 标准差分进化算法matlab程序实现(转载)
标准差分进化算法matlab程序实现 自适应差分演化算法方面的Matlab和C++代码及论文 差分进化算法 DE-Differential Evolution matlab练习程序(差异演化DE) [ ...
随机推荐
- java用正则方法验证文件名是否合法
Java中用到文件操作时,经常要验证文件名是否合法. 用File类的createNewFile()方法的确很管用.但当要批量验证时,效率上就会有问题.正则匹配的开销比创建文件少了很多. 那么一个合法的 ...
- java nio 映射文件内容到内存
FileChannel 的一个最好的功能就是能将文件的某个部分直接映射到内存.这要感谢 FileChannel.map() 方法,这个方法有下面三个参数: mode:映射到内存需要指定下面三种模式之一 ...
- 浏览器中回车(Enter)和刷新的区别是什么?[转载]
在浏览器中回车和F5刷新有什么区别那?今天就来说说:浏览器中回车(Enter)和刷新的区别是什么? 这点事. 概论: 1.回车在 Expires有效的时候,是不会去请求服务器的,打开调试看到的请求也只 ...
- go 删除数组元素
golang中对一个slice进行“slice”可以取片段得到一个新的slice,那么如何用简洁的代码删除slice中的一个元素呢? a := []int{0, 1, 2, 3, 4} //删除第i个 ...
- linux下生成https的crt和key证书
今天在配置kibana权限设置时,kibana要求使用https链接. 于是总结了一下linux下openssl生成 签名的步骤: x509证书一般会用到三类文,key,csr,crt Key 是 ...
- Gallery和自定义Adapter配合使用,实现图片预览
Gallery是一个可以拖动的列表,正中对应的是选中的东西.他和spinner有共同的父类:AbsSpinner 属性: android:animationDuration="1000&qu ...
- CSS3 Flex布局整理(二)-容器属性
一.Flex容器属性介绍 1.flex-flow :水平或垂直方向上的流动方式,包裹处理,其中包括了flex-direction属性和flex-wrap属性. 2.justify-content:定义 ...
- 内核态(Kernel Mode)与用户态(User Mode)
内核态: CPU可以访问内存所有数据, 包括外围设备, 例如硬盘, 网卡. CPU也可以将自己从一个程序切换到另一个程序 用户态: 只能受限的访问内存, 且不允许访问外围设备. 占用CPU的能力被剥夺 ...
- Java NIO AsynchronousFileChannel
In Java 7 the AsynchronousFileChannel was added to Java NIO. The AsynchronousFileChannel makes it po ...
- 6.2 dubbo在spring中自定义xml标签源码解析
在6.1 如何在spring中自定义xml标签中我们看到了在spring中自定义xml标签的方式.dubbo也是这样来实现的. 一 META_INF/dubbo.xsd 比较长,只列出<dubb ...