2

私のアプリケーションでは、高速なアンマネージ コードを使用して複数の画像から RGB ピクセル値を読み取り、それらを HSB カラーに変換します。ここで、次のパーティションを使用して HSB ヒストグラムを作成したいと思います。

  • 色相: 18 分割、結果として 0 ~ 360 の 20 間隔
  • 彩度: 3 つのパーティション、0...1 から 0.33 の間隔になります。
  • 明るさ: 3 つのパーティション、結果として 0...1 から 0.33 の間隔になります

したがって、私のヒストグラムには合計 18*3*3=162 のパーティション (ビン) があり、各チャネルの下の間隔の境界で構成されています。

  • ビン1: [0, 0, 0]
  • ビン 2: [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 回の反復を必要とし、1 つの画像に対して少なくとも数百万回の反復が必要になります。

私の質問は、ピクセルの適切なビンをすぐに見つけることができるように、このデータ構造を高速化するにはどうすればよいですか? 長さ 162 の単純な配列は機能する可能性がありますが、指定されたパーティションにまだ削減されておらず、[259.234、0.5634、0.90534] のような値を含む可能性がある特定のピクセルの正しいビン インデックスを計算するにはどうすればよいですか?

4

2 に答える 2

2

単純に 3 次元配列を使用しないのはなぜですか? そのようです:

int[,,] histogram = new int[18, 3, 3];

// initialize to 0
for(int h = 0; h < 18; h++) {
  for(int s = 0; s < 3; s++) {
    for(int b = 0; b < 3; b++) {
      histogram[h, s, b] = 0;
    }
  }
}

// foreach pixel...
HsbColor c = ... // color of pixel
int h = (int)(c.Hue / 20);
int s = (int)(c.Saturation * 3);
int b = (int)(c.Brighthess * 3);

// take care of boundary cases (Hue, Saturation or Brightness maxed out)
if(h >= 18) h = 17;
if(s >= 3) s = 2;
if(b >= 3) b = 2;

histogram[h, s, b]++;

注意: ここでは、合計ピクセル数 (より正確には、1 つのビンに分類されるピクセルの最大数) が を超えないと想定していますint.MaxValuelongそれ以外の場合は、ヒストグラムの代わりにデータ型を使用することを検討してintください。

于 2011-04-17T22:47:05.843 に答える
0

次のように、HSV 番号を unsigned long に変換できます。

ulong colorLookupValue = (color.Hue/18) * 9 + (ulong)((color.Saturation*3) * 3) + (ulong)(color.Brightness * 3) 

これがビン インデックスです。

于 2011-04-17T22:51:19.593 に答える