k-means算法MATLAB和opencv代码

来源:互联网 发布:财经日历重要数据解读 编辑:程序博客网 时间:2024/05/21 16:14

转自与http://blog.csdn.net/autocyz/article/details/46773143
该博客分两篇,第一篇讲解了K均值的原理,后一篇给出了实现的MATLAB代码和C++代码,还提供了聚类的效果。

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%    功能:实现如何利用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

这里写图片描述

以下是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;}
0 0
原创粉丝点击