当前位置:网站首页>C# 实现 FFT 正反变换 和 频域滤波
C# 实现 FFT 正反变换 和 频域滤波
2022-07-04 14:54:00 【全栈程序员站长】
要进行FFT运算首先要构造复数类,参考
http://blog.csdn.net/iamoyjj/archive/2009/05/15/4190089.aspx
下面的程序在依赖上述复数类的基础上实现了FFT正反变换算法和频域滤波算法,另外由于一般如果是对实数进行FFT的话,要将FFT得到的复数数组转为实数数组,下面类中的Cmp2Mdl方法的作用就是这个。这个FFT算法是基-2FFT算法,因此,如入的序列必须是2的n次方个点长。
频域滤波的基本原理是:
1、 对输入序列进行FFT
2、 得到的频谱乘以一个权函数(滤波器,系统的传递函数)
3、 得到的结果进行IFFT
4、 如果是实数运算的话用Cmp2Mdl方法转为实数
代码如下:
/// <summary>
/// 频率分析器
/// </summary>
public static class FreqAnalyzer
{
/// <summary>
/// 求复数complex数组的模modul数组
/// </summary>
/// <param name=”input”>复数数组</param>
/// <returns>模数组</returns>
public static double[] Cmp2Mdl(Complex[] input)
{
///有输入数组的长度确定输出数组的长度
double[] output = new double[input.Length];
///对所有输入复数求模
for (int i = 0; i < input.Length; i++)
{
if (input[i].Real > 0)
{
output[i] = -input[i].ToModul();
}
else
{
output[i] = input[i].ToModul();
}
}
///返回模数组
return output;
}
/// <summary>
/// 傅立叶变换或反变换,递归实现多级蝶形运算
/// 作为反变换输出需要再除以序列的长度
/// !注意:输入此类的序列长度必须是2^n
/// </summary>
/// <param name=”input”>输入实序列</param>
/// <param name=”invert”>false=正变换,true=反变换</param>
/// <returns>傅立叶变换或反变换后的序列</returns>
public static Complex[] FFT(double[] input, bool invert)
{
///由输入序列确定输出序列的长度
Complex[] output = new Complex[input.Length];
///将输入的实数转为复数
for (int i = 0; i < input.Length; i++)
{
output[i] = new Complex(input[i]);
}
///返回FFT或IFFT后的序列
return output = FFT(output, invert);
}
/// <summary>
/// 傅立叶变换或反变换,递归实现多级蝶形运算
/// 作为反变换输出需要再除以序列的长度
/// !注意:输入此类的序列长度必须是2^n
/// </summary>
/// <param name=”input”>复数输入序列</param>
/// <param name=”invert”>false=正变换,true=反变换</param>
/// <returns>傅立叶变换或反变换后的序列</returns>
private static Complex[] FFT(Complex[] input, bool invert)
{
///输入序列只有一个元素,输出这个元素并返回
if (input.Length == 1)
{
return new Complex[] { input[0] };
}
///输入序列的长度
int length = input.Length;
///输入序列的长度的一半
int half = length / 2;
///有输入序列的长度确定输出序列的长度
Complex[] output = new Complex[length];
///正变换旋转因子的基数
double fac = -2.0 * Math.PI / length;
///反变换旋转因子的基数是正变换的相反数
if (invert)
{
fac = -fac;
}
///序列中下标为偶数的点
Complex[] evens = new Complex[half];
for (int i = 0; i < half; i++)
{
evens[i] = input[2 * i];
}
///求偶数点FFT或IFFT的结果,递归实现多级蝶形运算
Complex[] evenResult = FFT(evens, invert);
///序列中下标为奇数的点
Complex[] odds = new Complex[half];
for (int i = 0; i < half; i++)
{
odds[i] = input[2 * i + 1];
}
///求偶数点FFT或IFFT的结果,递归实现多级蝶形运算
Complex[] oddResult = FFT(odds, invert);
for (int k = 0; k < half; k++)
{
///旋转因子
double fack = fac * k;
///进行蝶形运算
Complex oddPart = oddResult[k] * new Complex(Math.Cos(fack), Math.Sin(fack));
output[k] = evenResult[k] + oddPart;
output[k + half] = evenResult[k] – oddPart;
}
///返回FFT或IFFT的结果
return output;
}
/// <summary>
/// 频域滤波器
/// </summary>
/// <param name=”data”>待滤波的数据</param>
/// <param name=”Nc”>滤波器截止波数</param>
/// <param name=”Hd”>滤波器的权函数</param>
/// <returns>滤波后的数据</returns>
private static double[] FreqFilter(double[] data, int Nc, Complex[] Hd)
{
///最高波数==数据长度
int N = data.Length;
///输入数据进行FFT
Complex[] fData = FreqAnalyzer.FFT(data, false);
///频域滤波
for (int i = 0; i < N; i++)
{
fData[i] = Hd[i] * fData[i];
}
///滤波后数据计算IFFT
///!未除以数据长度
fData = FreqAnalyzer.FFT(fData, true);
///复数转成模
data = FreqAnalyzer.Cmp2Mdl(fData);
///除以数据长度
for (int i = 0; i < N; i++)
{
data[i] = -data[i] / N;
}
///返回滤波后的数据
return data;
}
}
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/110913.html原文链接:https://javaforall.cn
边栏推荐
- Using celery in projects
- Accounting regulations and professional ethics [7]
- Market trend report, technical innovation and market forecast of taillight components in China
- How to decrypt worksheet protection password in Excel file
- Vscode setting outline shortcut keys to improve efficiency
- 对人胜率84%,DeepMind AI首次在西洋陆军棋中达到人类专家水平
- Research Report on market supply and demand and strategy of surgical stapler industry in China
- How was MP3 born?
- Some fields of the crawler that should be output in Chinese are output as none
- The four most common errors when using pytorch
猜你喜欢
What should ABAP do when it calls a third-party API and encounters garbled code?
AI system content recommendation issue 24
Model fusion -- stacking principle and Implementation
嵌入式软件架构设计-函数调用
[native JS] optimized text rotation effect
[North Asia data recovery] a database data recovery case where the partition where the database is located is unrecognized due to the RAID disk failure of HP DL380 server
[tutorial] yolov5_ DeepSort_ The whole process of pytoch target tracking and detection
Blood cases caused by Lombok use
~89 deformation translation
error: ‘connect‘ was not declared in this scope connect(timer, SIGNAL(timeout()), this, SLOT(up
随机推荐
Software Engineer vs Hardware Engineer
[hcie TAC] question 5 - 1
Statistical learning: logistic regression and cross entropy loss (pytoch Implementation)
Digital recognition system based on OpenCV
Unity script API - transform transform
Research Report on market supply and demand and strategy of tetramethylpyrazine industry in China
[Previous line repeated 995 more times]RecursionError: maximum recursion depth exceeded
《吐血整理》保姆级系列教程-玩转Fiddler抓包教程(2)-初识Fiddler让你理性认识一下
Nine CIO trends and priorities in 2022
Some fields of the crawler that should be output in Chinese are output as none
Intranet penetrating FRP: hidden communication tunnel technology
Review of Weibo hot search in 2021 and analysis of hot search in the beginning of the year
Stew in disorder
Opencv learning -- geometric transformation of image processing
嵌入式软件架构设计-函数调用
Big God explains open source buff gain strategy live broadcast
I let the database lock the table! Almost fired!
Understand asp Net core - Authentication Based on jwtbearer
Socks agent tools earthworm, ssoks
Unity script API - component component