我正在玩图像处理,并决定阅读颜色量化的工作原理,经过一些阅读后我找到了Modified Median Cut Quantization算法。
我一直在阅读C implementation in Leptonica library的代码,并且遇到了一些我觉得有点奇怪的事情。
现在我要强调的是,我不是这方面的专家,不是我的数学头,所以我预测这一切都归结于我不理解所有这一切而不是实现算法错了。
该算法声明 vbox 应沿着摘要轴分割,并且应使用以下逻辑进行拆分
通过将bin与中值像素定位来划分最大轴 (按人口计算),选择较长的一侧,并在中心划分 那边我们可以简单地将bin与中值像素放在一起 在较短的一侧,但在细分的早期阶段,这 倾向于放置低密度集群(不考虑在内 细分)在同一个vbox中作为高密度集群的一部分 将以中位数vbox颜色投票,即使未来基于中位数 细分。这里使用的算法特别重要 早期细分,3对于提供可见但低的有用 人口颜色聚集他们自己的vbox。这几乎没有影响 高密度集群的细分,最终将具有 他们的vbox中人口大致相等。
为了论证,我们假设我们有一个vbox,我们正处于分裂过程中,红轴是最大的。在Leptonica算法中,在01297行,代码似乎执行以下操作
注意:当我说“红色”时,我指的是沿着轴的每个点被迭代覆盖,实际颜色可能不是红色但包含一定量的红色
因此,为了便于说明,假设我们沿红轴有9个“箱子”,并且他们有以下人口
4 8 20 16 1 9 12 8 8
在所有红色区域的迭代之后, partialsum 数组将包含上述区间的以下计数
4 12 32 48 49 58 70 78 86
总计的值为86
一旦完成,就应该执行实际的中值切割,对于红轴,这将在01346行执行
迭代垃圾箱并检查它们累积的总和。这是从算法描述中抛出我的部分。它查找的第一个bin的值更大 total / 2
不会 total / 2 意味着它正在寻找一个值大于平均值而不是中位数<的bin / em>?上述箱柜的中位数 49
使用 43 或 49 可能会对盒子的拆分方式产生巨大影响,即使算法然后移动到更大的中心匹配值的一侧是..
让我感到困惑的另一件事是,该文件指出应该找到具有中值的bin,但是如果有偶数个bin则没有提到如何继续..中位数将是(a + b)/ 2 并且无法保证任何垃圾箱都包含该人口数。所以这就是让我觉得有一些近似值可以忽略不计的原因,因为分裂实际上是如何在所选仓的较大边的中心进行的。
很抱歉,如果它有点长啰嗦,但我想尽可能多,因为它已经让我疯了几天了;)
答案 0 :(得分:2)
在9-bin示例中,49是前5个区间中的像素数。 49是 9个部分和的集合中的中位数,但我们希望集合中的像素为86像素,即43(或44),它居住在第4个垃圾箱。
检查leptonica的colorquant2.c中的修改的中值切割算法表明,3d盒的实际切割位置不一定发生在包含中值像素的仓附近。其原因在函数medianCutApply()中进行了解释。这是Paul Heckbert原创方法的“修改”之一。另一个重要的修改是根据人口和产品(人口*体积)的组合决定接下来切割哪个3d框,从而允许分割大的但人口稀少的颜色空间区域。
答案 1 :(得分:0)
我不知道算法,但我认为你的数组包含每个红色的数量;让我们用一个例子解释一下:
假设您有四个红色渐变:A,B,C和D. 并且您有以下红色值序列:
AABDCADBBBAAA
要查找中位数,您必须根据红色值对它们进行排序并取中间位置:
median
v
AAAAAABBBBCDD
现在让我们使用他们的方法:
A:6 => 6
B:4 => 10
C:1 => 11
D:2 => 13
13/2 = 6.5 => B
我认为不匹配的发生是因为你在计算人口;平均颜色为:
(6*A+4*B+1*C+2*D)/13