質問
データ収集カードを使用して、信号がピークまで増加し、その後元の値近くまで低下するデバイスから読み取り値を取得します。ピーク値を見つけるために、現在、配列内で最高の読み取り値を検索し、インデックスを使用して計算に使用されるピーク値のタイミングを決定します。
最高値が探しているピークである場合、これはうまく機能しますが、デバイスが正しく動作していない場合は、最初のピークよりも高い 2 番目のピークが表示される可能性があります。90 秒間にわたって 16 台のデバイスから 1 秒あたり 10 回の読み取り値を取得します。
私の最初の考えは、読み取り値のチェックを繰り返して、前のポイントと次のポイントが現在よりも小さいかどうかを確認して、ピークを見つけてピークの配列を構築することです。システム内のノイズを考慮して、現在位置の両側のポイント数の平均を調べる必要があるかもしれません。これが最善の方法でしょうか、それとももっと良いテクニックはありますか?
私たちは LabVIEW を使用しており、次のことを確認しました。 LAVA フォーラム そして興味深い例がたくさんあります。これはテスト ソフトウェアの一部であり、非標準 VI ライブラリの使用を避けようとしているため、特定のコードではなく、関連するプロセス/アルゴリズムに関するフィードバックを期待していました。
解決
信号の平均化を試すことができます。各点について、周囲の 3 つ以上の点との値を平均します。ノイズ ブリップが大きい場合は、これでも役に立たない可能性があります。
これが言語に依存しないことは理解していますが、LabView を使用していると推測すると、LabView には、スムージングやノイズ リダクションに使用できる、あらかじめパッケージ化された信号処理 VI が多数用意されています。の NI フォーラム この種のことについてより専門的なサポートを受けるには最適な場所です。
他のヒント
従来のピーク検出方法は数多くあり、どれも機能する可能性があります。特に、何がデータの品質を制限しているのかを確認する必要があります。基本的な説明は次のとおりです。
データ内の任意の 2 点の間で、
(x(0), y(0))
そして(x(n), y(n))
, 、合計しますy(i + 1) - y(i)
のために0 <= i < n
そしてこれを呼び出しますT
(「旅行」) と設定R
(「上昇」)y(n) - y(0) + k
適度に小さいk
.T/R > 1
ピークを示します。これは、ノイズによる大きな移動が起こりそうにない場合、またはノイズがベース カーブ形状の周囲に対称的に分布している場合には問題なく機能します。アプリケーションでは、特定のしきい値を超えるスコアを持つ最も早いピークを受け入れるか、上昇値ごとの移動量の曲線を分析して、より興味深い特性を求めます。マッチドフィルターを使用して、標準ピーク形状との類似性をスコアリングします (基本的に、何らかの形状に対して正規化されたドット積を使用して、類似性のコサインメトリクスを取得します)。
標準のピーク形状に対してデコンボリューションし、高い値をチェックします (ただし、単純な計測出力では 2 の方がノイズの影響を受けにくいことがよくあります)。
データを平滑化し、等間隔の点のトリプレットをチェックします。
x0 < x1 < x2, y1 > 0.5 * (y0 + y2)
, 、または次のようにユークリッド距離を確認します。D((x0, y0), (x1, y1)) + D((x1, y1), (x2, y2)) > D((x0, y0),(x2, y2))
, 、これは三角不等式に依存します。単純な比率を使用すると、再びスコアリング メカニズムが提供されます。非常に単純な 2 ガウス混合モデルをデータに適合させます (たとえば、Numerical Recipes には既成の優れたコードの塊があります)。先ほどのピークを撮ります。これにより、重複するピークが正しく処理されます。
データ内で単純なガウス曲線、コーシー曲線、ポアソン曲線、または手持ちの曲線に最もよく一致するものを見つけます。この曲線を広い範囲で評価し、ピークの位置を記録した後、データのコピーからそれを差し引きます。繰り返す。モデル パラメーター (おそらく標準偏差ですが、一部のアプリケーションでは尖度やその他の特徴を考慮する可能性があります) が何らかの基準を満たす最も早いピークを取得します。データからピークを差し引くときに残されるアーティファクトに注意してください。最良の一致は、上記の #2 で提案された一致スコアの種類によって決定される可能性があります。
あなたがやっていることは私も以前にやったことがあります:DNA 配列データでのピークの検出、測定された曲線から推定された導関数でのピークの検出、およびヒストグラムでのピークの検出。
適切なベースライン設定を注意深く行うことをお勧めします。ウィーナー フィルタリングやその他のフィルタリング、あるいは単純なヒストグラム分析は、多くの場合、ノイズが存在する場合のベースラインを設定する簡単な方法です。
最後に、一般にデータにノイズが多く、参照されていないシングルエンド出力 (または参照されていても差動ではない) としてカードからデータを取得している場合、および各データ ポイントに多数の観測値を平均している場合は、それらを並べ替えてみてください。観察し、最初と最後の四分位を破棄し、残ったものを平均します。このような、非常に役立つ外れ値除去戦術が多数あります。
この問題はある程度詳細に研究されています。
には非常に最新の実装のセットがあります。 TSpectrum*
のクラス 根 (核/素粒子物理解析ツール)。コードは 1 次元から 3 次元のデータで機能します。
ROOT ソース コードが利用可能なので、必要に応じてこの実装を取得できます。
から Tスペクトル クラスのドキュメント:
このクラスで使用されるアルゴリズムは、次の参考文献で公開されています。
[1] M.Morhac ら:多次元偶然のガンマ線スペクトルの背景除去方法。物理学研究の核楽器と方法A 401(1997)113- 132。
[2] M.Morhac ら:効率的な1次元および2次元の金のデコンボリューションと、ガンマ線スペクトル分解への適用。物理学研究の核機器と方法A 401(1997)385-408。
[3] M.Morhac ら:多次元偶然のガンマ線スペクトルにおけるピークの識別。研究物理学における核機器と方法A 443(2000)、108-125。
NIM オンライン サブスクリプションをお持ちでない方のために、論文はクラスのドキュメントからリンクされています。
行われる処理を簡単に説明すると、ノイズを除去するためにヒストグラムが平坦化され、平坦化されたヒストグラム内で力ずくで極大値が検出されます。
このスレッドに次のようなアルゴリズムを提供したいと考えています。 私自身も成長してきました:
それは次の原則に基づいています。 分散:新しいデータポイントが移動平均から所定の x 個の標準偏差だけ離れている場合、アルゴリズムはシグナル (または Zスコア)。このアルゴリズムは非常に堅牢です。 別 信号がしきい値を破損しないように、移動平均と偏差を調整します。したがって、以前の信号の量に関係なく、将来の信号はほぼ同じ精度で識別されます。このアルゴリズムは 3 つの入力を受け取ります。 lag = the lag of the moving window
, threshold = the z-score at which the algorithm signals
そして influence = the influence (between 0 and 1) of new signals on the mean and standard deviation
. 。たとえば、 lag
of 5 は、最後の 5 つの観測値を使用してデータを平滑化します。あ threshold
of 3.5 は、データポイントが移動平均から 3.5 標準偏差離れているかどうかを示します。と influence
0.5 の場合はシグナルが発生します 半分 通常のデータポイントが持つ影響力。同様に、 influence
0 の場合、新しいしきい値を再計算するために信号を完全に無視します。したがって、影響力 0 が最も堅牢なオプションとなります。
次のように動作します。
擬似コード
# Let y be a vector of timeseries data of at least length lag+2
# Let mean() be a function that calculates the mean
# Let std() be a function that calculates the standard deviaton
# Let absolute() be the absolute value function
# Settings (the ones below are examples: choose what is best for your data)
set lag to 5; # lag 5 for the smoothing functions
set threshold to 3.5; # 3.5 standard deviations for signal
set influence to 0.5; # between 0 and 1, where 1 is normal influence, 0.5 is half
# Initialise variables
set signals to vector 0,...,0 of length of y; # Initialise signal results
set filteredY to y(1,...,lag) # Initialise filtered series
set avgFilter to null; # Initialise average filter
set stdFilter to null; # Initialise std. filter
set avgFilter(lag) to mean(y(1,...,lag)); # Initialise first value
set stdFilter(lag) to std(y(1,...,lag)); # Initialise first value
for i=lag+1,...,t do
if absolute(y(i) - avgFilter(i-1)) > threshold*stdFilter(i-1) then
if y(i) > avgFilter(i-1)
set signals(i) to +1; # Positive signal
else
set signals(i) to -1; # Negative signal
end
# Adjust the filters
set filteredY(i) to influence*y(i) + (1-influence)*filteredY(i-1);
set avgFilter(i) to mean(filteredY(i-lag,i),lag);
set stdFilter(i) to std(filteredY(i-lag,i),lag);
else
set signals(i) to 0; # No signal
# Adjust the filters
set filteredY(i) to y(i);
set avgFilter(i) to mean(filteredY(i-lag,i),lag);
set stdFilter(i) to std(filteredY(i-lag,i),lag);
end
end
デモ
>元の回答
このメソッドは基本的に David Marr の著書「Vision」に基づいています。
ガウスぼかしは、予想されるピークの幅で信号をぼかします。これによりノイズスパイクが除去され、位相データは損傷されません。
次にエッジ検出 (LOG で十分です)
その場合、エッジはフィーチャのエッジ (ピークなど) でした。エッジの間でピークを探し、サイズごとにピークを並べ替えれば完了です。
私はこれのバリエーションを使用しましたが、非常にうまく機能します。
したいと思います 相互相関する あなたの信号と予想される模範的な信号。しかし、信号処理を勉強するのは久しぶりで、当時もあまり注目していませんでした。
私は計測についてはあまり詳しくないので、これはまったく実用的ではないかもしれませんが、別の方向で役立つかもしれません。測定値がどのように失敗する可能性があるかを知っており、そのような失敗が発生した場合にピーク間に一定の間隔がある場合は、各間隔で勾配降下を実行してみてはいかがでしょうか。降下によって以前に探索したエリアに戻ってきた場合は、そのエリアを放棄しても構いません。サンプリングされたサーフェスの形状によっては、これは検索よりも早くピークを見つけるのに役立つ場合もあります。
望ましいピークと望ましくない 2 番目のピークの間に定性的な違いはありますか?両方のピークが「鋭い」場合、つまり継続時間が短い -- (FFT を実行することにより) 周波数領域で信号を見ると、ほとんどの帯域でエネルギーが得られます。しかし、「良い」ピークに「悪い」ピークには存在しない周波数にエネルギーが確実に存在する場合、またはその逆の場合は、そのように自動的に区別できる可能性があります。
いくつか適用することもできます 標準偏差 あなたのロジックに従って、x% を超えるピークに注目してください。