-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsignal_process.rs
151 lines (126 loc) · 4.15 KB
/
signal_process.rs
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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
use std::collections::VecDeque;
use std::f32::consts::PI;
pub struct ButterworthFilter {
k1: f32,
k2: f32,
prev_input: f32,
prev_output: f32,
}
impl ButterworthFilter {
pub fn new(cutoff: f32, sample_rate: f32) -> Self {
let wc = (2.0 * PI * cutoff / sample_rate).tan();
let k1 = wc / (1.0 + wc);
let k2 = (1.0 - wc) / (1.0 + wc);
Self {
k1,
k2,
prev_input: 0.0,
prev_output: 0.0,
}
}
pub fn filter(&mut self, input: f32) -> f32 {
let output = self.k1 * input + self.k1 * self.prev_input + self.k2 * self.prev_output;
self.prev_input = input;
self.prev_output = output;
output
}
}
pub struct HighPassFilter {
k1: f32,
prev_input: f32,
prev_output: f32,
}
impl HighPassFilter {
pub fn new(cutoff: f32, sample_rate: f32) -> Self {
let wc = (2.0 * PI * cutoff / sample_rate).tan();
let k1 = 1.0 / (1.0 + wc);
Self {
k1,
prev_input: 0.0,
prev_output: 0.0,
}
}
pub fn filter(&mut self, input: f32) -> f32 {
let output = self.k1 * (input - self.prev_output);
self.prev_input = input;
self.prev_output = output;
output
}
}
pub struct MovingAverageFilter {
window_size: usize,
buffer: VecDeque<f32>,
sum: f32,
}
impl MovingAverageFilter {
pub fn new(window_size: usize) -> Self {
Self {
window_size,
buffer: VecDeque::with_capacity(window_size),
sum: 0.0,
}
}
pub fn filter(&mut self, input: f32) -> f32 {
if self.buffer.len() == self.window_size {
// 如果缓冲区已满,移除最旧的值
if let Some(old_value) = self.buffer.pop_front() {
self.sum -= old_value;
}
}
// 添加新值
self.buffer.push_back(input);
self.sum += input;
// 返回当前窗口的平均值
self.sum / self.buffer.len() as f32
}
}
// 寻峰算法
pub fn detect_peaks(signal: &[f32], base_threshold: f32, min_distance: usize) -> (usize, bool) {
if signal.len() < 3 {
return (0, false);
}
// 计算信号统计特征
let mean: f32 = signal.iter().sum::<f32>() / signal.len() as f32;
let variance = signal.iter().map(|x| (x - mean).powi(2)).sum::<f32>() / signal.len() as f32;
let std_dev = variance.sqrt();
// 自适应阈值计算
let dynamic_threshold = mean + std_dev; // 使用均值加标准差
let final_threshold = base_threshold.min(dynamic_threshold); // 取较小值作为阈值
let mut peaks = Vec::new();
let window_size = 5; // 用于局部最大值检测的窗口大小
for i in window_size..(signal.len() - window_size) {
let current = signal[i];
// 检查是否超过阈值
if current < final_threshold {
continue;
}
// 检查局部最大值
let is_local_max = (i - window_size..i)
.chain(i + 1..=i + window_size)
.all(|j| current >= signal[j]);
if is_local_max {
// 检查与上一个峰值的距离
if peaks.is_empty() || (i - peaks.last().unwrap() >= min_distance) {
peaks.push(i);
} else if signal[*peaks.last().unwrap()] < current {
// 如果新峰值更大,替换旧峰值
*peaks.last_mut().unwrap() = i;
}
}
}
// 峰值后处理:移除异常值
if peaks.len() > 2 {
let peak_values: Vec<f32> = peaks.iter().map(|&i| signal[i]).collect();
let peak_mean = peak_values.iter().sum::<f32>() / peak_values.len() as f32;
let peak_std = (peak_values
.iter()
.map(|x| (x - peak_mean).powi(2))
.sum::<f32>()
/ peak_values.len() as f32)
.sqrt();
// 移除偏离均值超过2个标准差的峰值
peaks.retain(|&i| (signal[i] - peak_mean).abs() <= 2.0 * peak_std);
}
let bigger = *signal.last().unwrap() > final_threshold;
(peaks.len(), bigger) // 返回峰值数量和是否检测到新峰值
}