9

我正在尝试根据像素值分离灰度图像:假设一个 bin 中的像素从 0 到 60,另一个 bin 中的像素为 60-120,另一个中的像素为 120-180 ...,依此类推,直到 255。在此范围内大致等距案子。但是,通过使用 K-means 聚类,是否有可能更实际地衡量我的像素值范围应该是多少?试图一起获得相似的像素,而不是在像素浓度较低的地方浪费垃圾箱。

编辑(包括获得的结果): 在此处输入图像描述 在此处输入图像描述

k-means 没有集群 = 5

4

2 回答 2

11

当然,K-Means 可以用于颜色量化。这非常方便。

让我们看一个Mathematica中的例子:

我们从灰度 (150x150) 图像开始:

在此处输入图像描述

让我们看看用 8 位表示图像时有多少灰度级:

ac = ImageData[ImageTake[i, All, All], "Byte"];
First@Dimensions@Tally@Flatten@ac
-> 234

好的。让我们减少这 234 个级别。我们的第一个尝试是让算法单独确定默认配置下有多少个集群:

ic = ClusteringComponents[Image@ac];
First@Dimensions@Tally@Flatten@ic 
-> 3

它选择了3个簇,对应的图像是:

在此处输入图像描述

现在,是否可以,或者您需要更多集群,这取决于您。

假设您决定需要更细粒度的分色。让我们要求 6 个集群而不是 3 个:

ic2 = ClusteringComponents[Image@ac, 6];
Image@ic2 // ImageAdjust  

结果:

在此处输入图像描述

以下是每个 bin 中使用的像素范围:

Table[{Min@#, Max@#} &@(Take[orig, {#[[1]]}, {#[[2]]}] & /@ 
    Position[clus, n]), {n, 1, 6}]
-> {{0, 11}, {12, 30}, {31, 52}, {53, 85}, {86, 134}, {135, 241}}

以及每个 bin 中的像素数:

Table[Count[Flatten@clus, i], {i, 6}]
-> {8906, 4400, 4261, 2850, 1363, 720}

所以,答案是肯定的,而且很简单。

编辑

也许这将帮助您了解您在新示例中做错了什么。

如果我对您的彩色图像进行聚类,并使用聚类编号来表示亮度,我会得到:

在此处输入图像描述

这是因为星团没有按亮度升序编号。

但是如果我计算每个集群的平均亮度值,并用它来表示集群值,我得到:

在此处输入图像描述

在我之前的示例中,这不是必需的,但这只是运气:D(即按亮度升序找到簇)

于 2011-03-24T03:36:44.050 回答
2

k-means 可以应用于您的问题。如果是我,我会首先尝试从决策树中借鉴的基本方法(尽管“更简单”取决于您的精确聚类算法!)

假设存在一个 bin,开始将像素强度填充到 bin 中。当箱“足够满”时,计算箱(或节点)的均值和标准差。如果标准偏差大于某个阈值,则将节点分成两半。继续此过程,直到完成所有强度,您将获得更有效的直方图。

当然,可以通过其他细节来改进此方法:

  1. 您可以考虑使用峰度作为分割标准。
  2. 偏度可用于确定分裂发生的位置
  3. 您可能会一直跨入决策树领域并借用 Jini 索引来指导拆分(一些拆分技术依赖于更多“异国情调”的统计数据,例如 t 检验)。
  4. 最后,您可以执行最后的合并过程以折叠任何稀疏的节点。

当然,如果您已经应用了上述所有“改进”,那么您基本上已经实现了 k-means 聚类算法的一种变体;-)

注意:我不同意上面的评论-您描述的问题似乎与直方图均衡化没有密切关系。

于 2011-03-24T03:18:10.620 回答