简单低通滤波器

以下是一个使用C++语言编写的基本低通滤波器的示例代码,它可以对输入信号进行滤波以降低高频成分:

#include <iostream>
#include <vector>
#include <cmath>using namespace std;// 低通滤波器类
class LowPassFilter {
public:LowPassFilter(double sample_rate, double cutoff_frequency) {double dt = 1.0 / sample_rate;double RC = 1.0 / (cutoff_frequency * 2.0 * M_PI);alpha_ = dt / (dt + RC);prev_output_ = 0.0;}// 更新滤波器输出double update(double input) {double output = alpha_ * input + (1.0 - alpha_) * prev_output_;prev_output_ = output;return output;}private:double alpha_;double prev_output_;
};int main() {// 输入信号vector<double> input_signal = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0};// 采样率和截止频率double sample_rate = 100.0;double cutoff_frequency = 10.0;// 创建低通滤波器LowPassFilter filter(sample_rate, cutoff_frequency);// 对输入信号进行滤波vector<double> output_signal;for (double input : input_signal) {double output = filter.update(input);output_signal.push_back(output);}// 输出滤波结果for (double output : output_signal) {cout << output << " ";}cout << endl;return 0;
}

在这个示例中,我们使用一个一阶滤波器来实现低通滤波器。该滤波器具有一个截止频率,所有高于该频率的信号成分都会被过滤掉。在构造函数中,我们根据采样率和截止频率计算出滤波器的alpha系数,这个系数用于控制信号在输入和输出之间的平衡。然后,我们在update函数中使用输入信号和alpha系数来计算滤波器的输出,并且将输出保存在prev_output_中,以便在下一次更新时使用。

在主函数中,我们创建了一个输入信号向量,并且创建了一个低通滤波器对象。然后,我们使用for循环将输入信号中的每个元素传递给滤波器进行处理,并且将输出保存在一个新的向量中。最后,我们将滤波后的输出向量输出到控制台。

FIR低通滤波器

以下是一个使用C++语言编写的基本FIR滤波器的示例代码,它可以对输入信号进行滤波以实现频率选择性:

#include <iostream>
#include <vector>
#include <cmath>using namespace std;// 创建一个函数,用于生成低通滤波器的系数
vector<double> createLowpassFilter(int M, double fc, double fs) {vector<double> h(M + 1);for (int n = 0; n <= M; ++n) {if (n == M / 2) {h[n] = 2.0 * fc / fs;} else {h[n] = sin(2.0 * M_PI * fc * (n - M / 2.0) / fs) / (M_PI * (n - M / 2.0));}h[n] *= 0.54 - 0.46 * cos(2.0 * M_PI * n / M);}return h;
}// FIR滤波器类
class FirFilter {
public:FirFilter(const vector<double>& taps) : taps_(taps), buffer_(taps.size(), 0.0) {}// 更新滤波器输出double update(double input) {// 将新的输入添加到环形缓冲区中buffer_.insert(buffer_.begin(), input);buffer_.pop_back();// 计算输出值double output = 0.0;for (int i = 0; i < taps_.size(); ++i) {output += taps_[i] * buffer_[i];}return output;}private:vector<double> taps_;  // 滤波器系数vector<double> buffer_;  // 环形缓冲区
};int main() {// 创建低通滤波器系数int M = 31;  // 系数数量double fc = 1000.0;  // 截止频率double fs = 44100.0;  // 采样率vector<double> taps = createLowpassFilter(M, fc, fs);// 输入信号vector<double> input_signal = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0};// 创建FIR滤波器FirFilter filter(taps);// 对输入信号进行滤波vector<double> output_signal;for (double input : input_signal) {double output = filter.update(input);output_signal.push_back(output);}// 输出滤波结果for (double output : output_signal) {cout << output << " ";}cout << endl;return 0;
}

在这个示例中,我们创建了一个名为createLowpassFilter的函数来生成FIR低通滤波器的系数。该函数接受三个参数:滤波器的长度M,截止频率fc和采样率fs。

IIR低通滤波器

#include <iostream>
#include <vector>
#include <cmath>using namespace std;class IirFilter {
public:IirFilter(double a0, double a1, double a2, double b1, double b2) : a0_(a0), a1_(a1), a2_(a2), b1_(b1), b2_(b2), x1_(0), x2_(0), y1_(0), y2_(0) {}// 更新滤波器输出double update(double input) {double output = a0_ * input + a1_ * x1_ + a2_ * x2_ - b1_ * y1_ - b2_ * y2_;x2_ = x1_;x1_ = input;y2_ = y1_;y1_ = output;return output;}private:double a0_, a1_, a2_, b1_, b2_;  // 滤波器系数double x1_, x2_, y1_, y2_;  // 状态变量
};int main() {// 设计IIR低通滤波器double fc = 1000.0;  // 截止频率double fs = 44100.0;  // 采样率double wc = 2.0 * M_PI * fc / fs;double Q = 0.707;  // 品质因数double alpha = sin(wc) / (2.0 * Q);double a0 = 1.0 + alpha;double a1 = -2.0 * cos(wc);double a2 = 1.0 - alpha;double b0 = (1.0 - cos(wc)) / 2.0;double b1 = 1.0 - cos(wc);double b2 = (1.0 - cos(wc)) / 2.0;// 创建IIR低通滤波器IirFilter filter(a0, a1, a2, b1, b2);// 输入信号vector<double> input_signal = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0};// 对输入信号进行滤波vector<double> output_signal;for (double input : input_signal) {double output = filter.update(input);output_signal.push_back(output);}// 输出滤波结果for (double output : output_signal) {cout << output << " ";}cout << endl;return 0;
}

在这个示例中,我们使用IirFilter类来实现IIR低通滤波器。该类接受五个参数,分别是系数a0,a1,a2,b1和b2。

简单带通滤波器

以下是一个简单的C++实现带通滤波器的例子。该代码使用了离散傅里叶变换(DFT)来计算信号的频谱,然后对频谱进行滤波。

#include <cmath>
#include <vector>using namespace std;const double PI = 3.14159265358979323846;// 计算离散傅里叶变换
void dft(const vector<double>& input, vector<complex<double>>& output) {int n = input.size();output.resize(n);for (int k = 0; k < n; k++) {complex<double> sum(0, 0);for (int j = 0; j < n; j++) {double angle = 2 * PI * k * j / n;sum += input[j] * exp(complex<double>(0, -angle));}output[k] = sum;}
}// 计算滤波器的频率响应
void filter(vector<double>& spectrum, double f1, double f2, double fs) {int n = spectrum.size();for (int k = 0; k < n; k++) {double freq = k * fs / n;if (freq < f1 || freq > f2) {spectrum[k] = 0;}}
}// 带通滤波器
void bandpass_filter(vector<double>& signal, double f1, double f2, double fs) {int n = signal.size();// 计算信号的频谱vector<complex<double>> spectrum;dft(signal, spectrum);// 对频谱进行滤波filter(spectrum, f1, f2, fs);// 计算滤波后的信号vector<double> filtered_signal;filtered_signal.resize(n);for (int i = 0; i < n; i++) {double sum = 0;for (int k = 0; k < n; k++) {double angle = 2 * PI * i * k / n;sum += spectrum[k].real() * cos(angle) - spectrum[k].imag() * sin(angle);}filtered_signal[i] = sum / n;}// 将滤波后的信号复制回原信号for (int i = 0; i < n; i++) {signal[i] = filtered_signal[i];}
}

这个实现中,带通滤波器被定义为 bandpass_filter 函数。它接受三个参数:输入信号 signal、截止频率 f1 和 f2,以及采样频率 fs。函数将修改输入信号的值,以使其成为经过带通滤波后的信号。

其中,dft 函数计算信号的离散傅里叶变换,filter 函数计算滤波器的频率响应,filtered_signal 数组存储滤波后的信号。

FIR带通滤波器

FIR滤波器是一种常用的数字滤波器类型,它在离散时间域内使用有限数量的系数(即有限冲击响应)来实现滤波器的功能。FIR带通滤波器可以通过在传递函数的频域上选择一个带通区域的方式来实现。以下是一个简单的C++实现FIR带通滤波器的例子:

#include <cmath>
#include <vector>using namespace std;const double PI = 3.14159265358979323846;// FIR带通滤波器
void bandpass_filter(vector<double>& signal, double f1, double f2, double fs, int num_taps) {int n = signal.size();// 计算滤波器系数vector<double> h;h.resize(num_taps);double hsum = 0;for (int i = 0; i < num_taps; i++) {double freq = (double)i / num_taps * fs;if (freq >= f1 && freq <= f2) {h[i] = 2 * (f2 - f1) / fs * cos(2 * PI * (f1 + f2) / 2 / fs * (i - (num_taps - 1) / 2.0)) / PI;} else {h[i] = 0;}hsum += h[i];}for (int i = 0; i < num_taps; i++) {h[i] /= hsum;}// 对信号进行滤波vector<double> filtered_signal;filtered_signal.resize(n);for (int i = 0; i < n; i++) {double sum = 0;for (int j = 0; j < num_taps; j++) {if (i >= j) {sum += h[j] * signal[i - j];}}filtered_signal[i] = sum;}// 将滤波后的信号复制回原信号for (int i = 0; i < n; i++) {signal[i] = filtered_signal[i];}
}

这个实现中,FIR带通滤波器被定义为 bandpass_filter 函数。它接受四个参数:输入信号 signal、截止频率 f1 和 f2,以及采样频率 fs,还有滤波器的阶数(即系数数量)num_taps。函数将修改输入信号的值,以使其成为经过带通滤波后的信号。

其中,h 数组存储滤波器的系数,filtered_signal 数组存储滤波后的信号。对于一个给定的阶数 num_taps,h 数组的值通过选择一个带通区域来计算。filtered_signal 数组的值是通过将信号与滤波器系数进行卷积来计算的。

IIR带通滤波器

IIR滤波器是一种数字滤波器类型,它在离散时间域内使用递归的系数来实现滤波器的功能。相对于FIR滤波器,IIR滤波器具有更小的阶数,更快的计算速度和更平滑的滤波特性。以下是一个简单的C++实现IIR带通滤波器的例子:

#include <cmath>
#include <vector>using namespace std;const double PI = 3.14159265358979323846;// IIR带通滤波器
void bandpass_filter(vector<double>& signal, double f1, double f2, double fs, double Q) {int n = signal.size();// 计算滤波器系数double w1 = 2 * PI * f1 / fs;double w2 = 2 * PI * f2 / fs;double bw = w2 - w1;double wc = sqrt(w1 * w2);double alpha = sin(bw) / (2 * Q);double b0 = alpha;double b1 = 0;double b2 = -alpha;double a0 = 1 + alpha;double a1 = -2 * cos(wc);double a2 = 1 - alpha;// 对信号进行滤波double x1 = 0, x2 = 0, y1 = 0, y2 = 0;for (int i = 0; i < n; i++) {double x0 = signal[i];double y0 = (b0 * x0 + b1 * x1 + b2 * x2 - a1 * y1 - a2 * y2) / a0;signal[i] = y0;x2 = x1;x1 = x0;y2 = y1;y1 = y0;}
}

这个实现中,IIR带通滤波器被定义为 bandpass_filter 函数。它接受四个参数:输入信号 signal、截止频率 f1 和 f2,以及采样频率 fs,还有滤波器的品质因数 Q。函数将修改输入信号的值,以使其成为经过带通滤波后的信号。

其中,b0、b1、b2、a0、a1、a2 分别是IIR滤波器的递归和非递归系数,它们的值通过选择一个带通区域来计算。x1、x2、y1、y2 是IIR滤波器的历史输入和输出样本,它们用于实现滤波器的递归过程。signal[i] 是当前输入样本的输出样本,由递归和非递归系数和历史输入和输出样本计算而来。

使用C++设计滤波器(低通滤波器,高通滤波器,带通滤波器)相关推荐

  1. 常用滤波器设计之低通滤波器、高通滤波器、带通滤波器、带阻滤波器

    本文为转载内容,原文地址为点击打开链接. 下两个滤波器都是切比雪夫I型数字滤波器,不是巴特沃尔滤波器,请使用者注意! 1.低通滤波器 使用说明:将下列代码幅值然后以m文件保存,文件名要与函数名相同,这 ...

  2. 低通滤波器转带通滤波器公式由来_开关电源电磁兼容进级EMI传导输入滤波器的设计理论(EDTEST上海)...

    在刚刚结束的EDTEST-上海站:开关电源电磁兼容进级优化设计:对于有开关电源的产品及控制系统:其输入EMI低通滤波器放置在输入端对系统的EMS设计也是非常关键的! 再补充详解一下:我讲的开关电源系统 ...

  3. matlab椭圆函数滤波器,椭圆函数LC带通滤波器的应用设计

    滤波器类型的选择可根据滤波器设计的带宽等指标和具体的应用场合来选择.相对带宽在20%以下的为窄带滤波器,应选用窄带滤波器的设计方法来设计:相对带宽在40%以上的为宽带滤波器,应选用宽带滤波器的设计方法 ...

  4. 用matlab设计滤波器实验报告,数字信号出来实验报告--matlab滤波器设计

    数字信号出来实验报告--matlab滤波器设计 广 西 工 学 院 实 验 报 告 用 纸 实验名称 IIR数字滤波器的设计 实验成绩 指导老师 陈艳 系(院) 计算机工程系 班级 学号 学生姓名 一 ...

  5. MATLAB设计滤波器代码

    自测可用,最基本的代码,无拔高. 目录 1.设计IIR模拟高低通滤波器 2.设计IIR数字滤波器 3.设计FIR数字滤波器 1.设计IIR模拟高低通滤波器 wp = 2*pi*4000;ws = 2* ...

  6. matlab采样率为100hz,matlab自己设计一个低通滤波器,要求滤出100Hz之外的频率,采样率为10000Hz...

    clc;clear all; %归一化模拟切比雪夫I型低通滤波器的设计 Wp=2*pi*1000;Ws=2*pi*1500;rp=3;rs=30;%设计滤波器的参数 wp=1;ws=Ws/Wp; %频 ...

  7. 数字信号处理matlab设计滤波器

    目 录 1  设计目的.内容及要求 1 1.1 设计目的 1 1.2 设计内容 1 1.3 设计思考 2 1.4 设计要求 2 2 设计方案与设计原理 3 2.1 设计思路 3 2.2 采样定理 3 ...

  8. 基于fpga的fir滤波器设计,通过matlab代码设计滤波器参数,最终通过fpga实现

    基于fpga的fir滤波器设计,通过matlab代码设计滤波器参数,最终通过fpga实现,modelsim仿真,最后在开发板上实现,两路adc采集的掺杂高频信号经过低通滤波器之后,由dac输出,由si ...

  9. 使用MATLAB设计FIR低通滤波器

    ** 使用MATLAB设计FIR低通滤波器 ** 关于现代通信原理作业. https://blog.csdn.net/tanghonghanhaoli/article/details/10053358 ...

最新文章

  1. R语言ggplot2可视化:为箱图的均值进行连线、将多个分组的均值连接起来Joining means on a boxplot with a line
  2. sqlite3常用命令以及django如何操作sqlite3数据库
  3. java 统计文本行数_统计文本文件的行数,单词书,字节数
  4. 【ML】 李宏毅机器学习一:error
  5. 【289】◀▶ Python I/O 读写文本文件
  6. Dev控件使用CheckedListBoxControl获取items.count为0 的解决方法
  7. POSIX:可移植操作系统接口(Portable Operating System Interface of UNIX,缩写为 POSIX )
  8. ArcView,ArcGis,MapObjects,ISRI有什么区别
  9. 洛必达法则及极限问题总结
  10. Java基础语法面试题汇总
  11. 【实战项目惜时App项目总结分析】Vue-cli3+Vant UI+Vue-element-admin+Egg.js+Mysql
  12. Eclipse下载版本的选择
  13. php 多个一维数组合拼成二维数组的方法
  14. MySQL数据库视频教程之扛得住的MySQL数据库架构
  15. Java基础学习(2)---Java基础语法
  16. python外星人游戏制作
  17. Object detection at 200 Frames Per Second - 每秒 200 帧的目标检测
  18. 3DMaxs快速导出全景图
  19. 不管你学的是什么专业,你都应该多少懂些管理学的东西之【罗森塔尔效应】【虚假同感偏差】...
  20. Some problems were encountered while building the effective model for cn.itcast:travel:war:1.0-SNAPS

热门文章

  1. TC358743xbg是一颗将HDMI信号转换成MIPI CSI2的芯片
  2. MFC窗口置顶代码实现
  3. 以太网通讯 WINCC 通过 ModbusTCP 驱动连接
  4. p2p 了解资源整合
  5. 微信小程序AES解密失败
  6. my97DatePicker选择年、季度、月、周、日
  7. 构造函数 和 析构函数 能否抛出异常
  8. 汽车背后那些看不见的软件系统
  9. eclipse 配置C/C++开发环境
  10. IRIS(Incorporated Research Institutions for Seismology)常用功能介绍