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文件夹下)

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-27 18:56:25

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

K均值算法matlab实现

这个算法可以分两步实现,一个是function [d] = dist(x,y) 其中x和y分别代表一个向量:另外一个是function [y,C] = Kmeans( D,k ) 其中y为聚类中心分类集合,C为聚类中心集,D为目标矩阵(即为待分类的矩阵),k为聚类中心个数. 测试矩阵为: 测试结果如下: 不要问我是谁,请叫我红领巾

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

部分代码与文档是早些时候收集的,出处找不到了,还请原作者看到后联系注明. 图切算法是组合图论的经典算法之一.近年来,许多学者将其应用到图像和视频分割中,取得了很好的效果.本文简单介绍了图切算法和交互式图像分割技术,以及图切算法在交互式图像分割中的应用. 图像分割指图像分成各具特性的区域并提取出感兴趣目标的技术和过程,它是由图像处理到图像分析的关键步骤,是一种基本的计算机视觉技术.只有在图像分割的基础上才能对目标进行特征提取和参数测量,使得更高层的图像分析和理解成为可能.因此对图像分割方法的研究具

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

Middlebury是每个研究光流算法的人不可能不使用的网站,Middlebury提供了许多标准的测试库,这极大地推进了光流算法的进展.Middlebury提供的标准库,其计算出的光流保存在后缀名为.flo的文件中,Middlebury本身也提供了读取.flo文件中C++源码和Matlab源码.尽管如此,将源码写成与OpenCV结合的形式是我们更期望的,以下我写的读写.flo文件的源码.相对于Middlebury给定的源码,更简洁易懂. #include "CCC/COMCV.h" #

『cs231n』作业1问题1选讲_通过代码理解K近邻算法&amp;交叉验证选择超参数参数

通过K近邻算法探究numpy向量运算提速 茴香豆的"茴"字有... ... 使用三种计算图片距离的方式实现K近邻算法: 1.最为基础的双循环 2.利用numpy的broadca机制实现单循环 3.利用broadcast和矩阵的数学性质实现无循环 图片被拉伸为一维数组 X_train:(train_num, 一维数组) X:(test_num, 一维数组) 方法验证 import numpy as np a = np.array([[1,1,1],[2,2,2],[3,3,3]]) b

K-means算法

K-means算法很简单,它属于无监督学习算法中的聚类算法中的一种方法吧,利用欧式距离进行聚合啦. 解决的问题如图所示哈:有一堆没有标签的训练样本,并且它们可以潜在地分为K类,我们怎么把它们划分呢?     那我们就用K-means算法进行划分吧. 算法很简单,这么做就可以啦: 第一步:随机初始化每种类别的中心点,u1,u2,u3,--,uk; 第二步:重复以下过程: 然后 ,就没有然后了,就这样子. 太简单, 不解释.

编程算法 - K路归并排序(k-way merge sort) 代码(C++)

K路归并排序(k-way merge sort) 代码(C++) 本文地址: http://blog.csdn.net/caroline_wendy K路归并排序作为经典的外部排序算法, 是程序员必须要掌握的. 知识概念参考: <数据结构> 主要思想: 在k个已排序的文件中, 选择第一个值, 采用败者树, 更新二叉树结构, 最终选择最优值. 代码仅供参考, 如最小值用(-1)代替, 最大值用(100)代替. /* * main.cpp * * Created on: 2014年9月11日 *

从K近邻算法、距离度量谈到KD树、SIFT+BBF算法

从K近邻算法.距离度量谈到KD树.SIFT+BBF算法 从K近邻算法.距离度量谈到KD树.SIFT+BBF算法 前言 前两日,在微博上说:“到今天为止,我至少亏欠了3篇文章待写:1.KD树:2.神经网络:3.编程艺术第28章.你看到,blog内的文章与你于别处所见的任何都不同.于是,等啊等,等一台电脑,只好等待..”.得益于田,借了我一台电脑(借他电脑的时候,我连表示感谢,他说“能找到工作全靠你的博客,这点儿小忙还说,不地道”,有的时候,稍许感受到受人信任也是一种压力,愿我不辜负大家对我的信任)

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

本文转载自zouxy09博客,原文地址为http://blog.csdn.net/zouxy09/article/details/16889905:在此,仅当笔记mark一下及给大家分享一下. 时空上下文视觉跟踪(STC)算法的解读与代码复现 [email protected] http://blog.csdn.net/zouxy09 本博文主要是关注一篇视觉跟踪的论文.这篇论文是Kaihua Zhang等人今年投稿到一个会议的文章,因为会议还没有出结果,所以作者还没有发布他的Matlab源代码

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

mser 的全称:Maximally Stable Extremal Regions 第一次听说这个算法时,是来自当时部门的一个同事, 提及到他的项目用它来做文字区域的定位,对这个算法做了一些优化. 也就是中文车牌识别开源项目EasyPR的作者liuruoze,刘兄. 自那时起就有一块石头没放下,想要找个时间好好理理这个算法. 学习一些它的一些思路. 因为一般我学习算法的思路:3个做法, 第一步,编写demo示例. 第二步,进行算法移植或效果改进. 第三步,进行算法性能优化. 然后在这三个过程中