我有一个关于滤波的问题。
目前我正在使用惯性测量单元(加速度计/加速度数据)进行行人步伐检测。我需要在预处理阶段对信号进行滤波。能否有人建议哪种滤波算法能获得更好的精度?目前我使用了数字低通FIR滤波器,参数设置为阶数=2,窗口大小=1.2秒,采样频率=200Hz,但似乎效果不佳。我想使用更低的截止频率。我使用了0.03Hz和3Hz的截止频率,但得到的结果相同。我需要您的指导或帮助,告诉我该如何继续。下面,我附上了在3Hz和0.03Hz截止频率下的滤波结果图片链接,以及我尝试过的代码。有人能建议我或提供任何在MATLAB中的好滤波器吗?以及我该如何操作?
3Hz截止频率下的FIR结果 0.03Hz截止频率下的FIR结果
Fs = 200;Hd = designfilt('lowpassfir','FilterOrder',2,'CutoffFrequency',0.03, ... 'DesignMethod','window','Window',{@kaiser,1.2},'SampleRate',Fs);y1 = filter(Hd,norm);plot(Time,norm,'b', Time, y1,'red')xlabel('Time (s)')ylabel('Amplitude')legend('norm','Filtered Data')
回答:
您尝试制作了一个二阶FIR滤波器。该阶数对于您的采样率(200 Hz)和所需的截止频率(3或0.03 Hz)来说太低了。FIR滤波器的所需阶数与IIR滤波器的阶数大不相同。第N阶FIR滤波器对N+1个数据点进行移动平均。Hd=designfilt(…)计算移动平均的系数或权重。我使用您的代码片段制作了3 Hz和0.03 Hz的截止滤波器,并将其命名为Hd300和Hd003。然后我查看了这两个滤波器的系数:
>> disp(Hd003.Coefficients); 0.2947 0.4107 0.2947>> disp(Hd300.Coefficients); 0.2945 0.4110 0.2945
如您所见,它们几乎相同——这就是为什么输出的滤波信号看起来相同的缘故。由于阶数=2对于制作3或0.03 Hz截止的有效FIR滤波器来说,远远不够,因此系数非常相似。您尝试的0.03截止频率对应于大约30(=1/.03)秒的时间常数。对于仅1.6秒长的数据使用如此低的截止频率是不合理的。即使您有数百秒的数据,这也不合理,因为您将使用大约30秒宽的窗口来平滑数据,这将使检测每个步骤变得非常困难。更好的方法:一个简单的二阶巴特沃斯低通滤波器,截止频率=1到10 Hz。请查看下面的代码和图形。我在代码中使用了filtfilt()而不是filter(),因为filtfilt()能更好地处理启动瞬变。将filtfilt()替换为filter(),您就会明白我的意思了。
%pedometerAccelFilter.m WCR 20210117% Question on stack exchange% The code provided on stack exchange assumes vector "norm"% contains 1.6 seconds of acceleration data sampled at 200 Hz.% I digitized the data from the figure on stack exchange and% saved it in file pedometerInterpData.txt (2 columns, 329 rows).%Load the datadata=load('pedometerInterpData.txt');Time=data(:,1); norm=data(:,2);%Compute the filter coefficientsFs=200; %sampling frequency (Hz)order=2;Fc1=5; %filter 1 cutoff frequency (Hz)Wn1=Fc1*2/Fs; %filter 1 normalized cutoff frequency[b1,a1]=butter(order,Wn1); %filter 1 coefficientsFc2=2; %filter 2 cutoff frequency (Hz)Wn2=Fc2*2/Fs; %filter 2 normalized cutoff frequency[b2,a2]=butter(order,Wn2); %filter 2 coefficients%Filter the datay1=filtfilt(b1,a1,norm); %filtfilt() could be replaced with filter()y2=filtfilt(b2,a2,norm);%Plot the dataplot(Time,norm,'r.-',Time,y1,'gx-',Time,y2,'bo-');xlabel('Time (s)'); ylabel('Amplitude');legend('Raw Data','Filter 1','Filter 2');