В моем приложении я считываю значения пикселей RGB из нескольких изображений, используя быстрый неуправляемый код, а затем преобразую их в цвета HSB. Теперь я хотел бы построить гистограмму HSB, используя следующие разделы:
- Оттенок: 18 разделов, в результате интервалы от 20 до 0 ... 360
- Насыщенность: 3 раздела, в результате интервалы 0,33 от 0 ... 1
- Яркость: 3 раздела, в результате интервалы 0,33 от 0 ... 1
Таким образом, моя гистограмма имеет в общей сложности 18 * 3 * 3 = 162 разбиения (ячейки), которые состоят из нижних границ интервалов для каждого канала:
- Бин1: [0, 0, 0]
- Bin2: [0, 0, 0,33]
- Бин3: [0, 0, 0,66]
- Бин4: [0, 0,33, 0]
- Бин5: [0, 0,33, 0,33]
- ...
- Bin162: [340, 0,66, 0,66]
Я реализовал это, делая вид, что каждый бин будет самого цвета HSB. Поэтому я вычислил границы интервала бина, создал экземпляры HsbColor из этих значений и поместил цвета (обернутые в класс HsbHistogramBin) в простой список.
При добавлении нового HsbColor в мою гистограмму я использую следующий код, чтобы определить, какой бин мне нужно увеличить:
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 итерации, чтобы найти свою ячейку, что приводит к по меньшей мере миллионам итераций для одного изображения.
У меня такой вопрос: как я могу ускорить эту структуру данных, чтобы я мог сразу же найти нужную ячейку для своих пикселей? Простой массив длиной 162 может работать, но как рассчитать индекс правильного бина для заданного пикселя, который еще не сокращен до упомянутых разделов и может содержать значения, такие как [259.234, 0.5634, 0.90534]?