1

3D グレースケール イメージのヒストグラム (単純な 1D 配列) を計算しました。ここで、各ポイントでこのヒストグラムの勾配を計算したいと思います。したがって、これは実際には、特定のポイントで 1D 関数の勾配を計算する必要があることを意味します。しかし、私には機能がありません。では、具体的な x 値と y 値を使用してどのように計算できますか?

簡単にするために、ヒストグラムの例でこれを説明していただけますか?たとえば、次の値を使用します(xは強度、yはこの強度の頻度):

x1 = 1; y1 = 3

x2 = 2; y2 = 6

x3 = 3; y3 = 8

x4 = 4; y4 = 5

x5 = 5; y5 = 9

x6 = 6; y6 = 12

x7 = 7; y7 = 5

x8 = 8; y8 = 3

x9 = 9; y9 = 5

x10 = 10; y10 = 2

これも数学の問題であることは知っていますが、c++ で解く必要があるため、ここで私を助けてくれます。

マルクさん、アドバイスありがとうございます

4

3 に答える 3

3

画像の境界検出で使用されるのと同じアプローチ(勾配計算)を使用して、勾配を計算できると思います。ヒストグラムがベクトルの場合、勾配の近似値を次のように計算できます*:

for each point in the histogram compute 
     gradient[x] = (hist[x+1] - hist[x])

これは非常に簡単な方法ですが、最も正確かどうかはわかりません。

  • 連続ではなく離散データを扱っているため、近似

編集

他の演算子は、小さな違いを強調する場合があります (小さなグラデーションがより強調されます)。ロバーツ アルゴリズムは、微分計算から派生します。

lim delta -> 0 = f(x + delta) - f(x) / delta

delta は (0 除算を避けるために) 無限に 0 になる傾向がありますが、ゼロになることはありません。コンピュータのメモリではこれは不可能であるため、取得できるデルタの最小値は 1 です (1 は画像 (またはヒストグラム) 内のポイントからポイントまでの最小距離であるため)。

代用

lim delta -> 0 to lim delta -> 1

我々が得る

f(x + 1) - f(x) / 1 = f(x + 1) - f(x) => vet[x+1] - vet[x]
于 2009-12-29T11:36:48.927 に答える
2

ここでは一般的に 2 つのアプローチがあります。

  1. 導関数の離散近似
  2. 当てはめ関数の実微分を取る

最初のケースでは、次を試してください。

g = (y_(i+1) - y_(i-1))/2*dx

端点を除くすべてのポイント、または次のいずれか

g_left-end  = (y_(i+1) - y_i)/dx
g_right-end = (y_i - y_(i-1))/dx

ここdxで、x ポイント間の間隔です。( Andresが提案した同様に正しい定義とは異なり、これは対称です。それが重要かどうかは、ユースケースによって異なります。)

2 番目のケースでは、データ [*] にスプラインを当てはめ、必要な点でスプライン ライブラリに導関数を求めます。

[*] ライブラリを使おう!これが学習プロジェクトでない限り、これを自分で実装しないでください。ROOTはマシンに既にあるので使用しますが、スプラインを取得するだけでもかなり重いパッケージです...


最後に、データにノイズが多い場合は、勾配検出を行う前に平滑化する必要があります。それは、ノイズを追うのを避け、大規模な斜面だけを見るということでした。

于 2009-12-29T17:22:29.473 に答える
2
  1. 方眼紙を取り、その上にヒストグラムを描きます。ヒストグラムの 0,0 ポイントを通る垂直軸と水平軸も描画します。

  2. 直線エッジを取り、関心のある各ポイントで、そのポイントでのグラデーションが何であるかについての考えと一致するまで、直線エッジを回転させます。これを行うことが最も重要です。グラデーションの定義は、あなたが望むものです。

  3. ストレート エッジが希望の角度になったら、その角度で線を引きます。

  4. 描いたばかりの線上の任意の 2 点から垂線を下ろします。選択した 2 点間の水平距離がヒストグラムの幅の約 25% 以上である場合、次の手順を実行しやすくなります。同じ 2 点から水平線を引き、ヒストグラムの垂直軸と交差します。

  5. 線は、x 距離と y 距離、つまり垂線/水平線との交点によってマークされた水平/垂直 (それぞれ) 軸の長さを定義します。必要なグラデーションは、y 距離を x 距離で割ったものです。

これをコードに変換するのは、ステップ 2 を除いて非常に簡単です。ヒストグラムの任意の点での勾配を決定するための基準を定義する必要があります。簡単な選択肢は次のとおりです。

a) 各ポイントで、ストレート エッジを下に置いてポイントを通過し、次のポイントをその右側に通過します。

b) 各ポイントで、ストレート エッジを下に置いてポイントを通過し、次のポイントを左に通過します。

c) 各ポイントで、左のポイントと右のポイントを通過するようにストレート エッジを設定します。

ヒストグラム上の多数の点を通る曲線 (2 次または高次の多項式など) をフィッティングし、その導関数を使用して勾配を表すなど、より複雑な選択を調査することが必要な場合があります。

紙の上の質問を理解するまで、C++ などでのコーディングは避けてください。それを理解すれば、コーディングは簡単です。

于 2009-12-29T11:08:22.410 に答える