使用K-means聚类算法(使用RGB特征)对图像进行颜色量化

3

能否使用matlab对图像的RGB + 空间特征进行聚类?注意:我想使用kmeans进行聚类。

实际上,我只想做一件事,就是从这个图片

enter image description here

得到这个图片

enter image description here


在进行聚类时,我想考虑图像的空间特征。是否可能在Matlab中提取图像的空间特征? - seleucia
空间特征是一个模糊的术语。如果将图像分成块,然后连接这些块的颜色直方图,则它们将成为空间颜色特征。如果您将SIFT特征打包到词袋模型中,则这些是梯度的空间特征。您必须决定使用什么。由于您正在使用RGB特征,因此我认为使用SIFT会有意义。 - Autonomous
是的,这是可能的。你可以使用共现矩阵作为主要特征,并在其上执行 k-means。 - rayryeng
感谢您关注这个问题,我已经重新编辑并进行了更正。由于它恰好用于我的项目中,我不应该使用“动物”图像。对于不适当的情况,我感到抱歉。 - seleucia
顺便问一下,有没有办法减少像素位置对聚类的影响? 你认为归一化或标准化RGB值会有帮助,能得到更好的结果吗? - seleucia
显示剩余4条评论
1个回答

6
我认为您正在寻找颜色量化技术。
[imgQ,map]= rgb2ind(img,4,'nodither'); %change this 4 to the number of desired colors
                                       %in quantized image
imshow(imgQ,map);

结果:

压缩图像

使用 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,[]);
kmeans的结果如下:

使用<code>kmeans</code>量化后的图像

如果您想将距离约束添加到kmeans中,则代码会稍有不同。基本上,您需要将相应像素值的像素坐标连接起来。但是请记住,在为每个像素分配最近的质心时,仅分配颜色,即前3个维度,而不是后2个维度。这显然没有意义。代码与先前非常相似,请注意更改并理解它们。
[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,[]);
< p > 带距离约束的 < code > kmeans 结果: < /p > < p > enter image description here < /p >

1
+1 - 啊,是的。这与原始帖子中OP所描述的完全不同,但我相信这就是所需的。非常好。 - rayryeng
在我们进行聚类时,我们是否也考虑了图像像素位置?如果没有的话,是否可以为聚类矩阵添加这个特性? - seleucia
你可以这样做,但我认为这会主导kmeans的决策。试一下吧。根据结果,我可以给你进一步的建议。请编辑你的问题并将其添加到那里。 - Autonomous
1
只是提供给您的知识,您正在朝着(所谓的)“图像分割”方向前进。如果您正在做这个作业/项目,那么很好。但我只是想让您了解更好的解决问题方法。也许基于图论(比如归一化割 -> 老但有用)。虽然它们很复杂。 - Autonomous
1
很棒的文章!不错的技巧。+1 - chappjc

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接