Memilih filter yang benar untuk data accelerometer

28

Saya cukup baru untuk DSP, dan telah melakukan beberapa penelitian tentang kemungkinan filter untuk menghaluskan data accelerometer dengan python. Contoh tipe data yang akan saya alami dapat dilihat pada gambar berikut:

Data akselerometer

Pada dasarnya, saya mencari saran untuk memuluskan data ini untuk akhirnya mengubahnya menjadi kecepatan dan perpindahan. Saya mengerti bahwa akselerometer dari ponsel sangat bising.

Saya tidak berpikir saya dapat menggunakan filter Kalman saat ini karena saya tidak bisa mendapatkan perangkat untuk referensi kebisingan yang dihasilkan oleh data (saya membaca bahwa penting untuk menempatkan perangkat datar dan menemukan jumlah suara dari pembacaan itu?)

FFT telah menghasilkan beberapa hasil menarik. Salah satu upaya saya adalah untuk FFT sinyal akselerasi, kemudian membuat frekuensi rendah untuk memiliki nilai FFT absolut dari 0. Kemudian saya menggunakan aritmatika omega dan invers FFT untuk mendapatkan plot kecepatan. Hasilnya adalah sebagai berikut:

Sinyal yang difilter

Apakah ini cara yang baik untuk melakukan sesuatu? Saya mencoba untuk menghilangkan sifat bising keseluruhan sinyal tetapi puncak yang jelas seperti sekitar 80 detik perlu diidentifikasi.

Saya juga lelah menggunakan low pass filter pada data accelerometer asli, yang telah melakukan pekerjaan yang sangat baik untuk melicinkannya, tetapi saya tidak begitu yakin ke mana harus pergi dari sini. Bimbingan tentang ke mana harus pergi dari sini akan sangat membantu!

EDIT: Sedikit kode:

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

Jadi pada dasarnya, saya telah melakukan FFT pada data accelerometer saya, memberikan Sz, menyaring frekuensi tinggi menggunakan filter dinding bata sederhana (saya tahu itu tidak ideal). Kemudian ive gunakan omega aritmatika pada FFT data. Juga terima kasih banyak kepada ahli data untuk menambahkan gambar saya ke dalam posting saya :)

Michael M.
sumber
Selamat datang di DSP! Apakah kurva merah di gambar kedua Anda versi "dihaluskan" dari data asli (hijau)?
Phonon
Kurva merah (mudah-mudahan!) Kurva kecepatan yang dihasilkan dari FFT diikuti dengan menyaring, diikuti oleh omega aritmatika (membagi dengan 2 * pi f j), berikut dengan inv. fft
Michael M
1
Mungkin jika Anda memasukkan ekspresi matematika yang lebih tepat atau pseudocode untuk apa yang Anda lakukan akan menghapus semuanya.
Phonon
Menambahkan beberapa sekarang, itulah nuansa umum kode ..
Michael M
1
Pertanyaan saya adalah: apa yang Anda harapkan dari data? Anda tidak akan tahu apakah Anda memiliki pendekatan yang baik kecuali jika Anda tahu sesuatu tentang sinyal yang mendasarinya yang Anda harapkan untuk dilihat setelah pemfilteran. Selain itu, kode yang Anda tampilkan membingungkan. Meskipun Anda tidak menunjukkan inisialisasi fzarray, tampaknya Anda menerapkan filter jalan pintas.
Jason R

Jawaban:

13

Seperti yang ditunjukkan oleh @JohnRobertson dalam Bag of Tricks for Denoising Signals Sementara Mempertahankan Transisi Tajam , Total Variaton (TV) denoising adalah alternatif lain yang baik jika sinyal Anda konstan konstan. Ini mungkin menjadi kasus untuk data accelerometer, jika sinyal Anda terus bervariasi antara plateaux berbeda.

Di bawah ini adalah kode Matlab yang melakukan denoising TV dalam sinyal seperti itu. Kode ini didasarkan pada kertas Metode Augmented Lagrangian untuk Pemulihan Video Variasi Total . Parameter dan harus disesuaikan sesuai dengan tingkat kebisingan dan karakteristik sinyal.μρ

Jika adalah sinyal berisik dan adalah sinyal yang diperkirakan, fungsi yang akan diminimalkan adalah , di mana adalah operator perbedaan hingga.yxμxy2+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)];

Hasil:

masukkan deskripsi gambar di sini masukkan deskripsi gambar di sini masukkan deskripsi gambar di sini

Daniel R. Pipa
sumber
Benar-benar menyukai jawaban ini, akan terus maju dan mencobanya. Maaf butuh waktu lama untuk membalas!
Michael M
Jawaban yang sangat bagus. Terima kasih untuk detailnya. Saya mencari versi C dari kode ini. Adakah yang mengirim kode matlab ini ke C yang ingin mereka bagikan? Terima kasih.
Rene Limberger
Apa arti konstanta sepotong-bijaksana?
tilaprimera
6

Masalahnya adalah bahwa suara Anda memiliki spektrum datar. Jika Anda menganggap noise Gaussian putih (yang ternyata menjadi asumsi yang baik) kerapatan spektrum dayanya konstan. Secara kasar, ini berarti bahwa suara Anda mengandung semua frekuensi. Itu sebabnya pendekatan frekuensi apa pun, misalnya DFT atau filter low-pass, tidak bagus. Apa yang akan menjadi frekuensi cut-off Anda karena kebisingan Anda ada di seluruh spektrum?

Satu jawaban untuk pertanyaan ini adalah filter Wiener, yang membutuhkan pengetahuan tentang statistik kebisingan Anda dan sinyal yang Anda inginkan. Pada dasarnya, sinyal berisik (sinyal + noise) dilemahkan pada frekuensi di mana noise diharapkan lebih besar daripada sinyal Anda, dan itu diperkuat di mana sinyal Anda diharapkan lebih besar daripada noise Anda.

Namun, saya akan menyarankan pendekatan yang lebih modern yang menggunakan pemrosesan non-linear, misalnya denoising wavelet. Metode-metode ini memberikan hasil yang sangat baik. Pada dasarnya, sinyal berisik pertama kali didekomposisi menjadi wavelet dan kemudian koefisien kecil menjadi nol. Pendekatan ini berfungsi (dan DFT tidak) karena sifat multi-resolusi wavelet. Artinya, sinyal diproses secara terpisah dalam pita frekuensi yang ditentukan oleh transformasi wavelet.

Dalam MATLAB, ketik 'wavemenu' dan kemudian 'SWT denoising 1-D'. Kemudian 'File', 'Analisis Contoh', 'Sinyal bising', 'dengan Haar di level 5, blok Bising'. Contoh ini menggunakan wavelet Haar, yang seharusnya berfungsi dengan baik untuk masalah Anda.

Saya tidak pandai Python, tapi saya percaya Anda dapat menemukan beberapa paket NumPy yang melakukan denoising Haar wavelet.

Daniel R. Pipa
sumber
1
Saya tidak setuju dengan pernyataan pertama Anda. Anda berasumsi bahwa sinyal yang menarik mencakup bandwidth penuh dari urutan input, yang tidak mungkin. Masih dimungkinkan untuk mendapatkan rasio sinyal-ke-noise yang ditingkatkan dengan menggunakan penyaringan linier dalam kasus ini, menghilangkan noise out-of-band. Jika sinyalnya sangat berlebih, maka Anda dapat memperoleh peningkatan besar dengan pendekatan sederhana.
Jason R
Itu benar, dan ini dicapai oleh filter Wiener, ketika Anda mengetahui statistik sinyal dan kebisingan Anda.
Daniel R. Pipa
Meskipun teori di balik denoising wavelet itu rumit, implementasinya sesederhana pendekatan yang Anda gambarkan. Ini hanya melibatkan bank filter dan thresholding.
Daniel R. Pipa
1
Saya sedang meneliti ini sekarang, akan memposting kemajuan saya di atas, terima kasih kepada Anda dan Phonon untuk semua bantuan Anda sejauh ini!
Michael M
@DanielPipa Saya tidak memiliki akses ke paket matlab yang dimaksud. Bisakah Anda memberikan kertas atau referensi lain yang menjelaskan metode yang sesuai dengan kode matlab Anda.
John Robertson
0

Sesuai saran Daniel Pipa, saya melihat denoising wavelet dan menemukan artikel yang bagus ini oleh Francisco Blanco-Silva.

Di sini saya telah memodifikasi kode Python-nya untuk pemrosesan gambar agar bekerja dengan data 2D (akselerometer) daripada 3D (gambar).

Perhatikan , ambang "dibuat" untuk soft-thresholding dalam contoh Francisco. Pertimbangkan ini dan modifikasi untuk aplikasi Anda.

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)

Dimana:

  • wavelet- nama string dari bentuk wavelet yang akan digunakan (lihat pywt.wavelist(), misalnya 'haar')
  • noise_sigma - standar deviasi kebisingan dari data
  • data - array nilai yang akan difilter (mis. data sumbu x, y, atau z)
ryanjdillon
sumber