Akselerometre verileri için doğru filtreyi seçme


28

DSP için oldukça yeniyim ve pythondaki ivmeölçer verilerini düzeltmek için olası filtreler üzerine bazı araştırmalar yaptım. Aşağıdaki resimde, yaşanmakta olduğu veri türünün bir örneği görülebilir:

İvmeölçer verileri

Temel olarak, sonunda verileri hıza ve yer değiştirmeye dönüştürmek için bu verileri pürüzsüz hale getirme konusunda tavsiye arıyorum. Cep telefonlarından ivmeölçer son derece gürültülü olduğunu biliyorum.

Şu anda bir Kalman filtresi kullanabileceğimi sanmıyorum, çünkü verilerin ürettiği gürültüyü referans almak için cihazı tutamıyorum (cihazı düz yerleştirmek ve bu değerlerden gelen ses miktarını bulmak için gerekli olduğunu okudum mu?)

FFT bazı ilginç sonuçlar verdi. Denemelerimden biri hızlanma sinyalini FFT yapmak, sonra da mutlak FFT değerine sahip olmak için düşük frekansları sağlamaktı. Sonra hız için bir arsa elde etmek için omega aritmetik ve ters FFT kullandım. Sonuçlar aşağıdaki gibidir:

Filtrelenmiş sinyal

Bu işlerle uğraşmak için iyi bir yol mu? Sinyalin genel gürültülü yapısını kaldırmaya çalışıyorum, ancak yaklaşık 80 saniye gibi belirgin tepe noktalarının tanımlanması gerekiyor.

Ayrıca orijinal ivmeölçer verilerinde düşük geçişli bir filtre kullanmaktan yoruldum. Buradan nereye gideceğinize dair herhangi bir rehberlik gerçekten yararlı olacaktır!

EDIT: Biraz kod:

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

Bu yüzden, temelde, ivme verilerim üzerinde bir FFT yaptım, basit bir tuğla duvar filtresi kullanarak Sz'ye yüksek frekansları filtrelemeyi sağladı (ideal olmadığını biliyorum). Sonra verinin FFT'sinde omega aritmetiği kullanıyorum. Ayrıca görüntüleri yazıma eklediği için datageist'e çok teşekkür ederim :)


DSP'ye Hoşgeldiniz! İkinci resminizdeki kırmızı eğri, orijinal (yeşil) verinin "düzeltilmiş" bir versiyonu mu?
Phonon

Kırmızı eğri (umutla!) 'Dir FFT üretilen bir hız eğrisi (2 x pi bölünerek, omega aritmetik, ardından filtre ile f inv ile takip edilerek, j). fft
Michael M

1
Belki de yaptığınız şey için daha kesin bir matematiksel ifade ya da sözde kod eklerseniz, işleri bir parça netleştirirsiniz.
Fonon

Bazı eklendi, bu kodun genel bir fikir şu ..
Michael M

1
Sorum şu olurdu: verilerde ne görmeyi umuyorsun? Filtrelemeden sonra görmeyi beklediğiniz temel sinyal hakkında bir şey bilmiyorsanız, iyi bir yaklaşımınızın olup olmadığını bilemezsiniz. Ayrıca, gösterdiğiniz kod kafa karıştırıcıdır. fzDizinin ilklendirilmesini göstermemenize rağmen , bunun yerine bir yüksek geçiş filtresi uyguladığınız anlaşılıyor.
Jason R,

Yanıtlar:


13

Sinyallerin Dengelenmesi için Püf Torbalarında @JoRRobertson'un belirttiği gibi , Keskin Geçişlerin Korunması Sırasında, eğer sinyaliniz sabitse, Toplam Değişme (TV) kınaması iyi bir alternatiftir. Sinyaliniz farklı platolar arasında değişmeye devam ederse, ivmeölçer verileri için geçerli olabilir.

μρ

yxμx-y2+Dx1D

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)];

Sonuçlar:

görüntü tanımını buraya girin görüntü tanımını buraya girin görüntü tanımını buraya girin


Gerçekten bu cevap gibi, devam edip deneyeceğim. Üzgünüm cevap vermem çok uzun sürdü!
Michael M,

Mükemmel cevap Detaylar için teşekkürler. Bu kodun C sürümünü arıyorum. Buradaki herkes bu matlab kodunu paylaşmak istedikleri C'ye taşıdı mı? Teşekkürler.
Rene Limberger,

Parça bazında sabit ne demektir?
tilaprimera

6

Sorun, gürültünüzün düz bir spektruma sahip olmasıdır. Beyaz Gauss gürültüsünü varsayarsanız (ki bu iyi bir varsayım olur) güç spektrumu yoğunluğu sabittir. Kabaca konuşursak, gürültünüzün tüm frekansları içerdiği anlamına gelir. Bu nedenle DFT veya düşük geçişli filtreler gibi herhangi bir frekans yaklaşımı iyi değildir. Gürültünüz spektrumun her tarafında olduğu için kesme frekanslarınız ne olur?

Bu sorunun bir cevabı, gürültünüzün istatistikleri ve istediğiniz sinyal hakkında bilgi gerektiren Wiener filtresidir. Temel olarak, gürültünün sinyali (sinyal + gürültü), gürültünün sinyalinizden daha yüksek olması beklenen frekanslar üzerinde zayıflatılır ve sinyalinizin gürültüsünden daha yüksek olması beklenen gçlendirilir.

Ancak, doğrusal olmayan işlemeyi, örneğin dalgacık denoising kullanan daha modern yaklaşımlar öneririm. Bu yöntemler mükemmel sonuçlar sağlar. Temel olarak, gürültülü sinyal önce dalgacıklara ayrıştırılır ve daha sonra küçük katsayılar sıfırlanır. Bu yaklaşım, dalgacıkların çoklu çözünürlük özelliklerinden dolayı işe yarar (ve DFT işe yaramaz). Yani sinyal, dalgacık dönüşümü tarafından tanımlanan frekans bantlarında ayrı olarak işlenir.

MATLAB'da 'wavemenu' ve sonra 'SWT dengeleyici 1-D' yazın. Daha sonra 'Dosya', 'Örnek Analizi', 'Gürültülü sinyaller', '5. seviyedeki Haar, Gürültülü bloklar'. Bu örnekte, probleminiz için iyi çalışması gereken Haar dalgacık kullanılmıştır.

Python'da iyi değilim ama Haar dalgacık denoising işlemi yapan bazı NumPy paketlerini bulabileceğinize inanıyorum.


1
İlk ifadene katılmıyorum. İlgilendiğiniz sinyalin, giriş sırasının tam bant genişliğini kapsadığını ve bunun olası olmadığını varsayıyorsunuz. Bu durumda, bant dışı gürültüyü ortadan kaldıran doğrusal filtreleme kullanarak sinyal-gürültü oranının iyileştirilmesi hala mümkündür. Sinyal çok fazla örneklenmişse, bu kadar basit bir yaklaşımla büyük bir gelişme elde edebilirsiniz.
Jason R

Doğru ve bu, sinyalinizin ve gürültünüzün istatistiklerini bildiğiniz zaman Wiener filtresi tarafından gerçekleştirilir.
Daniel R. Pipa,

Her ne kadar dalgacık denoising arkasındaki teori karmaşık olsa da, uygulama tarif ettiğiniz yaklaşım kadar basittir. Sadece filtre bankaları ve eşikleme içerir.
Daniel R. Pipa,

1
Şimdi bununla ilgili araştırma yapıyorum, şu ana kadarki yardımlarınız için hem siz hem de Phonon'a teşekkürler.
Michael M,

@DanielPipa Söz konusu matlab paketlerine erişimim yok. Matlab kodunuza karşılık gelen metodu tanımlayan bir makale veya başka bir referans verebilir misiniz?
John Robertson,

0

Daniel Pipa'nın önerisine göre ben bir baktım dalgacık denojenasyonuna ve bu mükemmel makaleyi Francisco Blanco- Silva’ndan buldum .

Burada, Python kodunu görüntü işleme için 3D (görüntü) verileri yerine 2D (ivmeölçer) ile çalışacak şekilde değiştirdim.

Not eşik Francisco'nun örnekte yumuşak eşikleme için "yapılmış" olduğunu. Bunu düşünün ve uygulamanız için değiştirin.

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)

Nerede:

  • wavelet- kullanılacak dalgacık formunun dize adı (bakınız pywt.wavelist(), örneğin 'haar')
  • noise_sigma - Gürültü verilerinden standart sapma
  • data - filtrelenecek değer dizisi (örneğin, x, y veya z ekseni verileri)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.