K-means algorithm MATLAB and opencv code, k-meansopencv
In the previous blog, I wrote the k-means clustering algorithm and the improved k-means algorithm. This blog posts the corresponding MATLAB and C ++ code.
The following is the MATLAB code to use k-means for segmentation:
% Functions: how to Use Kmeans clustering to achieve image segmentation; Time: 2015-07% % % function kmeans_segmentation () clear; close all; clc; % read test image im = imread('city.jpg '); imshow (im), title ('imput image '); % convert the color space of the image to get the sample cform = makecform ('srgb2lab '); lab = applycform (im, cform); AB = double (lab (:,:, 2: 3); nrows = size (lab, 1); ncols = size (lab, 2); X = resh Ape (AB, nrows * ncols, 2) '; figure, scatter (X (1, :)', X (2, :) ', 3, 'filened '), title ('image 2'); box on; % display two-dimensional sample space distribution after color space conversion % Kmeans clustering of Sample Space k = 5; % number of clusters max_iter = 100; % maximum number of iterations [centroids, labels] = run_kmeans (X, k, max_iter); % display the clustering splitting result figure, scatter (X (1, :) ', X (2, :) '3, labels, 'filened'), title ('image 3'); % displays the clustering effect of two-dimensional sample space. hold on; scatter (centroids (1, :), centroids (2, :), 60, 'R', 'filed') hold on; scatter (cen Troids (1, :), centroids (2, :), 30, 'G', 'filened') 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 seg1_end function [centroids, labels] = run_kmeans (X, k, max_iter) % This function implements Kmeans clustering % input parameter: % X is the input sample set, dxN % k is the number of cluster centers % max_iter is the maximum number of iterations of the kemans Cluster % output parameter: % centroids is the Cluster Class center dxk % labels is the class tag % of the sample. The K-means ++ algorithm is used to initialize the cluster center 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 % standard Kmeans Algorithm 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
The implementation result is as follows:
Figure 1 shows a JPG photo of handsome Liu Dehua, and figure 2 shows a diagram of converting an RGB space image into a LAB space. Figure 3 shows three types of LAB space images for clustering, figure 4 converts the LAB diagram after clustering to the original RGB diagram.
The following is the implementation of 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;}
This is a random sample point, and k-means is used for clustering.
The code is relatively simple. If you have any questions, please contact us ~
References:
1. Visual machine learning 20 lectures
2. opencv learning routine (in the source folder of the opencv installation path)
Copyright Disclaimer: This article is an original article by the blogger and cannot be reproduced without the permission of the blogger.