我正在玩一些图像处理,并决定阅读颜色量化的工作原理,经过一番阅读后,我发现了Modified Median Cut Quantization算法。
我一直在阅读Leptonica 库中的 C 实现代码,遇到了一些我认为有点奇怪的东西。
现在我想强调一下,我远不是这个领域的专家,我不是数学头脑,所以我预测这一切都归结为我没有理解所有这些,而不是算法的实现是错误的一点也不。
该算法规定vbox应沿最长轴拆分,并应使用以下逻辑拆分
通过定位具有中值像素(按人口)的箱,选择较长的边,并在该边的中心划分最大轴。我们可以简单地将具有中值像素的 bin 放在较短的一侧,但是在细分的早期阶段,这往往会将低密度簇(在细分中不考虑)放在同一个 vbox 中作为高密度的一部分即使未来基于中值的细分,它也会在中值 vbox 颜色中超过它。这里使用的算法在早期的细分中特别重要,3 对于给可见但人口少的颜色簇提供自己的 vbox 很有用。这对高密度集群的细分影响不大,最终将在其 vbox 中具有大致相等的人口。
为了论证的方便,我们假设我们有一个正在拆分的 vbox,并且红色轴是最大的。在 Leptonica 算法中,在第 01297 行,代码似乎执行以下操作
- 迭代红色的所有可能的绿色和蓝色变化
- 对于每次迭代,它都会添加到沿红轴找到的像素总数(总体)
- 对于每种红色,它将当前红色和以前红色的总数相加,从而为每种红色存储一个累积值
注意:当我说“红色”时,我指的是迭代所覆盖的沿轴的每个点,实际颜色可能不是红色,但包含一定量的红色
因此,为了说明起见,假设我们沿红轴有 9 个“箱”,并且它们具有以下总体
4 8 20 16 1 9 12 8 8
在所有红色 bin 的迭代之后,partialsum数组将包含上述 bin 的以下计数
4 12 32 48 49 58 70 78 86
总计的值为86
一旦完成,就该执行实际的中位数切割了,对于红色轴,这是在 01346 行执行的
它遍历箱并检查它们的累积总和。这是算法描述中让我想到的部分。它查找值大于total/2的第一个 bin
不是total/2意味着它正在寻找一个值大于平均值而不是中值的 bin吗?上述垃圾箱的中位数为49
使用43或49可能会对框的拆分方式产生巨大影响,即使该算法随后通过移动到匹配值所在的较大一侧的中心继续进行。
让我有点困惑的另一件事是,论文指定应该定位具有中值的 bin,但没有提到如果有偶数个 bin 时如何进行.. 中值将是(a+ b)/2并且不能保证任何垃圾箱都包含该人口计数。所以这就是让我觉得有一些近似值可以忽略不计的原因,因为分裂实际上是如何参与到所选箱的较大边的中心的。
对不起,如果它有点啰嗦,但我想尽可能彻底,因为它已经让我发疯了几天了;)