首先是基础知识:
Mean Shift 分割是一种局部均质化技术,对于抑制局部对象中的阴影或色调差异非常有用。
一个例子胜过许多言语:
Action:将每个像素替换为范围 r 邻域中且其值在距离 d 内的像素的平均值。
均值平移通常需要 3 个输入:
- 用于测量像素之间距离的距离函数。通常是欧几里德距离,但也可以使用任何其他明确定义的距离函数。这曼哈顿
距离 http://en.wikipedia.org/wiki/Taxicab_geometry有时是另一个有用的选择。
- 一个半径。该半径(根据上述距离测量)内的所有像素都将被纳入计算。
- 价值差异。对于半径 r 内的所有像素,我们将只取那些值在此差值内的像素来计算平均值
请注意,该算法在边界处没有明确定义,因此不同的实现会给您带来不同的结果。
我不会在这里讨论血淋淋的数学细节,因为如果没有正确的数学符号,它们就不可能显示,在 StackOverflow 中不可用,而且还因为它们可以找到来自其他地方的良好来源 http://saravananthirumuruganathan.wordpress.com/2010/04/01/introduction-to-mean-shift-algorithm/.
让我们看看矩阵的中心:
153 153 153 153
147 96 98 153
153 97 96 147
153 153 147 156
通过合理选择半径和距离,四个中心像素将得到 97(其平均值),并且与相邻像素不同。
我们来计算一下数学 http://www.wolfram.com/mathematica/。我们将显示颜色编码,而不是显示实际数字,因此更容易理解正在发生的情况:
矩阵的颜色编码是:
然后我们采取合理的Mean Shift:
MeanShiftFilter[a, 3, 3]
我们得到:
其中所有中心元素都相等(顺便说一句,为 97)。
您可以使用均值平移迭代多次,尝试获得更均匀的着色。经过几次迭代后,您将获得稳定的非各向同性配置:
此时,应该清楚的是,您无法选择应用 Mean Shift 后获得多少“颜色”。那么,让我们展示如何做到这一点,因为这是您问题的第二部分。
您需要能够提前设置输出簇的数量,类似于K均值聚类 http://en.wikipedia.org/wiki/K-means_clustering.
它以这种方式为你的矩阵运行:
b = ClusteringComponents[a, 3]
{{1, 1, 1, 1, 1, 1, 1, 1},
{1, 2, 2, 3, 2, 3, 3, 1},
{1, 3, 3, 3, 3, 3, 3, 1},
{1, 3, 2, 1, 1, 3, 3, 1},
{1, 3, 3, 1, 1, 2, 3, 1},
{1, 3, 3, 2, 3, 3, 3, 1},
{1, 3, 3, 2, 2, 3, 3, 1},
{1, 1, 1, 1, 1, 1, 1, 1}}
Or:
这与我们之前的结果非常相似,但正如您所看到的,现在我们只有三个输出级别。
HTH!