2012-02-07 11 views
0

私は本質的に、タイムスタンプをミリ秒単位で浮動小数点数にマッピングするデータオブジェクトをたくさん持っています。私は本質的に特定の範囲内のデータのピーク/最大値を見つけることを検討しています。アルゴリズムのノイズを取り除く

float previousValue = 0; 
for (int i = 0; i < data.size(); i++) { 
    MyData value = data.get(i); 
    if (value.getData() < previousValue) { 
     // found the peak! 
     break; 
    } else { 
     previousValue = value.getData(); 
    } 
} 

このアルゴリズムの唯一の問題は、それがノイズを考慮していないということです:私は基本的にこのようなものを使用してきました。基本的に、私はこのような値を持つことができます:

[0.1025, 0.3000, 0.3025, 0.3500, 0.3475, 0.3525, 0.1025] 

実際のピークは0.3525であるが、それが最初に来るよう上記の私のアルゴリズムは、0.3500としてそれを見るでしょう。私の計算の性質上、私は配列上でmax()を実行して最大の値を見つけ出すことはできません。その値が下がる前に最初に来る最大の値を見つける必要があります。

ノイズの変動を考慮しながら、ピークのトップを見つけるにはどうすればよいですか?

+0

どのようにピークを定義しますか? .3500の後の値と.3525の後の値が下がります。違いは何ですか? –

+0

懸念事項を分ける:まず、スライディングウィンドウを使用してデータを平均化する。これによりノイズが除去される。その後、自分の方法や他の方法で簡単にピークを見つけることができます。 – alf

答えて

1

は二つの問題があります。ノイズをフィルタリング

  1. ピークを見出した。

あなたがすでに2のためのソリューションを持っており、ノイズを除去するには1.

を解決する必要があるように、あなたがlow-pass filterのいくつかの種類を必要とするようです。 A moving averageはそのようなフィルタの1つです。たとえば、exponential moving averageは実装が非常に簡単で、うまく動作するはずです。

要約:フィルタを使用してシリーズを配置し、ピーク検出アルゴリズムを適用します。

+0

ローパスフィルタは不安定な値を取り除き、より線形な結果を返します。どうすればそのフィルタを書くことができますか?私はそれが数学になるとかなり無知です。 –

0

配列内の単一のピーク(または最大値)を見つけるために簡単にする方法(任意の数値配列:int型、ダブル)配列をループしているし、最高値に変数を設定し...

例:

boolean[] isPeak = new boolean[20]; // I am looking for 20 highest peaks 
float[] filter = new float[9]; // the range to which I want to define a peak is 9 
float[] peaks = new float[20]; // again the 20 peaks I want to find 
float lowpeak = 100; // use a value higher than the highest possible value 
// first we start the filter cycling through the data 
for (int i = 0; i < data.length; i++){ 
    for (int a = filter.length-1; a > 0; a--){ 
     filter[a] = filter[a-1]; 
    } 
    filter[0] = data[1] 
    // now we check to see if the filter detects a peak 
    if (filter[4]>filter[0] && filter[4]>filter[1] && filter[4]>filter[2] && 
      filter[4]>filter[3] && filter[4]>filter[5] && filter[4]>filter[6] && 
      filter[4]>filter[7] && filter[4]>filter[8]){ 
     // now we find the lowest peak 
     for (int x = 0; x < peaks.lengt-1; x++){ 
      if (peaks[x] < lowpeak){ 
       lowpeak = peaks[x]; 
      } 
     } 
     // now we check to see if the peak is above the lowest peak 
     for (int x = 0; x < peaks.length; x++){ 
      if (peaks[x] > lowpeak && peaks[x] != peaks[x+1]){ 
       for (int y = peaks.length-1; y > 0 && !isPeak[y]; y--){ 
       peaks[y] = peaks[y-1]; 
       } 
       peaks[0] = filter[4]; 
      } 
     } 
    } 
} 

番目:

float highest = 0; //use a number equal to or below the lowest possible value 
for (int i = 0; i < data.length; i++){ 
    if (data[i] > highest){ 
     highest = data[i]; 
    } 
} 

私はこの方法を用いてノイズの一部をフィルタリングするノイズの多いデータに複数のピークを見つけるために、(すべての例は、「データ」と呼ばれるfloat配列を使用します)これを行う最も効率的な方法ではないかもしれませんが、それは仕事を完了します!

関連する問題