加速度計データの正しいフィルターを選択する


28

私はDSPにかなり慣れていないので、Pythonで加速度計データを平滑化するためのフィルターの可能性について調査しました。発生するデータのタイプの例を次の画像に示します。

加速度計データ

基本的に、このデータを平滑化して最終的に速度と変位に変換するためのアドバイスを探しています。携帯電話の加速度計は非常にうるさいことを理解しています。

データによって生成されたノイズを参照するためにデバイスを取得できないため、現時点ではカルマンフィルターを使用できるとは思わない(デバイスを平らに配置し、それらの読み取り値からノイズの量を見つけることが不可欠であると読んだか?)

FFTは興味深い結果をもたらしました。私の試みの1つは、加速度信号をFFTし、次に低周波数をレンダリングして絶対FFT値を0にすることでした。次に、オメガ演算と逆FFTを使用して速度のプロットを得ました。結果は次のとおりです。

フィルター処理された信号

これは物事を進める良い方法ですか?信号の全体的なノイズ特性を削除しようとしていますが、約80秒などの明らかなピークを識別する必要があります。

また、元の加速度計データでローパスフィルターを使用するのも大変でした。これは、データを平滑化するのに非常に役立ちましたが、ここからどこに進むべきかわかりません。ここからどこへ行くかについてのガイダンスは本当に役立つでしょう!

編集:少しのコード:

for i in range(len(fz)): 
    testing = (abs(Sz[i]))/Nz

    if fz[i] < 0.05:
        Sz[i]=0

Velfreq = []
Velfreqa = array(Velfreq)
Velfreqa = Sz/(2*pi*fz*1j)
Veltimed = ifft(Velfreqa)
real = Veltimed.real

本質的に、iveは加速度計データに対してFFTを実行し、シンプルなブリックウォールフィルターを使用して高周波数をフィルター処理してSzを出力しました(理想的ではないことを知っています)。次に、データのFFTでオメガ演算を使用します。また、私の画像を私の投稿に追加してくれたdatageistにも感謝します:)


DSPへようこそ!2番目の写真の赤い曲線は、元の(緑の)データの「平滑化」バージョンですか?
フォノン

赤い曲線は(できれば!)fftから生成された速度曲線であり、その後にフィルタリングが続き、その後にオメガ演算(2 * pi f jで除算)、invが続きます。FFT
マイケル・M

1
おそらく、より正確な数学表現または疑似コードを含めると、やることが少し明確になります。
フォノン

いくつかの今を追加しました、コードの一般的な感触をthatsの...
マイケル・M

1
私の質問は次のとおりです。データに何を期待しますか?フィルタリング後に表示されるはずの基になる信号について何かを知っていない限り、適切なアプローチがあるかどうかはわかりません。さらに、示したコードは混乱を招きます。fz配列の初期化は表示しませんが、代わりにハイパスフィルターを適用しているようです。
ジェイソンR

回答:


13

@JohnRobertsonが指摘したように、鋭い遷移を維持しながら信号をノイズ除去するためのバッグオブトリックスでは、トータルバリアトン(TV)ノイズ除去は、信号が区分的に一定である場合のもう1つの優れた選択肢です。信号が異なるプラトー間で変化し続ける場合、これは加速度計データの場合です。

μρ

yバツμバツy2+Dバツ1D

function denoise()

f = [-1*ones(1000,1);3*ones(100,1);1*ones(500,1);-2*ones(800,1);0*ones(900,1)];
plot(f);
axis([1 length(f) -4 4]);
title('Original');
g = f + .25*randn(length(f),1);
figure;
plot(g,'r');
title('Noisy');
axis([1 length(f) -4 4]);
fc = denoisetv(g,.5);
figure;
plot(fc,'g');
title('De-noised');
axis([1 length(f) -4 4]);

function f = denoisetv(g,mu)
I = length(g);
u = zeros(I,1);
y = zeros(I,1);
rho = 10;

eigD = abs(fftn([-1;1],[I 1])).^2;
for k=1:100
    f = real(ifft(fft(mu*g+rho*Dt(u)-Dt(y))./(mu+rho*eigD)));
    v = D(f)+(1/rho)*y;
    u = max(abs(v)-1/rho,0).*sign(v);
    y = y - rho*(u-D(f));
end

function y = D(x)
y = [diff(x);x(1)-x(end)];

function y = Dt(x)
y = [x(end)-x(1);-diff(x)];

結果:

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


本当にこの答えのように、試してみてください。返信に時間がかかりすぎて申し訳ありません!
マイケルM

素晴らしい答え。詳細をありがとう。このコードのCバージョンを探しています。ここで誰もがこのmatlabコードをCに移植して共有したいですか?ありがとう。
ルネリンベルガー

区分的定数とはどういう意味ですか?
tilaprimera

6

問題は、ノイズのスペクトルが平坦であることです。ホワイトガウスノイズを仮定すると(これは良い仮定であることが判明)、そのパワースペクトル密度は一定です。大まかに言うと、ノイズにはすべての周波数が含まれていることを意味します。これが、DFTやローパスフィルターなどの周波数アプローチが適切でない理由です。ノイズはスペクトル全体にあるため、カットオフ周波数はどのくらいになりますか?

この質問に対する答えの1つはWienerフィルターです。Wienerフィルターは、ノイズと目的の信号の統計の知識を必要とします。基本的に、ノイズのある信号(信号+ノイズ)は、ノイズが信号よりも大きいと予想される周波数で減衰し、信号がノイズよりも大きいと予想される場所で増幅されます。

ただし、ウェーブレットノイズ除去など、非線形処理を使用するより現代的なアプローチをお勧めします。これらの方法は優れた結果を提供します。基本的に、ノイズの多い信号は最初にウェーブレットに分解され、次に小さな係数がゼロになります。このアプローチは、ウェーブレットの多重解像度の性質のために機能します(DFTは機能しません)。つまり、信号は、ウェーブレット変換によって定義された周波数帯域で個別に処理されます。

MATLABで、「wavemenu」と入力し、次に「SWT denoising 1-D」と入力します。次に、「ファイル」、「サンプル分析」、「ノイズの多い信号」、「レベル5のHaarでノイズの多いブロック」。この例では、Haarウェーブレットを使用しますが、これは問題に対してうまく機能するはずです。

私はPythonが苦手ですが、Haarウェーブレットノイズ除去を実行するNumPyパッケージを見つけることができると思います。


1
私はあなたの最初の声明に同意しません。興味のある信号が入力シーケンスの全帯域幅をカバーしていると仮定しますが、これはほとんどありません。この場合、線形フィルタリングを使用して改善されたS / N比を取得し、帯域外ノイズを除去することも可能です。信号が非常にオーバーサンプリングされている場合、このような単純なアプローチで大幅な改善を得ることができます。
ジェイソンR

それは事実であり、これは、信号とノイズの統計がわかっているときにWienerフィルターによって実現されます。
ダニエルR.ピパ

ウェーブレットノイズ除去の背後にある理論は複雑ですが、実装はあなたが説明したアプローチと同じくらい簡単です。これには、フィルターバンクとしきい値設定のみが含まれます。
ダニエルR.ピパ

1
私は今これを研究しています、これまでの私のすべての助けにあなたとフォノンの両方のおかげで、上記の私の進歩を投稿します!
マイケルM

@DanielPipa問題のmatlabパッケージにアクセスできません。matlabコードに対応する方法を説明する論文またはその他の参考資料を提供できますか。
ジョンロバートソン

0

ダニエルピパの提案に従って、ウェーブレットノイズ除去を見、フランシスコブランコシルバによるこの素晴らしい記事を見つけました。

ここでは、3D(画像)データではなく2D(加速度計)で動作するように画像処理用のPythonコードを変更しました。

注:フランシスコの例では、ソフトしきい値のしきい値は「構成」されています。これを考慮して、アプリケーションに合わせて変更してください。

def wavelet_denoise(data, wavelet, noise_sigma):
    '''Filter accelerometer data using wavelet denoising

    Modification of F. Blanco-Silva's code at: https://goo.gl/gOQwy5
    '''
    import numpy
    import scipy
    import pywt

    wavelet = pywt.Wavelet(wavelet)
    levels  = min(15, (numpy.floor(numpy.log2(data.shape[0]))).astype(int))

    # Francisco's code used wavedec2 for image data
    wavelet_coeffs = pywt.wavedec(data, wavelet, level=levels)
    threshold = noise_sigma*numpy.sqrt(2*numpy.log2(data.size))

    new_wavelet_coeffs = map(lambda x: pywt.threshold(x, threshold, mode='soft'),
                             wavelet_coeffs)

    return pywt.waverec(list(new_wavelet_coeffs), wavelet)

どこで:

  • wavelet-使用されるウェーブレット形式の文字列名(pywt.wavelist()例えばを参照'haar'
  • noise_sigma -データからのノイズの標準偏差
  • data -フィルタリングする値の配列(x、y、またはz軸データなど)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.