【Delphi】如何在三轴加速器的频谱分析中使用FFT(快速傅里叶变换)算法

关于傅里叶变换的作用,网上说的太过学术化,且都在说原理,已经如何编码实现,可能很多人有个模糊影响,在人工智能,图像识别,运动分析,机器学习等中,频谱分析成为了必备的手段,可将离散信号量转换为数字信息进行归类分析。

今天这里将的不是如何实现,而是如何使用傅里叶变换

但频谱分析中,涉及到的信号处理知识对大部分软件开发的人来说,太过于晦涩难懂,傅里叶变换,拉普拉斯,卷积,模相,实数,虚数,复数,三角函数等等,已经能让软件工程师望而却步,造成懂知识的人无法开发,懂开发的人无法分析,而同时具备两种技能的人,除了专业的研究生博士,剩下的少之又少。

站在软件开发人员的角度,能否抛开这些晦涩难懂概念,进行纯软件方面的信号处理?这个问题可能没有答案,最好能够通过实践来证明。而且若是抛开这些概念,让那些有兴趣的开发人员学习到信号处理,频谱分析,先不管可不可能,光想想,其作用也是有的,至少“高深”的东西能够被用上了。

三轴加速器步数计算分析

下面就以三轴加速器的实际应用开发为例,来讲一讲(限于个人水平,可能比较粗略)。

试下运动APP也有不少,不少APP开发人员就会接触到陀螺仪,加速器等,利用这些传感器进行行为分析,首先需要获取传感器的数据,将获取的数据输出到平面坐标图表中:

在上图中,采集频率为50Hz,即X轴每一个点为50分之1秒,可以看到前4秒(0-200)没有太明显走动,4秒后到12秒走动速度较慢,12秒走路稍微加快。在这里不得不感叹人脑简直是宇宙超级无敌,光看图表就能够直接知道行为,无法想象未来谁能够让人工智能能够超越人脑。

在软件开发中,我们要如何通过代码分析得到上面“人脑的分析结果“? 要直接上代码不是我的作风,百度可以搜到一篇腾讯的文章《利用三轴加速器的计步测算方法》,此文章的分析方法可以说大致能够理解,涉及到的计算方法却语焉不详,比如,在没有进行滤波前,上图的X轴波峰波谷并不平滑,可以看出每个大波峰上又有2个小波谷,如果以此来计算,得出来的步数误差非常大。

可能一些做过信号处理的人会说,做一个均值滚动滤波+低通滤波+高通滤波就差不多了,我只能说对于复杂的周期性信号分析是可行的,对于三轴加速器的步数计算来说,实际中并不存在什么周期性信号,人的上坡下坡走路非直线,时快时慢等动作都会加大分析难度。

先不说这么多了,拿到信号原始数据,马上进行傅里叶变换,Delphi可以使用FPC一个开源的库AlgLib,最新版好像不开源了且分为免费版和收费版,但codetyphon收录了以前的开源版本可以用。

alglib中关于快速傅里叶变换是在u_fft.pp文件中,delphi只把后缀pp改成pas就可以使用了。使用FFTC1D函数进行变换,其中N即为采集的数据量,当然实际中我们有时候采集了几十秒,而N的最佳范围是在128-2048范围(既充分又计算量不高),所以我们每10秒(50Hz即500个数据)进行一次傅里叶变换分析即可。

FFTC1D函数函数的调用方法

比如采集到的数据为[3.4,  4.1, 6.7, 3.1...],则如下代码:

var
  A : TComplex1DArray;
  I, N : Integer;
begin
   N := 50*10 // 10秒
   SetLength(A, N);
   for I:=0 to N-1 do
   begin
      A[I].X:=I;  //即时域的刻度
      A[I].Y:=Data[nIdx]; //填上采集的数据
   end;
   FFTC1D(A);

   //////////////////////////
   // 到这里已经完成傅里叶变换,如何使用变换后的数据??
end;

  

这里先引用百科上的一段话来帮助理解下面代码:

假设FFT之后某点n用复数a+bi表示,
那么这个复数的模就是An=根号a*a+b*b,
相位就是Pn=atan2(b,a)。
根据以上的结果,就可以计算出n点(n≠1,且n<=N/2)对应的信号的表达式为:An/(N/2)*cos(2*pi*Fn*t+Pn),即2*An/N*cos(2*pi*Fn*t+Pn)。
对于n=1点的信号,是直流分量,幅度即为A1/N。

由于FFT结果的对称性,通常我们只使用前半部分的结果,即小于采样频率一半的结果。

经过变换后的复数数组A,即是变换结果,但并不是分析的数据,而是一个中间数据,由该数据可以得到模值和相位,根据傅里叶变换原理,模值计算如下:

// 对A数组每个点的复数求模,即实部和虚部平方和再开根号。
nAValue := Math.Power(Abs(A[I].X*A[I].X)+Abs(A[I].Y*A[I].Y), 0.5);

  至于相位则是根据公式Pn=atan2(b,a)计算,但是频谱分析比较有用的是模值(主要是滤波),所以其他不管,当然幅度也有一定作用。

前面讲到使用10秒的数据进行计算,这样得到的傅里叶变换结果复数也有500个,由于傅里叶的对称性,我们只取0-250的结果来计算模值即可,因为251-500是对称的结果。

计算模值后再输出平面坐标图表,如下:

如上图,各种傅里叶变换文章中的结果图就出来了(请忽略图中的时间刻度与文章的10秒500个数据等相关性,因为我用的图是随便一段数据来的。)

看到上面的傅里叶变换结果图,会不会觉得悲剧才开始发生。没错,结果是出来了,但我们该如何分析呢?

如何分析傅里叶变换结果

原文地址:https://www.cnblogs.com/caibirdy1985/p/9896617.html

时间: 2024-10-13 22:51:29

【Delphi】如何在三轴加速器的频谱分析中使用FFT(快速傅里叶变换)算法的相关文章

陀螺仪以及三轴陀螺仪和六轴陀螺仪的区别_六轴陀螺仪和九轴陀螺仪的区别

来源:电子发烧友 链接:http://www.elecfans.com/article/88/142/2017/20171201590857.html 陀螺仪,是一种用来感测与维持方向的装置,基於角动量不灭的理论设计出来的.陀螺仪主要是由一个位於轴心可以旋转的轮子构成. 陀螺仪一旦开始旋转,由於轮子的角动量,陀螺仪有抗拒方向改变的趋向.陀螺仪多用於导航.定位等系统. 1850年法国的物理学家福柯(J.Foucault)为了研究地球自转,首先发现高速转动中的转子(rotor),由于惯性作用它的旋转

张高兴的 Windows 10 IoT 开发笔记:三轴数字罗盘 HMC5883L

原文:张高兴的 Windows 10 IoT 开发笔记:三轴数字罗盘 HMC5883L 注意,数据不包含校验,准确的来说我不知道怎么校验,但方向看起来差不多是对的... GitHub:https://github.com/ZhangGaoxing/windows-iot-demo/tree/master/HMC5883L

基于STM32的三轴数字罗盘HMC5883L模块的测试

最近买了个数字罗盘模块,调通后发现很不错,非常灵敏,测试的时候精度在1°以内.连续测量模式下,最快测量.输出速率可达75hz,模块每次测量完毕并将数据更新至寄存器后,其DRDY引脚便产生一个低电平脉冲(可以配置一个外部中断捕获DRDY引脚的下降沿,并在中断服务程序中读取数据),在STM32中可以设置一个下降沿触发的外部中断,并在中断服务程序中调用角度数据读取函数.以下为操作该模块的主要步骤. 一.IIC协议相关操作(单片机作为主机控制时钟线) 宏定义: //这里用到了STM32的位带区操作,方便

三轴加速度传感器原理及应用

三轴加速度传感器原理 目前的加速度传感器有多种实现方式,主要可分为压电式.电容式及热感应式三种,这三种技术各有其优缺点.以电容式3轴加速度计的技术原理为例.电容式加速度计能够感测不同方向的加速度或振动等运动状况.其主要为利用硅的机械性质设计出的可移动机构:由于加速度使得机械悬臂与两个电极之间的距离发生变化,从而改变了两个电容的参数.通过集成的开关电容放大电路量测电容参数的变化,形成了与加速度成正比的电压输出.因此3轴加速度传感器必然包含一个单纯的机械性MEMS传感器和一枚ASIC接口芯片两部分,

android 三轴加速度传感器【转】

一.手机中常用的传感器 在Android2.3 gingerbread系统中,google提供了11种传感器供应用层使用,具体如下:(Sensor类) #define SENSOR_TYPE_ACCELEROMETER 1 //加速度#define SENSOR_TYPE_MAGNETIC_FIELD 2 //磁力#define SENSOR_TYPE_ORIENTATION 3 //方向#define SENSOR_TYPE_GYROSCOPE 4 //陀螺仪#define SENSOR_TY

Arduino I2C + 三轴加速度计ADXL345

ADXL345是ADI公司生产的三轴数字加速度计芯片,与ST的LIS3DH功能接近.主要特性有: 工作电压:2.0 ~ 3.6V 功耗:待机功耗0.1μA:工作时与数据输出频率(ODR)有关,如ODR<10 Hz时30μA 接口:I2C:三线/四线制SPI 分辨率:可选择,最大13-bit 内置FIFO single tap/double tap检测 自由落体检测 两个可编程中断输出脚 封装:3 x 5 x 1 mm LGA 管脚定义 与Arduino的连接 用工作于3.3V/8MHz版本的Ar

【翻译】利用加速度求解位置的算法——三轴传感器

摘要 此文档描述并使用MMA7260QT三轴加速计和低功耗的9S08QG8八位单片机实现求解位置的算法 . 在今天先进的电子市场,有不少增加了许多特性和智能的多功能的产品.定位和游戏只是得益于获取到的位置信息的一部分市场.一个获取这种信息的可选方案是通过使用惯性传感器.从这些传感器中取得的信号需要进行一些处理,因为在加速度和位置之间没有一种直接转换. 为了获得位置,需要对加速度进行二次积分.本文介绍一种简单的算法实现加速度的二重积分.为了获取加速度的二重积分,一个简单的积分要进行两次,因为这样也

我的嵌入式Qt开发第一课——基于BBB和hmc5843三轴电子罗盘

几次想照着课本系统地学习Qt,但我发现还是有详细问题驱动时学习比較快. 于是我给自己设定了这个任务: 读取HMC5843的三轴磁场强度值,计算出角度,并把角度用直观形式显示在图形界面上. 这里面涉及到一些问题,接下来就用问答的形式记录一下. Q1: 搭建Ubuntu-BBB的Qt交叉编译环境.配置触摸屏: A1: http://blog.csdn.net/wyt2013/article/details/18549415 Q2: 去掉Qt界面的标题栏 A2: 在mainwindow.cpp中Mai

Atmega16驱动三轴加速度传感器MMA7455

最近做一个设计G-Sense的设备,需要一个三轴加速度传感器,最终选择飞思卡尔的MMA7455,因为看起来似乎比博士的三轴加速度芯片简单一些,哈哈.原本是准备应用在ARM上的,首先在比较熟悉的AVR单片机的环境下做个测试. 来个MMA7455模块的近照: 考虑到7455工作在3.3V,所以用宽电压工作的Atmega16L,这样就不存在电压冲突的问题.电路图参考7455的Datasheet: 在这里,中断INT1和INT2我都没有用,ACC_CS接3.3采用I2C模式,IADDR0接3.3,设置7