web-dev-qa-db-ja.com

ノイズの多い正弦波時系列でのリアルタイムのピーク検出

私は正弦波時系列データのピークを検出しようと試みてきましたリアルタイムが、これまでのところ成功していません。正弦波信号のピークを妥当なレベルの精度で検出するように機能するリアルタイムアルゴリズムを見つけることができないようです。ピークが検出されないか、正弦波に沿ってピークとして検出されているジリオンポイントが発生します。

正弦波に似ていて、ランダムノイズが含まれている可能性のある入力信号に適したリアルタイムアルゴリズムは何ですか?


簡単なテストケースとして、常に同じ周波数と振幅の定常正弦波を考えます。 (正確な周波数と振幅は重要ではありません。サンプリングレート8 KS/sで、周波数60 Hz、振幅+/- 1単位を任意に選択しました。)次のMATLABコードは、このような正弦波を生成します。信号:

dt = 1/8000;
t  = (0:dt:(1-dt)/4)';
x  = sin(2*pi*60*t);

Jean-Paulによって開発および公開されたアルゴリズム を使用すると、ピークが検出されない(左)か、無数の「ピーク」が検出される(右)かのいずれかです。

私は考えられるこれら3つのパラメーターの値のほぼすべての組み合わせを試してみました Jean-Paulが与える「経験則」 ですが、これまでのところ、期待される結果。


私は代替アルゴリズムを見つけました Eli Billauerによって開発および公開されました 、それはdoes希望する結果を提供します-

Eli Billauerのアルゴリズムははるかに単純であり、希望する結果を確実に生成する傾向がありますが、リアルタイムアプリケーションには適していません。


そのようなアルゴリズムを適用したい信号の別の例として、Eli Billauerが彼自身のアルゴリズムについて示したテストケースを考えてみましょう。

t = 0:0.001:10;
x = 0.3*sin(t) + sin(1.3*t) + 0.9*sin(4.2*t) + 0.02*randn(1, 10001);

これは、周波数と振幅が変化する、より珍しい(均一性が低い/規則的でない)信号ですが、それでも一般に正弦波です。プロットすると、ピークは目にはっきりとわかりますが、アルゴリズムで識別するのは困難です。


正弦波入力信号のピークを正しく識別するための優れたリアルタイムアルゴリズムとは何ですか?信号処理に関しては、私はあまり専門家ではないので、経験則を理解しておくと役立ちます正弦波入力を考慮します。または、おそらく変更する必要があります。正弦波信号を適切に処理するためのJean-Paulのアルゴリズム自体。その場合、どのような変更が必要になりますか?また、どのように変更するのですか?

6
Cody Gray

Findpeaksの使用を検討してください。それは高速であり、リアルタイムにとって重要な場合があります。精度を向上させるには、高周波ノイズをフィルタリングする必要があります。ここで、ウィンドウを移動してデータを平滑化します。

t = 0:0.001:10;
x = 0.3*sin(t) + sin(1.3*t) + 0.9*sin(4.2*t) + 0.02*randn(1, 10001);
[~,iPeak0] = findpeaks(movmean(x,100),'MinPeakProminence',0.5);

プロセスの時間を計ることができます(0.0015秒)

f0 = @() findpeaks(movmean(x,100),'MinPeakProminence',0.5)
disp(timeit(f0,2))

比較すると、勾配の処理は少し高速(0.00013秒)ですが、findpeaksには、ピーク間の最小間隔など、多くの便利なオプションがあります。

iPeaks1 = derivePeaks(x);
f1 = @() derivePeaks(x)
disp(timeit(f1,1))

DerivePeaksは次のとおりです。

function iPeak1 = derivePeaks(x)
xSmooth = movmean(x,100);
goingUp = find(diff(movmean(xSmooth,100)) > 0);
iPeak1 = unique(goingUp([1,find(diff(goingUp) > 100),end]));
iPeak1(iPeak1 == 1 | iPeak1 == length(iPeak1)) = [];
end
0
Yuval Harpaz