unity中利用C#的Math.Net库进行FFT傅里叶变换和自定义滤波

unity中利用C#的Math.Net库进行FFT傅里叶变换和自定义滤波

研二实验室我需要研究运动平台的控制,其中需要在Unity中对虚拟载具的线加速度和角速度进行滤波,这其中花了不少时间,试了几个帖子的自己写的傅里叶变换代码,测试结果和标准还是有点区别,于是最后干脆采用了Math.Net库的方法,测试下来没有问题,和MatLab结果一致。总结下来,为了帮助别人少走弯路。
主要内容分两块:
1.安装Math.Net数学库并调用。
这一块很多帖子已经说得比较清晰,我引用一下前辈的帖子内容:
1.1在 Visual Studio 2015 中,打开 Tools -> Nuget Package Manager -> Package Manager Console。
1.2在 Package Manager Console 中输入如下命令:

Install-Package MathNet.Numerics

把上面的语句输入,然后按Enter
1.3然后会自动安装 Math.NET Numerics。安装成功后,需要找到这个dll,然后复制到unity 的asset目录的任意位置。
拖拽即可
1.4只要添加名称空间,就可以引用了。

using MathNet.Numerics.IntegralTransforms;//这里因为FFT属于积分变换领域,所以使用IntegralTransforms。

2.FFT傅里叶变换和自定义滤波
2.1这里我简单使用了一个符合理想滤波函数的数组,测试脚本如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using MathNet.Numerics.IntegralTransforms;
public class FFT : MonoBehaviour
{
    MathNet.Numerics.Complex32[] mathNetComplexArrRe = new MathNet.Numerics.Complex32[64];
    float[] data = new float[] { 0, 3, 2, 5, 3, -7, -6, -9, -5, -13, -12, -15, -13, 17, 6, 19, 10, 13, 22, 22, 3, 27, 36, 19, 25, 13, 52, 45, 33, 22, 6, 19, 0, 3, 2, 5, 3, -7, -6, -9, -5, -13, -12, -15, -13, 17, 6, 19, 10, 13, 22, 22, 3, 27, 36, 19, 25, 13, 52, 45, 33, 22, 6, 19 };
    float[] resultArr = new float[64];
    private void Start()
    {
        float[] filterArr = new float[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
        resultArr = Filter(data, filterArr);
    }
    /// <summary>
    /// 滤波数组
    /// </summary>
    /// <param name="inData">输入的数据</param>
    /// <param name="filterArr">滤波数组,可以自定义</param>
    /// <returns></returns>
    public float[] Filter(float[] inData, float[] filterArr)
    {
        float[] outArr = new float[64];
        outArr = inData;
        MathNet.Numerics.Complex32[] mathNetComplexArr = new MathNet.Numerics.Complex32[64];
        for (int i = 0; i < mathNetComplexArr.Length; i++)
        {
            mathNetComplexArr[i] = new MathNet.Numerics.Complex32((float)outArr[i], 0);
        }
        Fourier.Forward(mathNetComplexArr);//傅里叶变换
        for (int i = 0; i < mathNetComplexArr.Length; i++)
        {
            mathNetComplexArr[i] = new MathNet.Numerics.Complex32(mathNetComplexArr[i].Real * filterArr[i], mathNetComplexArr[i].Imaginary * filterArr[i]);
        }
        float[] ArrFreq = new float[64];
        for (int i = 0; i < ArrFreq.Length; i++)
        {
            ArrFreq[i] = Mathf.Sqrt(mathNetComplexArr[i].Imaginary * mathNetComplexArr[i].Imaginary + mathNetComplexArr[i].Real * mathNetComplexArr[i].Real);//利用LineRenderer显示频域结果
        }
        Fourier.Inverse(mathNetComplexArr);//逆傅里叶变换
        for (int i = 0; i < mathNetComplexArr.Length; i++)
        {
            outArr[i] = mathNetComplexArr[i].Real;
        }
        return outArr;
    }
}

2.2滤波结果我在unity中使用LineRenderer组件画下来,如下:
滤波效果
最后,欢迎大家评判指正。

引用的帖子包括:https://blog.csdn.net/qq_39395589/article/details/88625913

发布了2 篇原创文章 · 获赞 2 · 访问量 315

猜你喜欢

转载自blog.csdn.net/qq_23936433/article/details/103723349