希尔伯特变换 实现包络提取 C++
时间: 2023-10-20 09:07:16 浏览: 456
MATLAB希尔伯特Hilbert变换求包络谱 源程序代码
5星 · 资源好评率100%
希尔伯特变换可以用于提取信号的包络,这在信号处理中很常见。以下是一个简单的C++实现:
```c++
#include <complex>
#include <iostream>
#include <vector>
using namespace std;
void hilbert_transform(const vector<double>& x, vector<complex<double>>& y) {
int n = x.size();
vector<double> h(n), f(n);
h[0] = h[n / 2] = 1;
for (int i = 1; i < n / 2; i++) {
h[i] = 2;
}
for (int i = 0; i < n; i++) {
f[i] = 2 * M_PI / n * i;
}
vector<complex<double>> c(n);
for (int i = 0; i < n; i++) {
c[i] = complex<double>(x[i], 0);
}
vector<complex<double>> dft(n);
for (int i = 0; i < n; i++) {
complex<double> sum(0, 0);
for (int j = 0; j < n; j++) {
sum += c[j] * exp(complex<double>(0, -f[i] * j));
}
dft[i] = sum;
}
for (int i = 0; i < n; i++) {
dft[i] *= h[i];
}
for (int i = 0; i < n; i++) {
c[i] = complex<double>(0, 0);
for (int j = 0; j < n; j++) {
c[i] += dft[j] * exp(complex<double>(0, f[i] * j));
}
y[i] = c[i] / complex<double>(0, 1);
}
}
void envelope_extraction(const vector<double>& x, vector<double>& y) {
vector<complex<double>> z(x.size());
hilbert_transform(x, z);
for (int i = 0; i < x.size(); i++) {
y[i] = sqrt(x[i] * x[i] + z[i].imag() * z[i].imag());
}
}
int main() {
vector<double> x = {1, 2, 3, 4, 5};
vector<double> y(x.size());
envelope_extraction(x, y);
for (int i = 0; i < x.size(); i++) {
cout << y[i] << endl;
}
return 0;
}
```
这段代码首先调用了上面提到的希尔伯特变换函数,然后根据公式 $y(t) = \sqrt{x^2(t) + z^2(t)}$ ,计算出信号的包络。最后输出包络信号。
阅读全文