【问题标题】:how do I generate a single partitioned image using MATLABs kmeans function on a jpeg image?如何在 jpeg 图像上使用 MATLAB kmeans 函数生成单个分区图像?
【发布时间】:2014-09-23 15:51:43
【问题描述】:

我的问题与this 类似,只是推荐的分割可视化方法对我不起作用。

我想做的是使用 MATLAB 的 k-means 代码对 jpeg 图像进行分区,然后将结果可视化。 MATLAB help 上提供了用于生成每个像素的聚类平均值和聚类索引的代码,但不包括可视化分割的代码(或者至少不是以我想要的方式 - 我想要一个单一的视图分区图像,即所有由派生均值表示的簇都表示在同一图像中,而不是像示例中那样使用“均值”生成掩码)。

如上所述,somebody 发布了以下内容作为可视化结果的方式,但它对我不起作用:

imseg = zeros(size(im,1),size(im,2));
for i=1:max(idx)
    imseg(idx==i)=i;
end
imagesc(imseg)

【问题讨论】:

  • 这段代码如何“不起作用”?它会给你一个错误吗?它不给你一个形象吗?它给你的形象不是你想要的吗?
  • 你几乎说对了。您需要做的是找出哪些像素属于哪个集群,然后根据该集群的平均值对这些像素进行着色。我会写一个答案。

标签: matlab image-processing cluster-analysis


【解决方案1】:

上一篇文章所做的是将集群 ID 可视化为输出图像。您可能想要集群本身的平均值(因此 k-means)。从上一篇文章中可以很容易地做到和修改。我还将假设您的图像是uint8 类型,其中每个灰度/颜色通道跨越[0,255]。假设 idx 包含每个像素的成员资格,centroids 包含集群本身的实际颜色/灰度值,您只需要这样做:

imseg = uint8(zeros(size(im,1),size(im,2))); %// Cast to uint8 as image is of this type
centroids = uint8(centroids); %// Just in case, to ensure compatible data types
for i=1:max(idx)
    imseg(idx==i) = centroids(i); %// Set location to the centroid value, not ID
end
imagesc(imseg);

现在,如果您想要彩色图像,您只需将 2D 矩阵堆叠在一起。这可以通过以下方式完成:

%// Initialize red, green and blue planes
imRed = uint8(zeros(size(im,1), size(im,2))); %// Cast to uint8 as image is of this type
imGreen = imRed;
imBlue = imRed;
centroids = uint8(centroids); %// Just in case, to ensure compatible data types
for i=1:max(idx)
    imRed(idx==i) = centroids(idx,1); %// Find centroid value for RGB for each cluster
    imGreen(idx==i) = centroids(idx,2); %// and set accordingly
    imBlue(idx==i) = centroids(idx,3);
end
imseg = cat(3,imRed, imGreen, imBlue);
imagesc(imseg);

旁注

对于灰度情况,您完全可以通过以下方式进行矢量化处理:

imseg = centroids(idx);
imagesc(imseg);

我坚持使用for 循环方法,因为这似乎是您最熟悉的方法,但您可以使用idx 作为centroids索引数组,输出将本质上是一张地图,其中每个成员 ID 都具有与该集群关联的灰度值。

【讨论】:

  • 感谢您的帮助。不过,我缺少一些东西;您的解决方案假设质心的大小与 imRed 相同,但假设我只使用了 4 个集群,那么“质心”是 4x1 向量?
  • @Neil - 没关系。您将idx 用于index centroids,因此imseg 的输出仍将与图像大小相同。在此处查看矩阵/数组索引的工作原理:mathworks.com/company/newsletters/articles/…
  • @Neil - 也可以看看这篇文章:stackoverflow.com/questions/22997632/…。你会明白为什么我以我的方式索引这些东西。祝你好运,感谢您接受我的回答!
  • 感谢您提供这些链接;尝试运行代码时出现 2 个错误。第一个错误发生在以下行: imRed(idx==i) = centroids(idx,1);因为 numel(imRed(idx==i)) ~= numel(centroids(idx,1)) 如果执行以下命令,则会产生第二个错误:'centroids(idx,2)' - '索引超出矩阵维度。'这是代码的链接:drive.google.com/file/d/0B1-f_AEoV8EFOEp3TndKbzdaUlU/…
  • @Neil - 原因是您将图像数据转换为一维向量。您需要将数据转换为N x 3,然后再次运行代码。我没有时间帮你解决这个问题,但是在你运行 kmeans 之前先做。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-04-07
  • 2018-06-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-10
相关资源
最近更新 更多