频域特征提取的Python实现(频谱、功率谱、倒频谱)

MATLAB程序代码:

%========================================================================== 
%Desc:      以高斯信号为例,求解其频谱、双边功率谱、单边功率谱、双边功率谱密度、
%           单边功率谱密度,这里高斯信号的半波全宽FWHM=50ps,中心点位于2.5ns处。 
%=========================================================================
clc;
clear;
FWHM=50e-12;            %高斯信号FWHM宽度,为50ps
time_window=100*FWHM;   %高斯信号的采样窗口宽度,该值决定了傅里叶变换后的频率分辨率
Ns=2048;                %采样点
dt=time_window/(Ns-1);  %采样时间间隔
t=0:dt:time_window;     %采样时间
gauss_time=exp(-0.5*(2*sqrt(2*log(2))*(t-2.5e-9)/FWHM).^2); %高斯脉冲,中心位于2.5ns处。
plot(t*1e+9,gauss_time,'linewidth',2.5);
xlabel('Time/ns');
ylabel('Amplitude/V');
title('Gauss pulse');
%===========以下计算双边谱、双边功率谱、双边功率谱密度=================
gauss_spec=fftshift(fft(ifftshift(gauss_time)));    %傅里叶变换,并且进行fftshift移位操作。
gauss_spec=gauss_spec/Ns;   %求实际的幅度值;
df=1/time_window;               %频率分辨率
k=floor(-(Ns-1)/2:(Ns-1)/2);    
% k=0:Ns-1;
double_f=k*df;   %双边频谱对应的频点


figure; %幅度谱
plot(double_f*1e-9,abs(gauss_spec),'linewidth',2.5);
xlabel('Frequency/GHz');
ylabel('Amplitude/V');
title('double Amplitude spectrum');


figure; %相位谱
plot(double_f*1e-9,angle(gauss_spec),'linewidth',2.5);
xlabel('Frequency/GHz');
ylabel('Phase/rad');
title('double Phase spectrum');


figure; %功率谱
double_power_spec_W=abs(gauss_spec).^2;                 %双边功率谱,单位W;
double_power_spec_mW=double_power_spec_W*1e+3;          %双边功率谱,单位mW;
double_power_spec_dBm=10*log10(double_power_spec_mW);   %双边功率谱,单位dBm;
plot(double_f*1e-9,double_power_spec_dBm,'linewidth',2.5);
xlabel('Frequency/GHz');
ylabel('Power/dBm');
title('double Power spectrum');


figure; %功率谱密度
double_power_specD_W=abs(gauss_spec).^2/(df);       %双边功率谱密度,单位W/Hz
double_power_specD_mW=double_power_specD_W*1e+3;    %双边功率谱密度,单位mW/Hz
double_power_specD_dBm=10*log10(double_power_specD_mW);%双边功率谱密度,单位dBm/Hz
plot(double_f*1e-9,double_power_specD_dBm,'linewidth',2.5);
xlabel('Frequency/GHz');
ylabel('Power/(dBm/Hz)');
title('double power spectrum Density');


%==========以下计算单边谱、单边功率谱及单边功率谱密度=========
gauss_spec=fft(ifftshift(gauss_time));  %计算单边谱无需fftshift
gauss_spec=gauss_spec/Ns;       %计算真实的幅度值
single_gauss_spec=gauss_spec(1:floor(Ns/2));
single_f=(0:floor(Ns/2)-1)*df;


figure; %幅度谱
plot(single_f*1e-9,abs(single_gauss_spec),'linewidth',2.5);
xlabel('Frequency/GHz');
ylabel('Amplitude/V');
title('single Amplitude spectrum');


figure; %相位谱
plot(single_f*1e-9,angle(single_gauss_spec),'linewidth',2.5);
xlabel('Frequency/GHz');
ylabel('Phase/rad');
title('single Phase spectrum');


figure;%功率谱
double_power_spec_W=abs(gauss_spec).^2;  
single_power_spec_W=2*double_power_spec_W(1:floor(Ns/2));   %单边功率谱,单位W
single_power_spec_mW=single_power_spec_W*1e+3;              %单边功率谱,单位mW;
single_power_spec_dBm=10*log10(single_power_spec_mW);       %双边功率谱,单位dBm;
plot(single_f*1e-9,single_power_spec_dBm,'linewidth',2.5);  
xlabel('Frequency/GHz');
ylabel('Power/dBm');
title('single Power spectrum');


figure;%功率谱密度
double_power_specD_W=abs(gauss_spec).^2/(df);
single_power_specD_W=2*double_power_specD_W(1:floor(Ns/2));         %单边功率谱密度,单位W/Hz
single_power_specD_mW=single_power_specD_W*1e+3;                    %单边功率谱密度,单位mW/Hz
single_power_specD_dBm=10*log10(single_power_specD_mW);             %单边功率谱密度,单位dBm/Hz
plot(single_f*1e-9,single_power_specD_mW,'linewidth',2.5);
xlabel('Frequency/GHz');
ylabel('Power/(dBm/Hz)');
title('single power spectrum density');

python 代码

频谱

from scipy.fftpack import fft, fftshift, ifft
from scipy.fftpack import fftfreq
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline

t_s = 0.01
t_start = 0.5
t_end = 5
t = np.arange(t_start, t_end, t_s)

f0 = 5
f1 = 20

# generate the orignal signal
y = 1.5*np.sin(2*np.pi*f0*t) + 3*np.sin(2*np.pi*20*t) + np.random.randn(t.size)

# fft
Y = fft(y)

# fftshift
shift_Y = fftshift(Y)

# the positive part of fft, get from fft
pos_Y_from_fft = Y[:Y.size//2]

# the positive part of fft, get from shift fft
pos_Y_from_shift = shift_Y[shift_Y.size//2:]

# plot the figures
plt.figure(figsize=(10, 12))

plt.subplot(511)
plt.plot(y)

plt.subplot(512)
plt.plot(np.abs(Y))

plt.subplot(513)
plt.plot(np.abs(shift_Y))

plt.subplot(514)
plt.plot(np.abs(pos_Y_from_fft))

plt.subplot(515)
plt.plot(np.abs(pos_Y_from_shift))
plt.show()

功率谱

fs = 1000
num_fft = 1024;

# generate original signal
t = np.arange(0, 1, 1/fs)
f0 = 100
f1 = 200
x = np.cos(2*np.pi*f0*t) + 3*np.cos(2*np.pi*f1*t) + np.random.randn(t.size)

# FFT
Y = fft(x, num_fft)
Y = np.abs(Y)

# power spectrum
ps = Y**2 / num_fft

# power spectrum using correlate
cor_x = np.correlate(x, x, 'same')
cor_X = fft(cor_x, num_fft)
ps_cor = np.abs(cor_X)
ps_cor = ps_cor / np.max(ps_cor)


plt.figure(figsize=(15, 12))
plt.subplot(511)
plt.plot(x)

plt.subplot(512)
plt.plot(20*np.log10(Y[:num_fft//2]))

plt.subplot(513)
plt.plot(20*np.log10(ps[:num_fft//2]))

plt.subplot(514)
plt.plot(20*np.log10(ps_cor[:num_fft//2]))

plt.show()

倒频谱

fs = 1000
num_fft = 1024
t = np.arange(0, 5, 1/fs)
y1 = 10*np.cos(2*np.pi*5*t) + 7*np.cos(2*np.pi*10*t) + 5*np.cos(2*np.pi*20*t) + np.random.randn(t.size)
y2 = 20*np.cos(2*np.pi*50*t) + 15*np.cos(2*np.pi*100*t) + 25*np.cos(2*np.pi*200*t) + np.random.randn(t.size)
y = y1*y2

Y1 = fft(y1, num_fft)
Y1 = np.abs(Y1)

Y2 = fft(y2, num_fft)
Y2 = np.abs(Y2)

Y = fft(y, num_fft)
Y = np.abs(Y)

spectrum = np.fft.fft(y, n=num_fft)
ceps = np.fft.ifft(np.log(np.abs(spectrum))).real


plt.figure(figsize=(20, 12))
plt.subplot(331)
plt.plot(y1)

plt.subplot(332)
plt.plot(y2)

plt.subplot(333)
plt.plot(y)

plt.subplot(334)
plt.plot(Y1[:num_fft//2])

plt.subplot(335)
plt.plot(Y2[:num_fft//2])

plt.subplot(336)
plt.plot(Y[:num_fft//2])

plt.show()

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ljtyxl

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值