当前位置:网站首页>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
边栏推荐
- Rearrange array
- Practice: fabric user certificate revocation operation process
- Change the mouse pointer on ngclick - change the mouse pointer on ngclick
- TypeError: list indices must be integers or slices, not str
- [North Asia data recovery] a database data recovery case where the disk on which the database is located is unrecognized due to the RAID disk failure of HP DL380 server
- Common API day03 of unity script
- Intranet penetrating FRP: hidden communication tunnel technology
- Object distance measurement of stereo vision
- Game theory
- How to save the contents of div as an image- How to save the contents of a div as a image?
猜你喜欢
~88 running people practice
Penetration test --- database security: detailed explanation of SQL injection into database principle
165 webmaster online toolbox website source code / hare online tool system v2.2.7 Chinese version
Dry goods | fMRI standard reporting guidelines are fresh, come and increase your knowledge
Opencv learning -- geometric transformation of image processing
时钟轮在 RPC 中的应用
Talking about Net core how to use efcore to inject multiple instances of a context annotation type for connecting to the master-slave database
Common API day03 of unity script
MySQL learning notes - data type (2)
Understand Alibaba cloud's secret weapon "dragon architecture" in the article "science popularization talent"
随机推荐
Expression #1 of ORDER BY clause is not in SELECT list, references column ‘d.dept_ no‘ which is not i
Unity script API - time class
Understand asp Net core - Authentication Based on jwtbearer
How to save the contents of div as an image- How to save the contents of a div as a image?
一图看懂ThreadLocal
Blood cases caused by Lombok use
2021 Google vulnerability reward program review
Daily notes~
The 17 year growth route of Zhang Liang, an open source person, can only be adhered to if he loves it
Vscode prompt Please install clang or check configuration 'clang executable‘
DC-2靶场搭建及渗透实战详细过程(DC靶场系列)
Proxifier global agent software, which provides cross platform port forwarding and agent functions
Anta is actually a technology company? These operations fool netizens
China Indonesia adhesive market trend report, technological innovation and market forecast
对人胜率84%,DeepMind AI首次在西洋陆军棋中达到人类专家水平
Hidden communication tunnel technology: intranet penetration tool NPS
Some fields of the crawler that should be output in Chinese are output as none
Research Report of exoskeleton robot industry - market status analysis and development prospect prediction
Accounting regulations and professional ethics [10]
Understand Alibaba cloud's secret weapon "dragon architecture" in the article "science popularization talent"