Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Color quantization of an image using K-means clustering (using RGB features)

Is it possible to clustering for RGB + spatial features of images with matlab?

NOTE: I want to use kmeans for clustering.

In fact basicly i want to do one thing, i want to get this image

enter image description here

from this

enter image description here

like image 726
seleucia Avatar asked Dec 11 '25 05:12

seleucia


1 Answers

I think you are looking for color quantization.

[imgQ,map]= rgb2ind(img,4,'nodither'); %change this 4 to the number of desired colors
                                       %in quantized image
imshow(imgQ,map);

Result:

Quantized image

Using kmeans :

%img is the original image

imgVec=[reshape(img(:,:,1),[],1) reshape(img(:,:,2),[],1) reshape(img(:,:,3),[],1)];
[imgVecQ,imgVecC]=kmeans(double(imgVec),4); %4 colors
imgVecQK=pdist2(imgVec,imgVecC); %choosing the closest centroid to each pixel, 
[~,indMin]=min(imgVecQK,[],2);   %avoiding double for loop

imgVecNewQ=imgVecC(indMin,:);  %quantizing
imgNewQ=img;
imgNewQ(:,:,1)=reshape(imgVecNewQ(:,1),size(img(:,:,1))); %arranging back into image
imgNewQ(:,:,2)=reshape(imgVecNewQ(:,2),size(img(:,:,1)));
imgNewQ(:,:,3)=reshape(imgVecNewQ(:,3),size(img(:,:,1)));

imshow(img)
figure,imshow(imgNewQ,[]);

Result of kmeans :

Quantized image by <code>kmeans</code>

If you want to add distance constraint to kmeans, the code will be slightly different. Basically, you need to concatenate pixel coordinates of corresponding pixel vales too. But remember, while assigning nearest centroid to each pixel, assign only the color i.e. the first 3 dimensions, not the last 2. That doesn't make sense, obviously. The code is very similar to the previous, please note the changes and understand them.

[col,row]=meshgrid(1:size(img,2),1:size(img,1));
imgVec=[reshape(img(:,:,1),[],1) reshape(img(:,:,2),[],1) reshape(img(:,:,3),[],1) row(:)   col(:)];
[imgVecQ,imgVecC]=kmeans(double(imgVec),4); %4 colors
imgVecQK=pdist2(imgVec(:,1:3),imgVecC(:,1:3));

[~,indMin]=min(imgVecQK,[],2);
imgVecNewQ=imgVecC(indMin,1:3);  %quantizing
imgNewQ=img;
imgNewQ(:,:,1)=reshape(imgVecNewQ(:,1),size(img(:,:,1))); %arranging back into image
imgNewQ(:,:,2)=reshape(imgVecNewQ(:,2),size(img(:,:,1)));
imgNewQ(:,:,3)=reshape(imgVecNewQ(:,3),size(img(:,:,1)));

imshow(img)
figure,imshow(imgNewQ,[]);

Result of kmeans with distance constraint:

enter image description here

like image 94
Autonomous Avatar answered Dec 12 '25 18:12

Autonomous