8

ヒストグラム(intの配列で表される)があり、ローカルの最大値と最小値を見つける最良の方法を探しています。各ヒストグラムには3つのピークがあり、そのうち1つはおそらく他のピークよりもはるかに高いピークです。ヒストグラムの極大/ピークと極小点の検索

  1. 最初の「谷」(絵に完全に最初のピークを取り除くために)最初のピークを以下の

  2. を検索を検索:

    は、私はいくつかのことをしたいです残りの2つのピークの間に最適な「谷」値を設定して画像を区切ります。

    大津の亜種を実装することで、手順2を実行する方法はすでに分かっています。 しかし、私はステップ1と苦労しています

  3. 残りの2つのピークの間の谷が十分に低くない場合は、警告を出したいと思います。また、画像は、ステップ1と3を行うには、ブルートフォースアルゴリズムであるもの

    ためのアカウントへのノイズの少ない、非常にきれいな

ですか?私は大津を実装する方法を見つけることができましたが、ブルートフォースは数学的に私を逃げ出しています。結論としては、大津のような方法を扱うためのドキュメントが多く、単に山と谷を見つけるだけではありません。私は何かを探しているわけではありません(つまり、それは一時的な解決策です、私はそれに多くの時間を費やすことができるまで、合理的な時間枠で実装する必要があります)

私はこれをすべてC#

どの手順を実行するとよいでしょうか? ありがとうございました!

EDIT:いくつかのより多くのデータ:

最もヒストグラムは、背景を表す第1のピークと、最初のもののようである可能性が高いです。

Histogram

Histogram 2

+0

はあなたには、いくつかのサンプルデータを与えることができるしてください? – ose

+0

ピークの周りの領域が正常に分布しているように見えますか?たとえば、あなたのデータに3つの独立した正規分布を当てはめる。標準偏差を使ってカットオフ点を決め、ピークと谷を特定することができます。 – Andreas

+0

3つの異なるクラスタを得るためにk = 3のAlgorithmを使用するとどうなりますか?物事がうまくいくと、各重心はピークの1つに対応するはずです。 – Reinhard

答えて

4

peakinessテストを使用してください。これは、2つの極小値の間の可能なピークをすべて見つけ、式に基づいてピークを測定する方法です。ピーク値が閾値より高い場合、ピークが受け入れられる。

出典:UCF CV CAP5415 lecture 9 slides以下

である私のコード:

public static List<int> PeakinessTest(int[] histogram, double peakinessThres) 
{ 
    int j=0; 
    List<int> valleys = new List<int>(); 

    //The start of the valley 
    int vA = histogram[j]; 
    int P = vA; 

    //The end of the valley 
    int vB = 0; 

    //The width of the valley, default width is 1 
    int W = 1; 

    //The sum of the pixels between vA and vB 
    int N = 0; 

    //The measure of the peaks peakiness 
    double peakiness=0.0; 

    int peak=0; 
    bool l = false; 

    try 
    { 
     while (j < 254) 
     { 

      l = false; 
      vA = histogram[j]; 
      P = vA; 
      W = 1; 
      N = vA; 

      int i = j + 1; 

      //To find the peak 
      while (P < histogram[i]) 
      { 
       P = histogram[i]; 
       W++; 
       N += histogram[i]; 
       i++; 
      } 


      //To find the border of the valley other side 
      peak = i - 1; 
      vB = histogram[i]; 
      N += histogram[i]; 
      i++; 
      W++; 

      l = true; 
      while (vB >= histogram[i]) 
      { 
       vB = histogram[i]; 
       W++; 
       N += histogram[i]; 
       i++; 
      } 

       //Calculate peakiness 
      peakiness = (1 - (double)((vA + vB)/(2.0 * P))) * (1 - ((double)N/(double)(W * P))); 

      if (peakiness > peakinessThres & !valleys.Contains(j)) 
      { 
       //peaks.Add(peak);       
       valleys.Add(j); 
       valleys.Add(i - 1); 
      } 

      j = i - 1; 
     } 
    } 
    catch (Exception) 
    { 
     if (l) 
     { 
      vB = histogram[255]; 

      peakiness = (1 - (double)((vA + vB)/(2.0 * P))) * (1 - ((double)N/(double)(W * P))); 

      if (peakiness > peakinessThres) 
       valleys.Add(255); 

       //peaks.Add(255); 
      return valleys; 
     } 
    } 

     //if(!valleys.Contains(255)) 
     // valleys.Add(255); 

    return valleys; 
} 
関連する問題