振动分析-3-基于Python的FFT幅值修正与能量修正

幅值修正与能量修正过程(更正)
参考什么是泄漏?
参考什么是窗函数?
参考使用python实现快速傅里叶变换(FFT)
参考频谱泄露和窗函数以及加窗后幅度修正和python代码实现

1 快速傅里叶变换(FFT)

离散傅里叶变换(discrete Fourier transform) 傅里叶分析方法是信号分析的最基本方法,傅里叶变换是傅里叶分析的核心,通过它把信号从时间域变换到频率域,进而研究信号的频谱结构和变化规律。但是它的致命缺点是:计算量太大,时间复杂度太高,当采样点数太高的时候,计算缓慢,由此出现了DFT的快速实现,即下面的快速傅里叶变换FFT。

快速傅里叶变换(FFT),计算量更小的离散傅里叶的一种实现方法。

1.1 原始信号

考虑一个有效值为1V,频率为20Hz的正弦波,如图1所示。
振幅A=np.sqrt(2)=1.414
正弦信号基础知识
y = A * sin(wt + b)
其中y是正弦信号
A是正弦信号的振幅
wt+b 为正弦信号的相位
w为角频率
频率f = w/2pi, w= 2pi*f

Fs = 1000  # 采样频率
f = 20  # 信号频率
A = np.sqrt(2) # 振幅,对应有效值为1V
t = np.linspace(0, 1, Fs)  # 生成 1s 的时间序列
y = A * np.sin(2 * np.pi * f * t)  # 给定信号
import matplotlib.pyplot as plt
plt.title('original data')
plt.plot(t, y)
plt.xlabel('time/s')
plt.ylabel('Amplitude/V')
plt.show()

在这里插入图片描述
相当于知道采样频率Fs,一段时长为1s的信号,根据fft得到信号的频率

1.2 scipy.fftpack.fft

快速傅里叶变换
scipy.fftpack.fft(x, n=None, axis=-1, overwrite_x=False)
其中n: 整数,可选,傅里叶变换的长度。如果n < x.shape[axis],x被截断。如果n > x.shape[axis],x是零填充的。默认结果是n = x.shape[axis]。

from scipy.fftpack import fft
fft_y=fft(y)  #快速傅里叶变换
print(len(fft_y))  # 与原始信号相同长度
print(fft_y[:2])  # [6.19504448e-14-0.j 2.22183652e-04-0.07072302j]

发现以下几个特点:
(1)变换之后的结果数据长度和原始采样信号是一样的。
(2)每一个变换之后的值是一个复数,为a+bj的形式,那这个复数是什么意思呢?
复数a+bj在坐标系中表示为(a,b),故而复数具有模和角度,我们都知道快速傅里叶变换具有“振幅谱”和“相位谱”,它其实就是通过对快速傅里叶变换得到的复数结果进一步求出来的,
那这个直接变换后的结果就是我需要的,在FFT中,得到的结果是复数,
(3)FFT得到的复数的模(即绝对值)就是对应的“振幅谱”,复数所对应的角度,就是所对应的“相位谱”,现在可以画图了。

1.3 FFT的原始频谱

N=len(fft_y)  # 频率个数 
x = np.arange(N)* Fs/N 
abs_y=np.abs(fft_y) # 取复数的绝对值,即复数的模(双边频谱)
angle_y=np.angle(fft_y)  #取复数的角度 import matplotlib.pyplot as plt
# 设置字体
plt.rcParams['font.family'] = 'Microsoft YaHei'
plt.subplot(1,2,1)
plt.plot(x,abs_y)   
plt.title('双边振幅谱(未归一化)') 
plt.subplot(1,2,2)
plt.plot(x,angle_y)   
plt.title('双边相位谱(未归一化)')
plt.show()

在这里插入图片描述

注意:我们在此处仅仅考虑“振幅谱”,不再考虑相位谱。
我们发现,振幅谱的纵坐标很大,而且具有对称性,这是怎么一回事呢?
关键:关于振幅值很大的解释以及解决办法——归一化和取一半处理。

比如有一个信号如下:
Y=A1+A2cos(2πω2+φ2)+A3cos(2πω3+φ3)+A4*cos(2πω4+φ4)
经过FFT之后,得到的“振幅图”中,
第一个峰值(频率位置)的模是A1的N倍,N为采样点,本例中为N=1000,此例中没有,因为信号没有常数项A1。
第二个峰值(频率位置)的模是A2的N/2倍,N为采样点,
第三个峰值(频率位置)的模是A3的N/2倍,N为采样点,
第四个峰值(频率位置)的模是A4的N/2倍,N为采样点,
依次下去…
考虑到数量级较大,一般进行归一化处理,既然大部分峰值是A的N/2倍,那么将每一个值都除以N/2即可
FFT具有对称性,一般只需要用N的一半,前半部分即可。

1.4 振幅谱归一化

norm_y=abs_y/(N/2) #归一化处理(双边频谱)
plt.plot(x,norm_y,'g')
plt.title('双边频谱(归一化)',fontsize=9,color='green')
plt.show()

在这里插入图片描述
现在我们发现,振幅谱的数量级不大了,变得合理了。

1.5 取一半处理

half_x = x[range(int(N/2))]  #取一半区间
norm_half_y = norm_y[range(int(N/2))] #由于对称性,只取一半区间(单边频谱)
plt.plot(half_x,norm_half_y,'b')
plt.title('单边频谱(归一化)',fontsize=9,color='blue')
plt.show()

在这里插入图片描述

1.6 整理成一个函数my_fft()

from scipy.fftpack import fft
def my_fft(y,Fs):fft_y=fft(y)  #快速傅里叶变换N=len(fft_y)  # 频率个数 x = np.arange(N) * Fs/N  abs_y=np.abs(fft_y) # 取复数的绝对值,即复数的模(双边频谱)norm_y=abs_y/(N/2) #归一化处理(双边频谱)half_x = x[range(int(N/2))]  #取一半区间norm_half_y = norm_y[range(int(N/2))] #由于对称性,只取一半区间(单边频谱)return half_x,norm_half_y

2 加窗

2.1 频谱泄露

统一窗函数(uniform)
汉宁窗(Hanning)
海明窗(Hamming)
布莱克窗(Blackman)
平顶窗(Flattop)
凯撒窗或凯撒贝塞尔窗(Kaiser-Bessel)
输入的数据(即“信号”)可能是周期的,也可能是非周期的。周期信号容易处理,可以将截断的长度就放在一个完整周期长度左右,这样就可以从FFT的结果里获得相应的频率信息。但是针对非周期信号,简单的截断会给FFT的计算带来一个问题,频谱泄露
在这里插入图片描述

频率泄露是指原本在输入频率的幅值会被降低,而不存在于输入信号中的频率点会有幅值存在,从幅频图上“形象”的认为,分析结果从已存在频率“泄露”到了不存在的频率点上。图,红色是没有频率泄露时,绿色是存在频率泄露时。

FFT过程认为将被运算的数据无限幅值延拓后,就是原信号。所以如果截断是基于信号的周期是不会有频率泄露的,因为延拓后的信号确实等于原信号。但是如果截断的数据是非周期的,延拓后不等于原信号,则频率泄露是实际发生的。这种非周期的情况,既可以是用非周期的长度截取了周期信号,也可以是信号本身就是非周期的,二者均会发生频率泄露。解决此问题的方案是加窗,尤其是非周期信号,加窗是必须项

加窗,简单来说,是用特殊的函数来截断数据,使得数据和函数相乘后,其结果为周期化的,减少频率泄露。常见的窗函数有以下几种。其中Uniform窗,即是简单截断,汉宁窗为比较常用的窗函数。

在这里插入图片描述

2.2 加窗FFT

from scipy.fftpack import fft
def my_fft(y,Fs):fft_y=fft(y)  #快速傅里叶变换N=len(fft_y)  # 频率个数 x = np.arange(N) * Fs/N  abs_y=np.abs(fft_y) # 取复数的绝对值,即复数的模(双边频谱)norm_y=abs_y/(N/2) #归一化处理(双边频谱)half_x = x[range(int(N/2))]  #取一半区间norm_half_y = norm_y[range(int(N/2))] #由于对称性,只取一半区间(单边频谱)return half_x,norm_half_y# window = np.hanning(len(y))  # 汉宁窗函数,幅值修正因子为2
window = np.hamming(len(y))  # 海明窗函数,幅值修正因子为1.85
window_y = y*window  # 对信号进行窗口加权
x1,y1 = my_fft(window_y,Fs)
plt.plot(x1,y1*1.85,'b')
plt.title('单边频谱(归一化)',fontsize=9,color='blue')
plt.xlabel('Frequency/Hz')
plt.ylabel('Amplitude/V')
plt.show()

在这里插入图片描述

3 频谱泄露和窗函数

针对一个频率为20Hz的正玄信号,使用1000Hz的采样频率进行采样,采集10个周期的数据。

from scipy.fftpack import fft
# 设置字体
plt.rcParams['font.family'] = 'Microsoft YaHei'
def my_fft(y,Fs):fft_y=fft(y)  #快速傅里叶变换N=len(fft_y)  # 频率个数 x = np.arange(N)*Fs/N abs_y=np.abs(fft_y) # 取复数的绝对值,即复数的模(双边频谱)norm_y=abs_y/(N/2) #归一化处理(双边频谱)half_x = x[range(int(N/2))]  #取一半区间norm_half_y = norm_y[range(int(N/2))] #由于对称性,只取一半区间(单边频谱)return half_x,norm_half_y

3.1 周期性截断

构建一个首尾可以相接周期截断的信号。

import numpy as np
import matplotlib.pyplot as plt
fs = 1000 # 采样频率,对应周期0.001s
t_interval = 1 / fs  # 频率分辨率fin = 100 # 信号频率20Hz,对应周期0.05s
n_period = 10
sample_N = int(fs / fin * 10)  # 采样点数
t = np.arange(0, sample_N * t_interval, t_interval)xn = np.sqrt(2) * np.sin(2 * np.pi * fin * t)  # 原始信号
x1,y1 = my_fft(xn,fs)  # fftplt.subplot(1,2,1)
plt.plot(t, xn)
plt.xlabel('time/s')
plt.ylabel('Amplitude/V')plt.subplot(1,2,2)
plt.plot(x1,y1,'b')
plt.title('单边频谱(归一化)',fontsize=9,color='blue')
plt.xlabel('Frequency/Hz')
plt.ylabel('Amplitude/V')
plt.show()

在这里插入图片描述

3.2 非周期截断

import numpy as np
import matplotlib.pyplot as plt
fs = 1000 # 采样频率,对应周期0.001s
t_interval = 1 / fs  # 频率分辨率fin = 50 # 信号频率20Hz,对应周期0.05s
n_period = 10
sample_N = int(fs / fin * 10) # 采样点数t = np.arange(0, (sample_N - 15) * t_interval, t_interval)
xn = np.sqrt(2) * np.sin(2 * np.pi * fin * t)  # 原始信号
x1,y1 = my_fft(xn,fs)  # fftplt.subplot(1,2,1)
plt.plot(t, xn)
plt.xlabel('time/s')
plt.ylabel('Amplitude/V')plt.subplot(1,2,2)
plt.plot(x1,y1,'b')
plt.title('单边频谱(归一化)',fontsize=9,color='blue')
plt.xlabel('Frequency/Hz')
plt.ylabel('Amplitude/V')
plt.show()

在这里插入图片描述

频谱泄露是由于对信号的非周期性截断所导致。

3.3 加窗处理

from scipy.fftpack import fft
# 设置字体
plt.rcParams['font.family'] = 'Microsoft YaHei'
def my_fft_window(y,Fs):window = np.hanning(len(y))  # 汉宁窗函数,幅值修正因子为2window_y = y*window  # 对信号进行窗口加权fft_y=fft(window_y)  #快速傅里叶变换N=len(fft_y)  # 频率个数 x = np.arange(N)*Fs/N abs_y=np.abs(fft_y)*2 # 取复数的绝对值,即复数的模(双边频谱)norm_y=abs_y/(N/2) #归一化处理(双边频谱)half_x = x[range(int(N/2))]  #取一半区间norm_half_y = norm_y[range(int(N/2))] #由于对称性,只取一半区间(单边频谱)return half_x,norm_half_yx1,y1 = my_fft_window(xn,fs)  # fft
plt.subplot(1,2,1)
plt.plot(t, xn)
plt.xlabel('time/s')
plt.ylabel('Amplitude/V')plt.subplot(1,2,2)
plt.plot(x1,y1,'b')
plt.title('单边频谱(归一化)',fontsize=9,color='blue')
plt.xlabel('Frequency/Hz')
plt.ylabel('Amplitude/V')
plt.show()

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/854466.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

84. 柱状图中最大的矩形(hard)

单调栈&#xff1a; 就是说&#xff1a;固定高度&#xff0c;寻找最长宽度&#xff0c;如何找最长宽度&#xff0c;需要从heights[i] 这一个元素开始向左向右两边寻找heights[j] <heights[i]的j元素&#xff0c;也就是找两边第一小于heights[i]的元素。此过程中就是利用到单…

java面试(企业场景)

设计模式 工厂方法模式 简单工厂模式 简单工厂包括以下角色&#xff1a; 抽象产品&#xff1a;定义了产品的规范&#xff0c;描述了产品的主要特性和功能具体产品&#xff1a;实现或者继承抽象产品的子类具体工厂&#xff1a;提供了创建产品的机会&#xff0c;调用者通过该…

【C++进阶学习】第二弹——继承(下)——挖掘继承深处的奥秘

继承&#xff08;上&#xff09;&#xff1a;【C进阶学习】第一弹——继承&#xff08;上&#xff09;——探索代码复用的乐趣-CSDN博客 前言&#xff1a; 在前面我们已经讲了继承的基础知识&#xff0c;让大家了解了一下继承是什么&#xff0c;但那些都不是重点&#xff0c;今…

企业内部、与合作伙伴/客户文档协作如何高效安全地收集资料?

在企业的日常运营与对外合作中&#xff0c;「文件收集」是一项特别常见的文档协作需求。例如&#xff0c;公司举办项目经验分享大会&#xff0c;组织者需要提前收集演讲者的材料&#xff1b;新项目启动时&#xff0c;项目经理需要快速收集技术方案和报价方案以便招投标和商务活…

大型Web应用的模块化与组织实践:Flask Blueprints深入解析

目录 一、引言 二、Flask Blueprints概述 三、Flask Blueprints的使用 创建Blueprint对象 定义路由和视图函数 注册Blueprint 使用Blueprints组织代码 四、案例分析 创建模块目录结构 创建Blueprint对象 注册Blueprint 五、代码示例与最佳实践 1. 代码示例 …

一行代码实现鼠标横向滚动

&#x1f9d1;‍&#x1f4bb; 写在开头 点赞 收藏 学会&#x1f923;&#x1f923;&#x1f923; 在项目中我们可能会遇到当鼠标在某个区域内&#xff0c;我们希望滚动鼠标里面的内容可以横向滚动&#xff1b; 比如我们一些常见的后台状态栏&#xff1a; 那这种该怎么写&…

【Linux 12】进程控制

文章目录 &#x1f308; Ⅰ 进程创建01. fork 函数介绍02. 写时拷贝03. fork 常规用法04. fork 调用失败的原因 &#x1f308; Ⅱ 进程终止01. 进程退出场景02. 常见退出方法 &#x1f308; Ⅲ 进程等待01. 进程等待必要性02. 进程等待的方法2.1 wait 方法2.2 waitpid 方法 03.…

关于禁止word的无用插入模式

这是我的word版本号 点击左上角文件选项 找到左侧最下方的选项 点击高级 把这两个叉掉

第二十篇——去除噪音:如何获得更多更准确的信息?

目录 一、背景介绍二、思路&方案三、过程1.思维导图2.文章中经典的句子理解3.学习之后对于投资市场的理解4.通过这篇文章结合我知道的东西我能想到什么&#xff1f; 四、总结五、升华 一、背景介绍 噪音的原理&#xff0c;换一个维度来看就会很清晰了&#xff1b;通俗易懂…

element-ui将组件默认语言改为中文

在main.js中加入以下代码即可 // 引入 Element Plus 及其样式 import ElementPlus from element-plus import element-plus/dist/index.css// 引入中文语言包 import zhCn from element-plus/es/locale/lang/zh-cn// 使用 Element Plus 并设置语言为中文 app.use(ElementPlus,…

04 远程访问及控制

1、SSH远程管理 SSH是一种安全通道协议&#xff0c;主要用来实现字符界面的远程登录、远程复制等功能。 SSH协议对通信双方的数据传输进行了加密处理&#xff08;包括用户登陆时输入得用户口令&#xff09;。 终端&#xff1a;接收用户的指令 TTY终端不能远程&#xff0c;它…

数据预处理之基于预测的(线性,ARIMA)异常值检测#matlab

基于密度的LOF异常值检测可见上篇文章。以下介绍基于预测的异常值检测&#xff1a; 1.基于预测的异常值检测方法 基于预测的异常值检测方法&#xff0c;特别是结合线性回归和ARIMA&#xff08;自回归积分滑动平均模型&#xff09;模型&#xff0c;是数据分析中常用的技术。这…

【自动驾驶】ROS小车系统介绍

文章目录 小车组成轮式运动底盘的组成轮式运动底盘的分类轮式机器人的控制方式感知传感器ROS决策主控ROS介绍ROS的坐标系ROS的单位机器人电气连接变压模块运动底盘的电气连接ROS主控与传感器的电气连接运动底盘基本组成电池电机控制器与驱动器控制器与运动底盘状态数据&#xf…

深度学习 --- stanford cs231学习笔记四(神经网络的几大重要组成部分)

训练神经网络1 1&#xff0c;激活函数&#xff08;activation functions&#xff09; 激活函数是神经网络之于线性分类器的最大进步&#xff0c;最大贡献&#xff0c;即&#xff0c;引入了非线性。 1&#xff0c;1 Sigmoid sigmoid函数的性质&#xff1a; 结合指数函数的图像可…

OpenGL3.3_C++_Windows(12)

demo演示 demo演示 模板stencil测试 OpenGL颜色缓冲区是用于存储渲染图像的颜色数据的内存区域&#xff0c;在每个新的渲染迭代&#xff0c;我们都将屏幕颜色清理glClearColor&#xff08;&#xff09;为我们指定的颜色&#xff0c;然后同时清除glClear()颜色缓冲区&#xff0…

《骑行健身:“柳叶刀”研究揭示的健康与经济双赢策略》

在这个物价飞涨、经济压力日益加重的时代&#xff0c;普通人如何在不增加额外负担的情况下提升生活质量&#xff1f;《柳叶刀》的最新研究为我们揭开了一个意想不到的秘密&#xff1a;坚持健身&#xff0c;尤其是骑行&#xff0c;竟等同于每年为自己赚取了一笔不小的财富。这一…

C++链表相关内容温习回顾——移除链表元素

本文主要对之前学过的C链表相关内容进行温习回顾&#xff0c;并以 移除链表元素 为例&#xff0c;进行应用。 关于链表的基础理论可见&#xff1a;链表理论基础 应用示例&#xff1a;LeetCode 203 移除链表元素 https://leetcode.cn/problems/remove-linked-list-elements/ 0、…

旋转的六边形

【题目描述】 输入一个整数n&#xff0c;绘制出n个不断旋转的六边形&#xff0c;如图1所示。 图1 旋转的六边形图形 【要求】 -绘制速度设为最快&#xff0c;画笔粗细为3。 -六边形每次旋转10度&#xff0c;边长增加10%。 【分析】 这是一个同心正六边&#xff0c;六边形边…

spring:深入理解@EnableAspectJAutoProxy

Hi~&#xff01;这里是奋斗的小羊&#xff0c;很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~~ &#x1f4a5;&#x1f4a5;个人主页&#xff1a;奋斗的小羊 &#x1f4a5;&#x1f4a5;所属专栏&#xff1a;C语言 &#x1f680;本系列文章为个人学习…

Airtest 使用指南

Airtest 介绍 准备工作 AirtestIDE 安装与启动: https://airtest.doc.io.netease.com/IDEdocs/getting_started/AirtestIDE_install/ 电脑端的准备工作完成后,对于手机端只需要打开允许USB调试,当首次运行时会提示安装PocoService,同意即可。 界面介绍