一阶低通滤波和一阶高通滤波的C++实现

【转自】阳光下的奔跑_FC

傅立叶变换,拉普拉斯变换和Z变换

对于信号分析而言,傅立叶变换是必不可少的,我们都知道傅立叶变换是把系统从时域变换到频域进行分析,那么拉普拉斯变换和Z变换是干什么的?简单的来说,由于傅里叶变换的收敛有一个狄利克雷条件,要求信号绝对可积/绝对可和。对于那些不符合狄利克雷条件的信号该怎么办呢,我们将频域的概念扩展到复频域.首先要说明的是傅立叶变换大致有两种,连续时间的傅立叶变换(CTFT)和离散的傅立叶变换(DTFT).而对于CTFT而言,拉普拉斯变换就是将连续时间系统的傅立叶变换扩展了;而对于DTFT而言,Z变换就是将离散时间系统的傅立叶变换扩展了.知乎上有一个很好的对三种变换的解释:傅立叶变换、拉普拉斯变换、Z变换的联系


RC一阶低通滤波器的算法推导

一阶的RC电路如下:
这里写图片描述
这里直接给出其s域的传递函数:

VoutVin=1RCs+1,(s=jω)VoutVin=1RCs+1,(s=jω)

这与px4代码的lib库中低通滤波是一样的:

float BlockLowPass::update(float input)
{
    if (!PX4_ISFINITE(getState())) {
        setState(input);
    }

    float b = 2 * float(M_PI) * getFCut() * getDt();
    float a = b / (1 + b);
    setState(a * input + (1 - a)*getState());//input:本次采样值 getState():上次滤波值
    return getState();
}


 
 

一阶RC高通滤波器

RC高通滤波器原理图如下,它和低通相反,电阻两端的电压作为输出,则其s域的传递函数为:

VoutVin=RCsRCs+1VoutVin=RCsRCs+1

zz

这与px4中的高通滤波是一样的:


float BlockHighPass::update(float input)
{
    float b = 2 * float(M_PI) * getFCut() * getDt();
    float a = 1 / (1 + b);
    setY(a * (getY() + input - getU()));//getY():上次滤波器输出值;getU():上次滤波器输入值
    setU(input);
    return getY();
}

这里写图片描述


总结

关于低通滤波和高通滤波,最关键的是学到了三类变换的关系以及离散化的方法,留下各位大佬的博客链接在此:
【滤波器学习笔记】一阶RC低通滤波
傅立叶变换、拉普拉斯变换、Z变换的联系
基础电路—RC组成的低通、高通滤波器
双线性变换
z变换

以下是C++编写代码实现空域平滑、空域锐化、高斯低通滤波、高斯高通滤波、巴特沃斯低通滤波和巴特沃斯高通滤波的功能的例子: 1. 空域平滑(均值滤波) ```cpp #include <opencv2/opencv.hpp> using namespace cv; int main() { Mat image = imread("input.jpg"); Mat smoothed; blur(image, smoothed, Size(3, 3)); imshow("Smoothed Image", smoothed); waitKey(0); return 0; } ``` 2. 空域锐化(拉普拉斯滤波) ```cpp #include <opencv2/opencv.hpp> using namespace cv; int main() { Mat image = imread("input.jpg"); Mat sharpened; Mat blurred; GaussianBlur(image, blurred, Size(3, 3), 0); addWeighted(image, 1.5, blurred, -0.5, 0, sharpened); imshow("Sharpened Image", sharpened); waitKey(0); return 0; } ``` 3. 高斯低通滤波 ```cpp #include <opencv2/opencv.hpp> using namespace cv; int main() { Mat image = imread("input.jpg"); Mat filtered; GaussianBlur(image, filtered, Size(3, 3), 0); imshow("Filtered Image", filtered); waitKey(0); return 0; } ``` 4. 高斯高通滤波 ```cpp #include <opencv2/opencv.hpp> using namespace cv; int main() { Mat image = imread("input.jpg"); Mat filtered; Mat blurred; GaussianBlur(image, blurred, Size(3, 3), 0); subtract(image, blurred, filtered); imshow("Filtered Image", filtered); waitKey(0); return 0; } ``` 5. 巴特沃斯低通滤波 ```cpp #include <opencv2/opencv.hpp> using namespace cv; int main() { Mat image = imread("input.jpg"); Mat filtered; Mat padded; int dft_M = getOptimalDFTSize(image.rows); int dft_N = getOptimalDFTSize(image.cols); copyMakeBorder(image, padded, 0, dft_M - image.rows, 0, dft_N - image.cols, BORDER_CONSTANT, Scalar::all(0)); Mat planes[] = {Mat_<float>(padded), Mat::zeros(padded.size(), CV_32F)}; Mat complexI; merge(planes, 2, complexI); dft(complexI, complexI); float cutoff_frequency = 30.0; float order = 2.0; float d0 = cutoff_frequency * dft_M / 100.0; for (int i = 0; i < complexI.rows; i++) { for (int j = 0; j < complexI.cols; j++) { float d = sqrt(pow(i - complexI.rows / 2, 2) + pow(j - complexI.cols / 2, 2)); float h = 1.0 / (1.0 + pow(d / d0, 2 * order)); complexI.at<Vec2f>(i, j)[0] *= h; complexI.at<Vec2f>(i, j)[1] *= h; } } idft(complexI, filtered, DFT_SCALE | DFT_REAL_OUTPUT); filtered = filtered(Rect(0, 0, image.cols, image.rows)); imshow("Filtered Image", filtered); waitKey(0); return 0; } ``` 6. 巴特沃斯高通滤波 ```cpp #include <opencv2/opencv.hpp> using namespace cv; int main() { Mat image = imread("input.jpg"); Mat filtered; Mat padded; int dft_M = getOptimalDFTSize(image.rows); int dft_N = getOptimalDFTSize(image.cols); copyMakeBorder(image, padded, 0, dft_M - image.rows, 0, dft_N - image.cols, BORDER_CONSTANT, Scalar::all(0)); Mat planes[] = {Mat_<float>(padded), Mat::zeros(padded.size(), CV_32F)}; Mat complexI; merge(planes, 2, complexI); dft(complexI, complexI); float cutoff_frequency = 30.0; float order = 2.0; float d0 = cutoff_frequency * dft_M / 100.0; for (int i = 0; i < complexI.rows; i++) { for (int j = 0; j < complexI.cols; j++) { float d = sqrt(pow(i - complexI.rows / 2, 2) + pow(j - complexI.cols / 2, 2)); float h = 1.0 / (1.0 + pow(d0 / d, 2 * order)); complexI.at<Vec2f>(i, j)[0] *= h; complexI.at<Vec2f>(i, j)[1] *= h; } } idft(complexI, filtered, DFT_SCALE | DFT_REAL_OUTPUT); filtered = filtered(Rect(0, 0, image.cols, image.rows)); imshow("Filtered Image", filtered); waitKey(0); return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值