振动分析-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.rhkb.cn/news/352242.html

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

相关文章

configure: error: library ‘crypto‘ is required for OpenSSL

1、执行命令&#xff1a;./configure --prefix/opt/app/postgresql --with-openssl 报错&#xff1a; 2、解决办法 执行命令&#xff1a;yum install openssl-devel 重新执行 ./configure --prefix/opt/app/postgresql --with-openssl

Springboot 开发之任务调度框架(一)Quartz 简介

一、引言 常见的定时任务框架有 Quartz、elastic-job、xxl-job等等&#xff0c;本文主要介绍 Spirng Boot 集成 Quartz 定时任务框架。 二、Quartz 简介 Quartz 是一个功能强大且灵活的开源作业调度库&#xff0c;广泛用于 Java 应用中。它允许开发者创建复杂的调度任务&…

C++ 03 之 命名空间

game_kun.cpp #include "game_kun.h"void kun::atk() {cout << "吃鸡的攻击"<< endl; } game_lol.cpp #include "game_lol.h"void lol::atk() {cout << "lol的攻击"<< endl; } game_kun.h #include <…

Linux驱动开发-01配置开发环境

一、配置网络环境 使用桥接网卡时 Ubuntu 就是使用一个真实的网卡 &#xff1a;开发板的网线也连接到这个真实的网卡上&#xff0c;这样 Windows 、 Ubuntu 、开发板就都可以用过这个网卡互通了。 NAT 网卡&#xff1a; Ubuntu 通过它上网&#xff0c;只要 Windows 能上网&…

电商客服的得力助手:快捷回复软件

随着技术的进步&#xff0c;传统的人工打字已经逐渐不能满足快节奏的电商服务需求。如今&#xff0c;市面上涌现出众多快捷回复辅助软件&#xff0c;它们以高效率的特点&#xff0c;成为电商客服人员的必备工具。 作为一名拥有五年经验的电商客服&#xff0c;我深刻体会到了这类…

使用 cx_Oracle 在 Oracle 中等待记录并执行操作

问题背景&#xff1a; 在第一个 Python 项目中&#xff0c;需要等待记录被插入 Oracle 表中&#xff0c;一旦记录存在&#xff0c;就调用 Python 函数。目前使用 cx_Oracle 库&#xff0c;采用一种无限循环的方式来查询表。如果记录存在&#xff0c;就调用函数&#xff0c;然后…

【leetcode刷题】面试经典150题 , 27. 移除元素

leetcode刷题 面试经典150 27. 移除元素 难度&#xff1a;简单 文章目录 一、题目内容二、自己实现代码2.1 方法一&#xff1a;直接硬找2.1.1 实现思路2.1.2 实现代码2.1.3 结果分析 2.2 方法二&#xff1a;排序整体删除再补充2.1.1 实现思路2.1.2 实现代码2.1.3 结果分析 三、…

如何修改倍福CX7000PLC IP地址

我们可以通过登录网页修改PLC的IP地址,这个需要我们知道PLC的初始IP地址,倍福常用学习网址如下: 课程: EPC 产品概要 | 倍福虚拟学院https://tr.beckhoff.com.cn/course/view.php?id=19#section-31、浏览器直接输入PLC 的IP地址 2、点击修改按钮(就是那个旋转) 修改IP地…

【图像分割】DSNet: A Novel Way to Use Atrous Convolutions in Semantic Segmentation

DSNet: A Novel Way to Use Atrous Convolutions in Semantic Segmentation 论文链接&#xff1a;http://arxiv.org/abs/2406.03702 代码链接&#xff1a;https://github.com/takaniwa/DSNet 一、摘要 重新审视了现代卷积神经网络&#xff08;CNNs&#xff09;中的atrous卷积…

针对微电网中可时移,柔性,基础负荷的电价响应模型---代码解析

前言&#xff1a; 在上两篇帖子中&#xff0c;讲解了我对于粒子群算法的理解&#xff0c;站在巨人的肩膀上去回望&#xff1a;科研前辈们确实非常牛逼&#xff0c;所以它才成为了非常经典的算法。这篇帖子主要是想分享一下&#xff0c;对于微电网、电力系统的论文中&#xff0c…

“深入探讨Redis主从复制:原理、配置与优化“

目录 # 概念 1. 配置主从同步步骤 1.1 创建文件夹 1.2 复制配置文件 1.3 配置文件关闭 1.4 查看端口号&#xff0c;发现端口号存在 1.5 连接三个端口号 1.6 查看主机运行情况 1.7 让服务器变成&#xff08;主机&#xff09;或&#xff08;从机&#xff09; 1.8 实现效…

CSS选择符和可继承属性

属性选择符&#xff1a; 示例&#xff1a;a[target"_blank"] { text-decoration: none; }&#xff08;选择所有target"_blank"的<a>元素&#xff09; /* 选择所有具有class属性的h1元素 */ h1[class] { color: silver; } /* 选择所有具有hre…

志愿服务管理系统的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;管理员管理&#xff0c;基础数据管理&#xff0c;广场论坛管理&#xff0c;志愿活动管理&#xff0c;活动报名管理 前台账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;志愿活动&a…

单片机(STM32)与上位机传输浮点数

目录 单片机(STM32)与上位机传输数据的方法1. 传输整形数据2. 传输浮点数据3. 如何打包与解包 单片机(STM32)与上位机传输数据的方法 在进行单片机程序的开发时&#xff0c;常常需要与其他设备进行通信。一种情况是与其他电路板通信&#xff0c;比如STM32主机与STM32从机通信&…

YOLOv10项目-服务器上运行

1、前言 2、运行YOLOv10代码流程&#xff08;超详细&#xff09; &#xff08;3&#xff09;根据下面步骤安装&#xff1a; &#xff08;4&#xff09;数据集和其他配置 &#xff08;5&#xff09;测试训练&#xff08;很详细&#xff09; 1、前言 由于一些事情&#xff0…

2024中国应急(消防)品牌巡展成都站成功召开!

汇聚品牌力量&#xff0c;共同相聚成都。6月14日&#xff0c;由中国安全产业协会指导&#xff0c;中国安全产业协会应急创新分会、应急救援产业网联合主办&#xff0c;四川省消防协会协办的“一切为了安全”2024年中国应急(消防)品牌巡展-成都站成功举办。该巡展旨在展示中国应…

英特尔 “AI” 科通:英特尔AI大模型应用前瞻

亲爱的科技探险家、前沿探索者、对未来深具好奇心的您&#xff0c; 身处人工智能引领的时代&#xff0c;我们目睹着行业的革命性变革。技术的创新不仅改变着我们的日常&#xff0c;更重新定义着我们对未来的期许。今天&#xff0c;怀着无限激情和期待&#xff0c;我们邀请您参…

MySQL之优化服务器设置和复制(一)

优化服务器设置 操作系统状态 CPU密集型的机器 CPU密集型服务器的vmstat输出通常在us列会有一个很高的值&#xff0c;报告了花费在非内核代码上的CPU时钟;也可能在sy列有很高的值&#xff0c;表示系统CPU利用率&#xff0c;超过20%就足以令人不安了。在大部分情况下&#xff…

Web应用安全测试-防护功能缺失

Web应用安全测试-防护功能缺失 1、Cookie属性问题 漏洞描述&#xff1a; Cookie属性缺乏相关的安全属性&#xff0c;如Secure属性、HttpOnly属性、Domain属性、Path属性、Expires属性等。 测试方法&#xff1a; 通过用web扫描工具进行对网站的扫描&#xff0c;如果存在相关…

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

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