为加速度计数据选择正确的过滤器

信息处理 fft Python
2022-01-07 22:17:13

我对 DSP 相当陌生,并且已经对可能的过滤器进行了一些研究,以在 python 中平滑加速度计数据。下图中可以看到我将遇到的数据类型的示例:

加速度计数据

本质上,我正在寻找有关平滑这些数据以最终将其转换为速度和位移的建议。我知道手机的加速度计非常嘈杂。

我认为我目前不能使用卡尔曼滤波器,因为我无法掌握设备来参考数据产生的噪声(我读到将设备平放并从这些读数中找出噪声量是必不可少的吗?)

FFT 产生了一些有趣的结果。我的尝试之一是对加速度信号进行 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

所以本质上,我对我的加速度计数据执行了 FFT,使用简单的砖墙滤波器(我知道它不理想)将 Sz 过滤掉了高频。然后我对数据的 FFT 使用欧米茄算术。也非常感谢 datageist 将我的图片添加到我的帖子中 :)

3个回答

正如@JohnRobertson 在保持尖锐过渡的同时去噪信号的技巧包中所指出的,如果您的信号是分段恒定的,则总变差 (TV) 去噪是另一个不错的选择。如果您的信号在不同的平台之间不断变化,则加速度计数据可能就是这种情况。

下面是一个 Matlab 代码,它在这样的信号中执行电视去噪。该代码基于论文An Augmented Lagrangian Method for Total Variation Video Restoration参数μρ必须根据噪声水平和信号特性进行调整。

如果y是噪声信号,并且x是要估计的信号,要最小化的函数是μxy2+Dx1,其中是有限差分算子。D

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

结果:

在此处输入图像描述 在此处输入图像描述 在此处输入图像描述

问题是你的噪音有一个平坦的频谱。如果您假设高斯白噪声(事实证明这是一个很好的假设),则其功率谱密度是恒定的。粗略地说,这意味着您的噪声包含所有频率。这就是为什么任何频率方法(例如 DFT 或低通滤波器)都不是一个好的方法。由于您的噪音遍布整个频谱,您的截止频率是多少?

这个问题的一个答案是维纳滤波器,它需要了解噪声和所需信号的统计信息。基本上,噪声信号(信号 + 噪声)在预期噪声比您的信号更大的频率上被衰减,并且在您的信号预期比您的噪声更大的地方被放大。

但是,我会建议使用非线性处理的更现代的方法,例如小波去噪。这些方法提供了极好的结果。基本上,噪声信号首先分解为小波,然后将小系数归零。由于小波的多分辨率特性,这种方法有效(而 DFT 无效)。也就是说,在小波变换定义的频带中分别处理信号。

在 MATLAB 中,输入“wavemenu”,然后输入“SWT denoising 1-D”。然后是“文件”、“示例分析”、“噪声信号”、“Haar 在第 5 级,噪声块”。此示例使用 Haar 小波,它应该可以很好地解决您的问题。

我不擅长 Python,但我相信你可以找到一些执行 Haar 小波去噪的 NumPy 包。

根据 Daniel Pipa 的建议,我看了一下小波去噪,发现了 Francisco Blanco-Silva 的这篇优秀文章

在这里,我修改了他用于图像处理的 Python 代码,以使用 2D(加速度计)而不是 3D(图像)数据。

请注意,在弗朗西斯科的示例中,阈值是“弥补”的软阈值。考虑这一点并针对您的应用程序进行修改。

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 轴数据)