【问题标题】:Color quantization of an image using K-means clustering (using RGB features)使用 K-means 聚类对图像进行颜色量化(使用 RGB 特征)
【发布时间】:2014-12-30 19:38:39
【问题描述】:

是否可以使用 matlab 对图像的 RGB + 空间特征进行聚类?

注意:我想使用kmeans 进行聚类。

其实基本上我想做一件事,我想得到这张图片

从这里

【问题讨论】:

  • 这个问题很模糊。但是,如果我理解正确,您的意思是您想使用图像的 RGB 值和空间特征进行聚类。如果是这样,那么是的,你可以这样做。一种方法是连接两个特征向量。对于 RGB,可以以颜色直方图为例。
  • 在聚类时我想考虑图像的空间特征。是否可以在matlab中提取图像的空间特征?
  • 空间特征是一个模糊的术语。如果将图像分成块,然后将块的颜色直方图连接起来,那么它们就是空间颜色特征。如果您采用 SIFT 特征并将其打包到词袋模型中,那么这些就是梯度的空间特征。你必须决定使用什么。由于您使用的是 RGB 功能,我认为 SIFT 会有意义。
  • 是的,这是可能的。您也许可以使用共现矩阵作为主要特征并在其上执行k-means。
  • 非常感谢您的所有帮助,我是计算机视觉的新手,因此有时我很难理解您的指示。事实上,基本上我想做一件事,我想从这个i.imgur.com/86VuM02.jpg 得到这个图像i.imgur.com/L44h8jf.jpg。我想通过集群来做到这一点。

标签: image matlab image-processing k-means


【解决方案1】:

我认为您正在寻找颜色量化。

[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 的结果:

如果要给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,[]);

kmeans 带距离约束的结果:

【讨论】:

  • +1 - 是的。这与原始帖子中描述的 OP 完全不同,但我相信这是所需要的。非常好。
  • 在聚类时我们是否也在考虑图像像素位置?如果没有,是否也可以为聚类矩阵添加此功能
  • 你可以,但我认为这将主导kmeans 的决定。试试吧。根据结果​​,我可以给你进一步的建议。请编辑您的问题,并在获得后将其添加到那里。
  • 仅据您所知,您将前往(称为)image segmentation。如果您将其作为作业/项目进行,那很好。但我只是想让您了解解决问题的更好方法。也许基于图论(比如归一化切割-> 旧的,但有用)。不过它们很​​复杂。
  • 好帖子!不错的提示。 +1
猜你喜欢
  • 2017-12-08
  • 2016-07-28
  • 2012-03-23
  • 1970-01-01
  • 2019-03-07
  • 2020-04-18
  • 2015-11-09
  • 2017-05-23
  • 2015-01-16
相关资源
最近更新 更多