在我的应用程序中,我使用快速非托管代码从多个图像中读取 RGB 像素值,然后将它们转换为 HSB 颜色。现在我想使用以下分区构建 HSB 直方图:
- 色调:18 个分区,从 0...360 产生 20 个间隔
- 饱和度:3 个分区,从 0...1 产生 0,33 的间隔
- 亮度:3 个分区,从 0...1 产生 0,33 的间隔
所以我的直方图总共有 18*3*3=162 个分区(bin),它们由每个通道的下间隔边界组成:
- Bin1: [0, 0, 0]
- Bin2: [0, 0, 0.33]
- Bin3: [0, 0, 0.66]
- Bin4: [0, 0.33, 0]
- Bin5: [0, 0.33, 0.33]
- ...
- Bin162:[340、0.66、0.66]
我实现了这个,假装每个 bin 本身都是 HSB 颜色。所以我计算了 bin 间隔边界,根据这些值创建了 HsbColor 实例,并将颜色(包装在 HsbHistogramBin 类中)放在一个简单的列表中。在我的直方图中添加一个新的 HsbColor 时,我使用以下代码来确定我需要增加哪个 bin:
private HsbHistogramBin FindBin(HsbColor color)
{
HsbHistogramBin bin = null;
bool foundBin = false;
for (int i = Bins.Count - 1; i >= 0; i--)
{
bin = Bins[i];
if (bin.Color.Hue > color.Hue)
continue;
if (bin.Color.Saturation > color.Saturation)
continue;
if (bin.Color.Brightness > color.Brightness)
continue;
foundBin = true;
break;
}
return foundBin ? bin : null;
}
public void AddColor(HsbColor color)
{
FindBin(color).Value++;
}
显然这太慢了。在最坏的情况下,每个像素需要 162 次迭代才能找到它的 bin,这导致单个图像至少需要数百万次迭代。
我的问题是:我怎样才能加快这个数据结构的速度,以便我可以立即为我的像素找到合适的 bin?一个长度为 162 的简单数组可能有效,但我如何计算给定像素的正确 bin 索引,该像素尚未减少到上述分区并且可能包含 [259.234, 0.5634, 0.90534] 之类的值?