相互相関を使用したオシロスコープ信号の時間遅延推定


12

スコープから2つの信号を記録しました。次のようになります。 ここに画像の説明を入力してください

Matlabでそれらの間の時間遅延を測定したい。各信号には、サンプリング周波数が2001000.5の2000個のサンプルがあります。

データはcsvファイルにあります。これは私がこれまで持っているものです。
電圧レベルのみがcsvファイルに含まれるように、csvファイルから時間データを消去しました。

x1 = csvread('C://scope1.csv');
x2 = csvread('C://scope2.csv');  
cc = xcorr(x1,x2);
plot(cc);  

これにより、次の結果が得られます。 ここに画像の説明を入力してください

私が読んだことから、これらの信号の相互相関を取る必要があり、これは時間遅延に関連するピークを与えるはずです。しかし、これらの信号の相互相関を取ると、2000年にピークが得られますが、これは正しくないことがわかります。これらの信号を相互相関させる前に、これらの信号に対して何をすべきですか?ある方向を探しています。

編集:DCオフセットを削除した後、これは私が今得ている結果です:
ここに画像の説明を入力してください

より明確な時間遅延を得るためにこれをクリーンアップする方法はありますか?

編集2:ファイルは次のとおりです
。http//dl.dropbox.com/u/10147354/scope1col.csv
http://dl.dropbox.com/u/10147354/scope2col.csv


正確に、相互相関をどのように行っていますか?直接的な質問への回答では、相互相関の前に信号に何もする必要はありませんが、最初のフィルタリングは結果を歪める可能性のあるノイズを取り除くのに役立つ場合があります。
ジム・クレイ

1
使用したコードと、さらに重要な相互相関信号のプロットを投稿してください。一部のツール/ライブラリは、グラフの中央に(ラグ= 0)スコアを入れます。Matlabがそれを行うかどうかは覚えていません。
-pichenettes

@pichenettes:更新された投稿
Nick

@JimClay:更新された投稿
Nick

@NickS。信号が完全に揃っている場合、ccプロ​​ットの中央にピークがあります。したがって、2000のピークは遅延がないことを意味します。ここで、10サンプルの遅延があるとします。つまり、signal2はsignal1から10サンプル離れています。これにより、ccのピークが2000年から2010年(または1990年)に移動します。したがって、遅延時間は実際のピーク位置であるマイナス2000に対応します。–
スペイシー

回答:


11

@NickS

プロットの2番目の信号が実際には1番目の信号の遅延バージョンにすぎないことは確かではないため、古典的な相互相関以外の他の方法を試行する必要があります。これは、信号が互いに遅延バージョンである場合、相互相関(CC)は最尤推定量にすぎないためです。この場合、それらの非定常性についても言うまでもないことは明らかです。

この場合、うまくいくのは、信号の重要なエネルギーの時間推定だと思います。確かに、「有意」は多少主観的かもしれませんが、統計的観点からあなたの信号を見ることで、「有意」を定量化してそこから進むことができると信じています。

このために、次のことを行いました。

ステップ1:信号エンベロープを計算します。

各ステップのヒルベルト変換の出力の絶対値が計算されるため、このステップは簡単です。エンベロープを計算する方法は他にもありますが、これは非常に簡単です。この方法は、基本的に信号の分析形式、つまりフェーザー表現を計算します。絶対値をとると、エネルギーを失った段階で破壊段階になります。

さらに、信号のエネルギーの時間遅延推定を追求しているため、このアプローチが必要です。

ここに画像の説明を入力してください

ステップ2:エッジ保存型非線形メディアフィルターによるノイズ除去:

これは重要なステップです。ここでの目的は、しかし、あなたのエネルギーの封筒を滑らかにあるなしに破壊したり、エッジや高速の立ち上がり時間を滑らか。実際にはこれに専念するフィールド全体がありますが、ここでの目的のために、簡単に実装できる非線形Medialフィルターを使用できます。(中央値フィルタリング)。これは強力な手法です。平均フィルタリングとは異なり、中間フィルタリングはエッジを無効にしませんが、同時に重要なエッジを大幅に劣化させることなく信号を「スムーズ」にします。 (ウィンドウの長さが奇数の場合)。ここでのケースでは、ウィンドウサイズ25サンプルの中間フィルターを選択しました。

ここに画像の説明を入力してください

ステップ3:時間の削除:ガウスカーネル密度推定関数の作成:

上記のプロットを通常の方法ではなく横から見た場合はどうなりますか?数学的に言えば、ノイズ除去された信号のすべてのサンプルをy振幅軸に投影した場合、何が得られるでしょうか?これを行うことで、いわば時間を削除し、信号統計のみを調べることができます。

直感的に何が上の図から浮かび上がりますか?ノイズエネルギーは低いですが、より「人気がある」という利点があります。対照的に、エネルギーを持つ信号エンベロープはノイズよりもエネルギッシュですが、しきい値を超えて断片化されます。「人気」をエネルギーの尺度として考えたらどうでしょうか?これは、ガウスカーネルを使用したカーネル密度関数(KDE)の(粗雑な)実装で行います。

これを行うには、すべてのサンプルを取得し、その値を平均として使用してガウス関数を作成し、事前に選択された事前設定の帯域幅(分散)を使用します。ガウス分布の分散を設定することは重要なパラメーターですが、アプリケーションと一般的な信号に基づいたノイズ統計に基づいて設定できます。(2つのファイルのみを使用できます)。その後、KDE推定を作成すると、次のプロットが得られます。

ここに画像の説明を入力してください

KDEは、いわばヒストグラムの連続した形であり、分散はビン幅と考えることができます。ただし、滑らかなPDFを保証するという利点があり、1回目と2回目の微分計算を実行できます。ガウスKDEが得られたので、ノイズサンプルの人気のピーク位置を確認できます。ここで、x軸は振幅空間へのデータの投影を表していることに注意してください。したがって、ノイズが最も「エネルギッシュな」しきい値を確認でき、どのしきい値を回避すべきかがわかります。

2番目のプロットでは、ガウス KDEの1次導関数を取得し、ガウス混合のピークの後の1次導関数の後の最初のサンプルの横座標を選択して、ゼロに近い特定の値を取得します。(または最初のゼロ交差)。KDEは適切な帯域幅の滑らかなガウス分布で構成されており、この滑らかでノイズのない関数の一次導関数が採用されているため、この方法を使用して「安全」にできます。(通常、一次微分はノイズを拡大するため、高SNR信号以外では問題となります)。

黒い線は、ノイズフロア全体を回避するために、画像を「セグメント化」するのに賢明なしきい値を示しています。元の信号に適用すると、次のプロットが得られます。黒い線は信号のエネルギーの開始を示しています。

ここに画像の説明を入力してください

δt=241

これがお役に立てば幸いです。


ワオ。どうもありがとうございます。これらはすべて、私が研究を開始する新しいテクニックです。あなたが使用したMATLABコードを見ることができる方法はありますか?
ニックシナス

したがって、Matlabでステップ#1と#2を完了し、私の結果はあなたのものと一致していますが、ステップ#3で問題が発生しています。どの機能を使用しましたか?
ニックシナス

@NickS。お願いします。あなたは私にメールを受け取り、私に使ったコードを送れます
スペイシー

@Mohammedあなたのコードを投稿して、遅延時間を推定してください。この件に関してメールをお送りしましたので、助けてください

6

自己相関でこれを行うにはいくつかの問題があります

  1. 巨大なDCオフセット(既に修正済み)
  2. タイムウィンドウ:Matlabのxcorr()には、タイムラグをスライドさせるときに両端で信号を本質的に「ゼロパッド」するという厄介な慣習があります。つまり、データウィンドウはタイムラグの関数です。これにより、定常信号(正弦波を含む)の三角形が作成されます。より良い選択は、ウィンドウサイズと最大タイムラグが合計データウィンドウに収まるように相関ウィンドウを選択するか、パディングされていないサンプルの数で相互相関を正規化することです。
  3. 2つの信号は、特に私には相関していません。形状はやや似ていますが、ピークとディップの特定の間隔はまったく異なるため、適切な自己相関でさえ多くの洞察を得られるとは思いません。

もっと簡単なアプローチは、しきい値検出器を使用して開始点を見つけ、単純にこれらの点の差を遅延として使用することです。


4

ピケネットが示すように、この場合、出力の中央のピークは0ラグを示します。中間点からのピークのオフセットは、タイムラグです。

編集:それは、相関関係がほぼ完全な三角形であるということです。これは、相互相関が電力の正規化を行っていないことを示しています。これにより、大きなラグよりも小さなラグに不公平なバイアスがかかります。xcorr呼び出しを「cc = xcorr(x1、x2、 'unbiased');」に変更します。

大きなラグの結果は、少ないデータに基づいているため、低ラグの結果よりも不安定になるため、これは完璧なソリューションではありません。わずかなコイントスで100%の頭と尻尾を得ることができるのと同じ理由で、四肢の大きなピークは偽物である可能性がありますが、多くのトスでは起こりそうにありません。


信号が遅延しないという意味ですか?
ニックsiNAは

わからない-ピークはどこですか?中央付近にあることがわかりますが、実際に中央にあるかどうかは明らかではありません。また、電力の正規化の問題があり、これを回答の編集で対処します。
ジム・クレイ

'unbiased'パラメータは間違いなく見栄えを良くします。私が期待するものの多く。私はこれを調べ続けます。ありがとう。
ニックシナス

@JimClayおそらくNick Sは、実際の信号ではなく、彼の信号のエンベロープを相関させています(これは本当ですか?)。これにより、(おおよそ)この三角形の形が得られます。
スペイシー

2
@NickS。Mohammadのコメントは、結果を台無しにしている巨大なDCオフセットを持っていることを私に見せてくれました。両方の信号から平均値を引き、それらに対してxcorrを実行します。最初に「偏りのない」オプションなしで試します。
ジム・クレイ

4

他の人が指摘したように、質問に対する最後の編集に基づいて気付いたようですが、示されているデータセットの相互遅延が時間遅延の適切な推定値を与えるとは思われません。相関は、2つの時系列間の形状の類似性を測定します。これは、あるタイムラグの範囲で1つをスライドさせ、各ラグで2つのシリーズ間の内積を計算します。2つのシリーズが定性的に類似している場合、または2つのシリーズが互いに「相関」している場合、結果は大きくなります。これは、2つのベクトルが同じ方向を向いているときに2つのベクトルの内積が最大になる方法に似ています。

あなたが示したデータの問題は、(少なくとも私たちが見ることができるスニペットに関しては)形状にあまり類似性がないように見えることです。信号の1つに適用して他の信号のように見せることができる遅延はありません。これは、相互相関を計算することにより、まさにこれを行っています。

ただし、相互相関が役立つ場合があります。2番目の信号は、ノイズが追加されている場合でも、実際にはオリジナルのタイムシフトバージョンであるとします。

a = csvread('scope1col.csv');
a = a - mean(a);               % to remove DC offset
b = a(200:end) + sqrt(0.05)*randn(1801,1);
figure; subplot(211); plot(a); subplot(212); plot(b)

ここに画像の説明を入力してください

2つの信号が時間遅延によって関連していることはすぐにはわかりません。ただし、相互相関を取ると、次のようになります。

[c,lags] = xcorr(a,b);
igure; plot(lags,c); grid on; xlabel('Lag'); ylabel('Cross-correlation');

ここに画像の説明を入力してください

これは、200サンプルの正しいラグでピークを示しています。相関は、適切なタイプの類似性を含むデータセットに適用すると、時間遅延を決定するための便利なツールになります。


他に何ができるかについてのアイデアはありますか?たぶん、相互相関または別のタイプのフィルター以外の別のテクニックですか?ありがとう。
ニックシナス

@NickS。私もそれを見ましたが、それらはお互いの遅延コピーではありません。そうは言っても、エネルギーの遅延を推定したいですか?この場合、VS 信号の遅延のほうが理にかなっていると思います。実行中の基礎となるチャネル/実験について詳しくお聞かせください
スペイシー

@Mohammadありがとう。基礎となるチャネルはスチールです。エネルギーの遅延を推定する方法についてのアイデアはありますか?
ニックシナス

@Mohammad信号の歪みは、フィルタリングでクリーンアップできる残響の一種であると思いますか?
ニックシナス

@NickS。そこにはリバーブクリーニングのトリックがいくつかあるかもしれませんが(それらがどのように達成されるかはわかりません)、私はあなたが見てみたいと思うなら、エネルギー推定器となる簡単なものをまとめました。
スペイシー

0

Muhammadの提案に基づいて、Matlabスクリプトを作成しようとしました。ただし、分散に基づいてガウス分布を作成してからKDE推定を行うか、ガウス推定を使用してKDE推定を実行するかを推測することはできません。

また、KDEオフセット時間を時間領域に変換する方法を推測することは困難です。これが私の試みです。スクリプトの使用に興味があるユーザーは、可能であれば改善されたバージョンを自由に更新できます。

%% Initialising data

Ws1 = data1;
Ws2 = data2;
mWs1 = nanmean(Ws1);
mWs2 = nanmean(Ws2);
sdWs1 = nanstd(Ws1);
sdWs2 = nanstd(Ws2);

%% Computing the signal envelopes
Ws1d = Ws1 - mWs1;
Ws2d = Ws2 - mWs2;
h1 = abs(hilbert(Ws1d));
h2 = abs(hilbert(Ws2d));
figure();
subplot(211)
plot([Ws1d, h1])
subplot(212)
plot([Ws2d, h2])

%% Denoise the signal with edge preserving nonlinear medial filtering
w = 25;
mf1 = medfilt1(h1, w);
mf2 = medfilt1(h2, w);
figure();
subplot(211)
plot(mf1)
subplot(212)
plot(mf2)

<%% Remove time: construct the gaussian kernel density estimation functions>
% Using the kde from Matlab central directly on the filtered data
data1 = mf1;
[bw1, den1, xmesh1, cdf1] = kde(data1, 2^14);
der1 = diff(den1);
data2 = mf2;
[bw2, den2, xmesh2, cdf2] = kde(data2, 2^14);
der2 = diff(den2);
figure();
plot([der1, der2]);
legend('Sig1', 'Sig2')

% the other method as explained in Muhammad's post
for i = 1:length(mf1)
gf1(:,i) = mf1(i) + sdWs1*randn(1000,1);
gf2(:,i) = mf2(i) + sdWs2*randn(1000,1);
end
[bwM1, denM1, xmeshM1, cdfM1] = kde(gf1(:,1), 2.^11);
dd1 = diff(denM1);
[bwM2, denM2, xmeshM2, cdfM2] = kde(gf2(:,1), 2.^11);
dd2 = diff(denM2);
figure();
plot([dd1, dd2]);
legend('Sig1', 'Sig2')
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.