0%

自适应滤波算法

简介

​ 在频域的滤波,有些时候简单的高通滤波、低通滤波并不能很好的解决问题。比如有一种业务场景: 某次实验需要用到几个传感器在实验开始前启动传感器,一秒后启动实验装置,实验持续一秒。如此、我们就可以确定传感器数据中前一秒的数据全为无效信号即可定义为全为杂波、传感器数据中第二秒的数据为有效信号与无效信号的一个叠加信号。也就是说将第二秒的叠加信号减去第一秒的无效信号即为有效信号。改文档详细介绍这种滤波算法的过程以及优劣。

实现过程

  • 获取杂波信号

    • 从原始的信号中提取出杂波信号。比如0-1秒的数据碓冰的数据库中的0-10000的条目,提取这部分数据。以0-1W为x轴数据,以提取出的数据为y轴数据生成时域图像。
  • 提取杂波信号频谱数据

    • 对时域图像做傅里叶变换。 因为仅傅里叶变换后的数据x轴为一个频率的映射(需要经过k*fs/N才能得到对应的频率),Y轴数据为振幅的一个映射(需要经过 _Y[0] = _Y[0]/2 _Y = [_Y[i]*2/len(_Y) for i in range(0,len(_Y))] 操作后才能得到真正的振幅)这里将傅里叶变换生成的频谱图的振幅转化为真实的振幅。
  • 提取特征信号段

    • 确定特征信号段提取这部分数据,提取流程与提取杂波信号一致
  • 提取特特征信号段频谱数据

    • 与提取杂波信号频谱的操作流程一致
  • 特征信号段频谱数据减杂波信号数据得到有效信号频谱数据

    • 用特征信号频谱数据减杂波信号频谱数据得到有效信号频谱数据。将有效信号频谱数据做_Y[0] = _Y[0]*2 _Y = [_Y[i]/2*len(_Y) for i in range(0,len(_Y))]操作为傅里叶反变换做准备
  • 傅里叶反变换得到有效信号的时域图像

    • 将有效信号频谱数据压入傅里叶反变换算法得到有效信号时域图像

试用情况

算法测试

示例代码执行结果

对杂波信号、特征信号、有效信号的频谱图做放大可以很明显的看到相同的信号。这两个数据做差将杂波滤掉。在有效信号频谱中可以看到仍含有一个振幅为±0.05的信号经排查发现为杂波信号与特征信号的确含有0.05的误差滤波效果并不是特别理想

真实数据测试

一个较为明显的数据 从图中可以看出起了一部分作用但效果并不明显(可能留下的就是有效信号)

一个效果很差的图像 (可以从图中看出前一秒的传感器数据图像含有一定的规律不能定义是否完全为杂波(可以确定的是该时段未进行实验))减去该时段的频域图像后生成的有效信号波形更加奇怪

总结

​ 滤波效果并不十分理想, 而且必须确定大致的杂波信号段(传感器肯定先于实验启动 该段时间容易确定)确定特征信号段 。(该段时间不容易确定 如果是长时间的实验大段时间都为特征信号段则不易处理) 并且杂波信号与特征信号持续时间应近乎一致(本来就存在一个较大的误差 如果杂波信号或特征信号过于稀疏则相减时误差更大近乎完全无法使用)

可用性并不十分理想 特定条件下可能存在一定优势

代码示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
def start(self):
_arraylength = 100000
_titileArraylength = 10000
_zq = 10
_zq1 = 100
_x = range(_arraylength)
_y = [np.sin(_x[i]/2/np.pi/_zq) for i in range(0,_arraylength)]

for i in range(_titileArraylength,_arraylength):
if i > _titileArraylength:
_y[i] = _y[i] + np.sin(_x[i]/2/np.pi/_zq1)

plt.figure(1)

# 原始信号
plt.subplot(241)
plt.plot(_x,_y)

# 原始频谱
plt.subplot(245)
_Y = np.fft.fft(_y)

_Y[0] = _Y[0]/2
_Y = [_Y[i]*2/len(_Y) for i in range(0,len(_Y))]
plt.plot(_x,_Y)

# 杂波信号
plt.subplot(242)
plt.plot(_x[:_titileArraylength],_y[:_titileArraylength])

# 杂波频谱
plt.subplot(246)
_Yz = np.fft.fft(_y[:_titileArraylength])

_Yz[0] = _Yz[0]/2
_Yz = [_Yz[i]*2/len(_Yz) for i in range(0,len(_Yz))]

plt.plot(_x[:_titileArraylength],_Yz)

# 特征信号段
plt.subplot(243)
_yt = _y[60000:70000]
_xt = _x[60000:70000]
plt.plot(_xt,_yt)

# 特征信号频谱
plt.subplot(247)
_Yt = np.fft.fft(_yt)

_Yt[0] = _Yt[0]/2
_Yt = [_Yt[i]*2/len(_Yt) for i in range(0,len(_Yt))]

plt.plot(_xt,_Yt)

# 有效信号频谱
plt.subplot(248)
_Yy = [_Yt[i]-_Yz[i] for i in range(len(_Yz))]
plt.plot(_xt,_Yy)

_Yy[0] = _Yy[0]*2
_Yy = [_Yy[i]/2*len(_Yy) for i in range(0,len(_Yy))]

plt.subplot(244)

_yy = np.fft.ifft(_Yy)
_yy[:50] = 0
plt.plot(_xt,_yy)

plt.show()