В моем приложении я считываю значения пикселей RGB из нескольких изображений с помощью быстрого неуправляемого кода, а затем конвертирую их в цвета HSB. Теперь я хочу построить гистограмму HSB, используя следующие разделы:
- Оттенок: 18 разделов, что соответствует 20 интервалам от 0 до 360.
- Насыщенность: 3 раздела, в результате получаются интервалы 0,33 от 0 до 1.
- Яркость: 3 раздела, что дает интервалы 0,33 от 0 до 1.
Итак, моя гистограмма имеет в общей сложности 18 * 3 * 3 = 162 раздела (бинов), которые состоят из нижних границ интервала для каждого канала:
- 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]
Я реализовал это, делая вид, что каждая корзина сама по себе будет цветом 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]?