Python实战:用NumPy和Matplotlib实现FFT频谱分析(附完整代码)

FFT实战:用Python手把手教你实现音频频谱分析(附完整代码) 本文通过Python实战,手把手教你实现音频频谱分析。详细讲解了如何利用快速傅立叶变换将时域音频信号转换为频域频谱,并介绍了窗函数、短时傅里叶变换等关键技巧,以及如何通过逆快速傅立叶变换进行音频滤波等应用。附完整代码,助你掌握信号处理核心技能。 阅读详情

Python实战:用NumPy和Matplotlib实现FFT频谱分析(附完整代码)

你是否曾经面对一段音频波形、一组传感器数据,或者任何随时间变化的信号,感到无从下手?那些看似杂乱无章的波动背后,往往隐藏着决定性的规律——频率。在数字信号处理的世界里,快速傅里叶变换(FFT)就是一把打开这扇大门的万能钥匙。它能够将时间域的信号“翻译”成频率域的语言,让我们清晰地看到构成复杂信号的各个频率成分及其强度。对于数据分析师、算法工程师,甚至是硬件开发者而言,掌握FFT的实战应用,就如同掌握了一门洞察数据本质的“内功心法”。

今天,我们不打算深陷于复杂的数学公式推导,而是直接切入Python编程的实战场景。我们将手把手地,从零开始,使用NumPy和Matplotlib这两个强大的库,构建一个完整的FFT频谱分析流程。无论你是刚刚接触信号处理的初学者,还是希望快速将理论转化为代码的实践者,这篇文章都将为你提供可直接运行、可修改、可扩展的代码范例和清晰的思路。我们将从生成一个模拟信号开始,一步步完成FFT计算、结果解读,并最终实现专业级的可视化图表,让你在实战中真正理解频谱分析的魅力。

1. 环境准备与核心库概览

在开始编码之前,确保你的Python环境已经就绪。我强烈建议使用Anaconda来管理环境,它能避免很多依赖库的冲突问题。当然,使用纯净的Python配合pip安装也是完全可行的。

首先,我们需要安装两个核心库:NumPy 和 Matplotlib。如果你使用pip,打开终端或命令提示符,执行以下命令:

pip install numpy matplotlib

对于追求更佳绘图效果和交互体验的用户,也可以考虑安装seaborn库来美化图表,但这并非必需:

pip install seaborn

现在,让我们快速认识一下今天的主角:

  • NumPy:Python科学计算的基石。它提供了高效的多维数组对象ndarray,以及一系列用于数组操作的函数。在FFT分析中,我们几乎所有的数学运算——从信号生成到复数计算——都将依赖它。其numpy.fft模块封装了高效的FFT算法实现,是我们今天工作的核心引擎。
  • Matplotlib:Python绘图库的“事实标准”。我们将主要使用其pyplot子模块(通常别名为plt)来创建各种静态、交互式的图表,将计算得到的频谱数据直观地呈现出来。

一个常见的误区是认为FFT分析非常复杂,需要自己实现算法。实际上,得益于NumPy等成熟库,我们只需调用几个函数即可完成核心计算,从而将精力集中在信号的理解和结果的分析上。下面是一个最简单的导入代码块,我们后续的所有代码都将基于此:

import numpy as np
import matplotlib.pyplot as plt

# 为了在Jupyter Notebook中直接显示图表,可以取消下面这行的注释
# %matplotlib inline

print("NumPy版本:", np.__version__)
print("Matplotlib版本:", plt.matplotlib.__version__)

运行这段代码,如果没有报错并成功打印出版本号,那么恭喜你,环境已经准备就绪。

2. 构建你的第一个测试信号

在进行频谱分析之前,我们首先需要一个分析对象——信号。直接从真实世界采集的数据(如音频、振动)往往包含噪声和复杂的成分,不利于初学者理解。因此,我们从一个完全由自己控制的“纯净”合成信号开始。这能让我们清晰地验证FFT分析的正确性。

一个最经典的合成信号是多个正弦波的叠加。正弦波是频率成分最单一的信号,多个不同频率、不同幅度的正弦波叠加,就能模拟出许多复杂信号的特性。

假设我们想模拟一个采样频率为1000 Hz(即每秒采集1000个数据点),持续时间为1秒的信号。其中包含两个主要的频率成分:一个强力的50 Hz信号和一个稍弱的120 Hz信号。此外,为了模拟真实环境,我们还可以加入一点随机噪声。以下是生成该信号的代码:

# 信号参数设置
fs = 1000               # 采样频率 (Hz)
T = 1                   # 信号总时长 (秒)
N = int(fs * T)         # 总采样点数
t = np.linspace(0, T, N, endpoint=False) # 时间轴,不包含终点以避免重复

# 信号的频率成分
freq1 = 50    # 第一个频率成分 (Hz)
amp1 = 0.7    # 第一个频率的振幅
freq2 = 120   # 第二个频率成分 (Hz)
amp2 = 0.3    # 第二个频率的振幅

# 生成纯净的合成信号
signal_pure = amp1 * np.sin(2 * np.pi * freq1 * t) + amp2 * np.sin(2 * np.pi * freq2 * t)

# 添加一些高斯白噪声,模拟真实情况
noise_amplitude = 0.05
noise = noise_amplitude * np.random.randn(N)
signal_noisy = signal_pure + noise

# 可视化原始信号
fig, axes = plt.subplots(2, 1, figsize=(10, 6))

# 绘制纯净信号
axes[0].plot(t, signal_pure, linewidth=1.0, color='blue', alpha=0.7)
axes[0].set_title('纯净合成信号 (50Hz & 120Hz)')
axes[0].set_xlabel('时间 [秒]')
axes[0].set_ylabel('振幅')
axes[0].grid(True, linestyle='--', alpha=0.5)
axes[0].set_xlim(0, 0.1)  # 只看前0.1秒,细节更清晰

# 绘制含噪信号
axes[1].plot(t, signal_noisy, linewidth=1.0, color='red', alpha=0.7)
axes[1].set_title('含噪声的合成信号')
axes[1].set_xlabel('时间 [秒]')
axes[1].set_ylabel('振幅')
axes[1].grid(True, linestyle='--', alpha=0.5)
axes[1].set_xlim(0, 0.1)

plt.tight_layout()
plt.show()

运行这段代码,你会看到两个并排的子图,分别展示了纯净信号和加噪信号在前0.1秒内的波形。即使加入了噪声,你依然能看出信号周期性波动的“轮廓”。这个时域波形图告诉我们信号如何随时间变化,但它无法直接告诉我们信号由哪些频率组成。这就是我们需要FFT的原因。

提示:采样频率fs的选择至关重要。根据奈奎斯特采样定理,要无失真地还原一个信号,采样频率必须大于信号中最高频率成分的两倍。在我们的例子中,最高频率是120Hz,因此fs=1000Hz是绰绰有余的。如果fs设置过低,会导致高频成分“混叠”到低频中,造成分析错误。

3. 执行FFT计算与频谱解读

有了信号数据,接下来就是施展FFT魔法的时刻。使用NumPy进行FFT计算异常简单,核心函数就是np.fft.fft()。但是,理解其输入输出背后的意义,才是正确解读结果的关键。

3.1 执行FFT计算

我们直接对上一节生成的signal_noisy进行分析。

# 对含噪信号执行FFT
fft_values = np.fft.fft(signal_noisy)

# 计算对应的频率轴
n = len(signal_noisy) # 信号长度
freqs = np.fft.fftfreq(n, d=1/fs) # d是采样间隔,等于1/fs

# 取单边频谱(因为频谱是关于0Hz对称的)
half_n = n // 2
fft_magnitude = np.abs(fft_values[:half_n]) * 2 / n # 求幅度,并归一化
single_sided_freqs = freqs[:half_n]

短短几行代码,计算就完成了。我们来拆解一下:

  1. np.fft.fft(signal_noisy):返回一个复数数组,长度与输入信号n相同。每个复数对应一个频率分量的信息,包含了该分量的幅度和相位。
  2. np.fft.fftfreq(n, d=1/fs):生成一个与FFT结果对应的频率数组。其范围从-fs/2到+fs/2(实际上略小于)。参数d是采样时间间隔。
  3. 由于实数信号的频谱是共轭对称的(即负频率部分是正频率部分的镜像),我们通常只关心正频率部分(从0Hz到fs/2)。half_n = n // 2取得了正频率部分的索引。
  4. np.abs(fft_values)计算复数的模,即该频率分量的幅度。* 2 / n是一个常见的归一化操作,使得频谱图中幅度的刻度与实际信号振幅相匹配(对于除直流分量外的频率)。直流分量(0Hz)通常需要单独处理。

3.2 关键概念与结果解读

FFT的输出直接看是难以理解的。下表总结了几个核心概念,帮助你建立直观认识:

概念解释在代码中的体现注意事项
频率分辨率频谱图上相邻频率点之间的间隔。它决定了你能区分多近的两个频率。df = fs / n信号总时长T越长(n越大),分辨率df越小,频谱越精细。
奈奎斯特频率能够被无混叠分析的最高频率,等于采样频率fs的一半。f_nyquist = fs / 2所有高于此频率的信号成分都会“折叠”回来,造成混叠失真。
幅度谱各频率分量振幅的大小。是我们最常观察的频谱图。np.abs(fft_values)反映了该频率成分对原始信号“能量”的贡献大小。
相位谱各频率分量在时间轴上的起始位置。np.angle(fft_values)在需要重建信号或分析信号间时序关系时非常重要。
频谱泄漏由于信号长度有限(非整数个周期),导致能量“泄漏”到旁瓣频率的现象。表现为主峰周围有拖尾。可通过加窗函数(如汉宁窗)来抑制。

现在,让我们可视化幅度谱,看看能否从中找到我们预设的50Hz和120Hz。

# 绘制幅度频谱图
plt.figure(figsize=(12, 5))

# 绘制线性坐标下的频谱
plt.subplot(1, 2, 1)
plt.plot(single_sided_freqs, fft_magnitude, color='green', linewidth=1.5)
plt.axvline(x=freq1, color='blue', linestyle='--', alpha=0.7, label=f'{freq1} Hz')
plt.axvline(x=freq2, color='red', linestyle='--', alpha=0.7, label=f'{freq2} Hz')
plt.title('幅度频谱 (线性坐标)')
plt.xlabel('频率 [Hz]')
plt.ylabel('幅度')
plt.xlim(0, 200) # 聚焦在0-200Hz范围
plt.legend()
plt.grid(True, linestyle='--', alpha=0.5)

# 绘制对数坐标下的频谱(更能看清小信号)
plt.subplot(1, 2, 2)
plt.plot(single_sided_freqs, 20 * np.log10(fft_magnitude + 1e-10), color='purple', linewidth=1.5) # 加极小值避免log(0)
plt.axvline(x=freq1, color='blue', linestyle='--', alpha=0.7, label=f'{freq1} Hz')
plt.axvline(x=freq2, color='red', linestyle='--', alpha=0.7, label=f'{freq2} Hz')
plt.title('幅度频谱 (对数坐标,单位: dB)')
plt.xlabel('频率 [Hz]')
plt.ylabel('幅度 [dB]')
plt.xlim(0, 200)
plt.legend()
plt.grid(True, linestyle='--', alpha=0.5)

plt.tight_layout()
plt.show()

在这张图中,你应该能清晰地看到在两个虚线标记的位置(50Hz和120Hz),出现了尖锐的谱峰。它们的幅度比例大约为0.7:0.3,与我们生成信号时设定的振幅比例相符。对数坐标图将幅度转换成了分贝(dB),这使得较小的频率成分(如我们添加的噪声)也变得可见,噪声在整个频带内呈现为一条抬高的“基底”。

4. 高级技巧与实战问题处理

掌握了基础分析后,我们面对真实数据时总会遇到各种挑战。这一节,我们将探讨几个提升分析质量的关键技巧。

4.1 使用窗函数抑制频谱泄漏

前面我们提到过频谱泄漏。当你分析的信号片段不是其周期的整数倍时,就会发生泄漏。这会导致本应集中在一个频率点上的能量,扩散到周围的频率上,使谱峰变宽、旁边出现虚假的旁瓣,影响频率识别和幅度测量的准确性。

加窗是抑制泄漏的标准方法。窗函数在时域上与信号相乘,使信号的起始和结束平滑地过渡到零,从而减少截断带来的突变。常用的窗函数有汉宁窗(Hanning)、汉明窗(Hamming)、布莱克曼窗(Blackman)等。

# 生成一个非整数周期的信号,演示泄漏
freq_leak = 50.5  # 非整数周期频率
t_leak = np.linspace(0, 1, fs, endpoint=False)
signal_leak = np.sin(2 * np.pi * freq_leak * t_leak)

# 应用汉宁窗
window = np.hanning(len(signal_leak))
signal_windowed = signal_leak * window

# 计算加窗前后的FFT
fft_raw = np.fft.fft(signal_leak)
fft_win = np.fft.fft(signal_windowed)
freqs = np.fft.fftfreq(len(signal_leak), d=1/fs)
half = len(signal_leak)//2

# 可视化对比
fig, axes = plt.subplots(2, 2, figsize=(12, 8))

# 时域信号对比
axes[0, 0].plot(t_leak[:100], signal_leak[:100], label='原始信号')
axes[0, 0].set_title('时域原始信号 (前100点)')
axes[0, 0].set_xlabel('时间 [秒]')
axes[0, 0].set_ylabel('振幅')
axes[0, 0].legend()
axes[0, 0].grid(True, alpha=0.3)

axes[0, 1].plot(t_leak[:100], signal_windowed[:100], color='orange', label='加窗后信号')
axes[0, 1].plot(t_leak[:100], window[:100], color='red', linestyle='--', alpha=0.5, label='汉宁窗')
axes[0, 1].set_title('时域加窗信号 (前100点)')
axes[0, 1].set_xlabel('时间 [秒]')
axes[0, 1].set_ylabel('振幅')
axes[0, 1].legend()
axes[0, 1].grid(True, alpha=0.3)

# 频域频谱对比 (对数坐标)
axes[1, 0].plot(freqs[:half], 20*np.log10(np.abs(fft_raw[:half]) + 1e-10))
axes[1, 0].set_title('原始信号频谱 (泄漏严重)')
axes[1, 0].set_xlabel('频率 [Hz]')
axes[1, 0].set_ylabel('幅度 [dB]')
axes[1, 0].set_xlim(40, 60)
axes[1, 0].grid(True, alpha=0.3)

axes[1, 1].plot(freqs[:half], 20*np.log10(np.abs(fft_win[:half]) + 1e-10), color='orange')
axes[1, 1].set_title('加窗后信号频谱 (泄漏抑制)')
axes[1, 1].set_xlabel('频率 [Hz]')
axes[1, 1].set_ylabel('幅度 [dB]')
axes[1, 1].set_xlim(40, 60)
axes[1, 1].grid(True, alpha=0.3)

plt.tight_layout()
plt.show()

通过对比图可以明显看到,加窗前(左下),50.5Hz的主峰周围有很多高的旁瓣,能量泄漏严重。加汉宁窗后(右下),旁瓣被显著抑制,主峰更“干净”,但代价是主峰略有展宽。这是一个典型的权衡:用频率分辨率换取频谱纯度。

4.2 处理实信号与提高频率估计精度

有时我们不仅要知道频率的大致位置,还需要更精确地估计频率值,尤其是在谱峰不在频率分辨率的整数倍位置上时。一种简单有效的方法是零填充。

零填充是在进行FFT之前,在信号末尾补充若干个0。它并不增加信号的真实信息,因此不能提高真实的频率分辨率,但可以对频谱进行插值,让谱线看起来更平滑,有助于通过观察找到谱峰的顶点,从而更精确地估计频率。

# 对一个接近但不等于频率分辨率整倍数的信号进行分析
f_precise = 52.3  # 精确频率
signal_precise = np.sin(2 * np.pi * f_precise * t)

# 方法1:无零填充
fft_no_pad = np.fft.fft(signal_precise)
freqs_no_pad = np.fft.fftfreq(len(signal_precise), d=1/fs)
half_no_pad = len(signal_precise)//2

# 方法2:进行零填充(将信号长度扩展到原来的4倍)
zero_pad_factor = 4
signal_padded = np.pad(signal_precise, (0, len(signal_precise)*(zero_pad_factor-1)), 'constant')
fft_padded = np.fft.fft(signal_padded)
freqs_padded = np.fft.fftfreq(len(signal_padded), d=1/fs)
half_padded = len(signal_padded)//2

# 绘制对比
plt.figure(figsize=(14, 5))

plt.subplot(1, 2, 1)
plt.stem(freqs_no_pad[:half_no_pad], np.abs(fft_no_pad[:half_no_pad]), basefmt=" ", use_line_collection=True)
plt.title(f'无零填充频谱 (分辨率: {fs/len(signal_precise):.2f} Hz)')
plt.xlabel('频率 [Hz]')
plt.ylabel('幅度')
plt.xlim(50, 55)
plt.grid(True, alpha=0.3)
# 找到峰值位置
peak_idx_no_pad = np.argmax(np.abs(fft_no_pad[:half_no_pad]))
estimated_freq_no_pad = freqs_no_pad[peak_idx_no_pad]
plt.axvline(x=estimated_freq_no_pad, color='red', linestyle='--', label=f'估计: {estimated_freq_no_pad:.2f} Hz')
plt.axvline(x=f_precise, color='green', linestyle=':', label=f'真实: {f_precise} Hz')
plt.legend()

plt.subplot(1, 2, 2)
plt.plot(freqs_padded[:half_padded], np.abs(fft_padded[:half_padded]), linewidth=1.5)
plt.title(f'4倍零填充后频谱 (插值后)')
plt.xlabel('频率 [Hz]')
plt.ylabel('幅度')
plt.xlim(50, 55)
plt.grid(True, alpha=0.3)
# 在插值后的频谱上找峰值
peak_idx_padded = np.argmax(np.abs(fft_padded[:half_padded]))
estimated_freq_padded = freqs_padded[peak_idx_padded]
plt.axvline(x=estimated_freq_padded, color='red', linestyle='--', label=f'估计: {estimated_freq_padded:.2f} Hz')
plt.axvline(x=f_precise, color='green', linestyle=':', label=f'真实: {f_precise} Hz')
plt.legend()

plt.tight_layout()
plt.show()

print(f"真实频率: {f_precise} Hz")
print(f"无零填充估计频率: {estimated_freq_no_pad:.2f} Hz (误差: {abs(estimated_freq_no_pad - f_precise):.2f} Hz)")
print(f"零填充后估计频率: {estimated_freq_padded:.2f} Hz (误差: {abs(estimated_freq_padded - f_precise):.2f} Hz)")

左图使用stem绘制离散的谱线,由于频率分辨率是1Hz(1000Hz/1000点),谱峰落在52Hz的格点上,与真实频率52.3Hz有误差。右图经过零填充插值后,频谱曲线变得连续平滑,我们可以更准确地定位到谱峰顶点在52.3Hz附近,估计精度大大提高。

5. 综合实战:分析一段真实音频片段

最后,我们将所有知识融会贯通,处理一个更接近真实世界的任务:分析一段简短音频文件的频谱。这里我们将使用scipy库来读取音频文件,如果你没有安装,请先运行pip install scipy。

注意:由于我们无法在代码中直接包含音频文件,以下示例假设你有一个名为sample_audio.wav的WAV格式文件。你可以录制一段包含固定频率(如用手机软件生成一个440Hz的A4标准音)的音频,或者使用任何简短的音效文件。

import numpy as np
import matplotlib.pyplot as plt
from scipy.io import wavfile

# 1. 读取音频文件
# 请将 'sample_audio.wav' 替换为你的音频文件路径
try:
    sample_rate, audio_data = wavfile.read('sample_audio.wav')
except FileNotFoundError:
    print("未找到音频文件,将使用模拟音频数据代替。")
    # 生成模拟音频数据:一个A4标准音 (440Hz) 加一点背景噪声
    sample_rate = 44100
    duration = 2.0  # 2秒
    t = np.linspace(0, duration, int(sample_rate * duration), endpoint=False)
    A4_freq = 440.0
    audio_data = 0.5 * np.sin(2 * np.pi * A4_freq * t) + 0.1 * np.sin(2 * np.pi * 880 * t) # 加一个倍频
    audio_data = audio_data + 0.02 * np.random.randn(len(t)) # 加噪声
    # 将浮点数数据转换为16位PCM格式模拟
    audio_data = (audio_data * 32767).astype(np.int16)

# 如果音频是双声道,取左声道或转换为单声道
if audio_data.ndim > 1:
    print(f"音频为 {audio_data.shape[1]} 声道,取左声道进行分析。")
    audio_data = audio_data[:, 0]

# 2. 截取一段进行分析(例如前0.5秒),避免计算量过大
analysis_duration = 0.5  # 分析0.5秒
num_samples = int(sample_rate * analysis_duration)
audio_segment = audio_data[:num_samples].astype(float) # 转换为浮点型便于计算
time_axis = np.arange(num_samples) / sample_rate

# 3. 加窗并计算FFT
window = np.hanning(num_samples)
windowed_audio = audio_segment * window

fft_result = np.fft.fft(windowed_audio)
freq_axis = np.fft.fftfreq(num_samples, d=1/sample_rate)

# 取单边频谱
half_n = num_samples // 2
magnitude = np.abs(fft_result[:half_n]) * 2 / np.sum(window) # 使用窗函数能量进行归一化
single_sided_freq = freq_axis[:half_n]

# 4. 绘制时域波形和频谱图
fig, axes = plt.subplots(2, 1, figsize=(12, 8))

# 时域图
axes[0].plot(time_axis, audio_segment, linewidth=0.8, alpha=0.7)
axes[0].set_title('音频信号时域波形 (片段)')
axes[0].set_xlabel('时间 [秒]')
axes[0].set_ylabel('振幅')
axes[0].grid(True, alpha=0.3)
axes[0].set_xlim(0, analysis_duration)

# 频域图 (对数坐标)
axes[1].plot(single_sided_freq, 20 * np.log10(magnitude + 1e-10), linewidth=1.0)
axes[1].set_title('音频信号幅度频谱 (加汉宁窗)')
axes[1].set_xlabel('频率 [Hz]')
axes[1].set_ylabel('幅度 [dB]')
axes[1].grid(True, alpha=0.3)
axes[1].set_xlim(20, sample_rate/2)  # 通常关注20Hz以上
axes[1].set_ylim(-80, 0)  # 设置动态范围

# 标记可能的基频和泛音
# 这里简单演示:找到前5个峰值
from scipy.signal import find_peaks
peaks, properties = find_peaks(20*np.log10(magnitude+1e-10), height=-50, distance=50) # 设置最小高度和峰间距离
for i, peak in enumerate(peaks[:5]):
    freq_peak = single_sided_freq[peak]
    db_peak = 20 * np.log10(magnitude[peak] + 1e-10)
    axes[1].plot(freq_peak, db_peak, "rx")
    axes[1].annotate(f'{freq_peak:.1f} Hz', xy=(freq_peak, db_peak), xytext=(5, 5),
                     textcoords='offset points', fontsize=9, color='red')

plt.tight_layout()
plt.show()

# 打印一些基本信息
print(f"采样率: {sample_rate} Hz")
print(f"分析片段长度: {analysis_duration} 秒")
print(f"频率分辨率: {sample_rate/num_samples:.2f} Hz")
print(f"检测到的主要峰值频率: {single_sided_freq[peaks[:5]]}")

这段代码完成了一个简易的音频频谱分析仪的核心功能。它读取(或模拟)音频数据,截取片段,加窗,计算FFT并绘制出专业的频谱图。通过scipy.signal.find_peaks函数,我们还能自动识别并标记出频谱中的主要峰值,这对于分析乐器音高、机器故障特征频率等应用非常有用。

在实际项目中,你可能还需要考虑平均多个时间段的频谱(短时傅里叶变换,STFT)来观察频率随时间的变化,或者使用更精确的峰值检测算法。但无论如何,你现在已经拥有了从信号生成、FFT计算、结果可视化和解读,到应用高级技巧处理实际问题的完整工具箱。

不愧是摸鱼高手Python matplotlib 绘制频谱图都会,能怪老板不管 复习回顾 matplotlib 是Python专门用来绘制渲染的模块,其底层主要分为脚本层、美工层和后端。脚本层为我们提供常见图形绘制如折线、柱状、直方、饼图。以往文章 这么详细的Python matplotlib 绘制图形 还不赶紧收藏_ Python matplotlib 绘制等高线图_ Python matplotlib 绘制散点图 还不收藏起来 python入门到进阶,爬虫数据分析全套资料分享讲解 CHINA 1. 频谱图概述 什么是频谱图? 频谱图表示的信号频率与能量的关系 阅读详情

相关推荐

傅里叶变换实战:用Python手把手教你绘制频谱图(附完整代码)

本文通过Python实战,手把手教你如何应用傅里叶变换绘制频谱图。文章从生成合成信号开始,详细讲解了FFT计算、频率轴构建、幅度谱与相位谱绘制等核心步骤,并针对频谱泄露、频率分辨率等现实挑战提供了加窗、补零等解决方案,最后以音频信号分析作为综合案例,帮助读者将理论转化为直观的编程实践。

weixin_35815766的博客 582

Python中利用FFT(快速傅里叶变换)进行频谱分析

本文将从实例的角度出发讲解Python中fft函数的基本使用,对已知信号进行频谱分析,不包含复杂的理论推导。

莫比的博客 3万+

IQ信号频谱fft数据处理

提供了一个MATLAB仿真文件,用于对IQ数据进行快速傅里叶变换(FFT)处理。该仿真文件旨在帮助用户理解和实践如何在MATLAB环境中对IQ数据进行频谱分析。

使用python进行傅里叶FFT 频谱分析

目录 一、一些关键概念的引入 1.1.离散傅里叶变换(DFT) 1.2快速傅里叶变换(FFT) 1.3.采样频率以及采样定率 1.4.如何理解采样定理 二、使用scipy包实现快速傅里叶变换 2.1.产生原始信号——原始信号是三个正弦波的叠加 2.2.快速傅里叶变换 2.3.FFT的原始频谱 2.4.将振幅谱进行归一化和取半处理 三、完整代码 一、一些关键概念的引入 1.1、离散傅里叶变换(DFT) 离散傅里叶变换(discrete Fourie...

qq_39720178的博客 1万+

LTC3783 LED驱动控制器设计与效率优化详解

开关电源控制器是现代LED照明的核心器件,通过电流模式控制实现高效能量转换。其核心原理是通过采样电阻检测负载电流,配合误差放大器形成闭环调节,在汽车电子、显示背光等场景中确保±3%的电流精度。LTC3783作为典型代表,集成升压/降压-升压多拓扑支持,配合PWM调光技术可实现3000:1的无色偏调光范围。在工程实践中,需重点考量功率电感选型、MOSFET开关损耗与热管理设计,例如在38W功率方案中采用10μH/5A电感和4.5mΩ MOSFET可达成95%效率。该方案特别适用于需要应对9-36V宽输入电压波

weixin_36231030的博客 401

239号资源-simulink仿真:MATLAB/Simulink教程(PDF文档)-----已提供下载资源

电网论文源程序擅长文章解读,论文与完整源程序,等方面的知识,电网论文源程序关注python,机器学习,计算机视觉,深度学习,神经网络,数据挖掘领域.电网论文源程序擅长文章解读,论文与完整源程序,等方面的知识,电网论文源程序关注python,机器学习,计算机视觉,深度学习,神经网络,数据挖掘领域.《《《《《《《《更多资源还请持续关注本专栏》》》》》》》《《《《《《《《更多资源还请持续关注本专栏》》》》》》》论文与完整源程序_电网论文源程序的博客-优快云博客。电网论文源程序-优快云博客。

LIANG674027206的博客 1076

python频谱分析

# -*- coding: utf-8 -*-

913

Windows环境下DataEase一站式安装指南(含WSL2+Docker配置)

本文详细介绍了在Windows环境下通过WSL2和Docker快速部署DataEase的完整教程。从WSL2配置、Docker环境搭建到DataEase离线安装,逐步指导用户完成一站式部署,特别适合需要快速搭建数据分析平台的开发者。教程包含常见问题解决方案和性能优化技巧,帮助用户高效使用这款国产开源数据可视化工具。

weixin_42526166的博客 399

用python代码实现实验:应用快速傅里叶变换对信号进行频谱分析

2.下面的代码实现对于正弦信号的频谱分析。4.下面实现对于衰减正弦序列的频谱分析。3.下面代码实现高斯序列的频谱分析。5.下面实现三角序列的频谱分析。6.下面实现三角序列的频谱分析。如有不足,欢迎指正。

m0_67424508的博客 1249

优快云积分获取与管理全攻略

技术社区积分系统是知识共享生态的核心激励机制,通过量化用户贡献实现资源交换。其底层逻辑遵循Web2.0时代的UGC经济模型,用户通过内容创作、社区互动等行为积累虚拟资产。在开发者社区场景中,积分体系能有效促进技术文档、工具源码等资源的流通,优快云作为国内头部平台,其积分规则具有典型参考价值。掌握签到策略、内容互动技巧和资源上传规范等实操方法,可系统性提升积分获取效率。2023年新规强化了连续签到奖励和互动质量检测机制,结合GitHub等开源平台资源互补,能构建更高效的技术资源获取路径。

weixin_34233974的博客 218

中小公司无线组网实战:用一台H3C AC和普通三层交换,实现办公网AP统一管理

本文详细介绍了中小型企业如何利用H3C AC控制器与普通三层交换机实现无线AP统一管理的实战方案。通过VLAN规划、DHCP配置和AC控制器设置,构建经济高效的办公网络,解决信号覆盖和连接稳定性问题,特别适合50-200人规模的企业部署。

weixin_42531516的博客 383

频谱分析—Python代码

利用python进行频谱分析。

老哥的博客 1082

ECC椭圆曲线加解密原理详解(配图)

椭圆曲线加解密原理详解 本文主要参照:ECC椭圆曲线详解(有具体实例)[1] 前言: 椭圆曲线(ECC)加密原理跟RSA加解密原理比起来,可真是晦涩难懂。拜读了大神Kalafinaian文章“ECC椭圆曲线详解(有具体实例)”,终于看到了参透的曙光。 由于原文中有微小的瑕疵,也为了便于阅读起来更加流畅,我重新整理了一下这篇文章。 为什么使用椭圆曲线加密算法? RSA的解决分解整数问题需要亚指数...

Mark的博客 7万+

使用python(matplotlib和numpy)实现快速傅里叶变换(FFT),并画出频谱图和相位图

使用python(matplotlib和numpy)实现快速傅里叶变换(FFT),并画出频谱图和相位图 一.模块包的安装 win+R打开命令窗口,在命令窗口输入cm的,在终端D:,再输入cd D:\python\Python3.7\Scripts(这里是每个人的自己的安装目录)转到该安装目录下。 最后直接在命令窗口输入 pip install+需要安装的模块,例如本实验要安装的 pip insta...

hjw1314kl的博客 1万+

ThinkBook 16p 2024 BIOS降压定频实战:从解锁CFG Lock到AC Loadline调优

高性能笔记本在满载时频繁撞上温度墙,通常源于固件层默认电压冗余过大,而系统级降压工具又受限于CFG Lock锁定。要根治问题,需要从BIOS固件层面理解电压管理机制——AC/DC Loadline参数控制着CPU在不同负载下的电压请求,通过修改这些负载线值可以安全降低电压,解锁CFG Lock后还能让XTU、ThrottleStop等软件调参工具恢复可用。这种BIOS级调优在工程实践中广泛用于改善散热、稳定频率、压降风扇噪音,尤其适用于联想ThinkBook 16p 2024与拯救者Y9000P等采用HX平

weixin_32496547的博客 389

FineBI学习总结

交叉表:一组作为行标题显示在表的左部,另一组作为列标题显示在表的顶部。连接到数据,如果数据不满足数据分析的需求,先进行自助数据集处理。数据集分类:DB表、SQL、Excel、自助数据集。分组表:将报表中的数据按相同项合并为一组显示。1、数据准备2、制作仪表板3、分享仪表板。左合并:保留左边全部数据,合并右边。右合并:保留右边全部数据,合并左边。上下拼接:上下拼接到一张表数据。3、如何实现拼表:多表拼一张。分组–业务包–数据集–字段。字段分类:数值、文本和日期。目录–仪表板–数据准备。维度:文本和日期类型。

Rsun2018的博客 1562

用Python实战信号处理:如何用FFT快速实现音频频谱分析(附完整代码)

本文通过Python实战,详细讲解了如何利用FFT(快速傅里叶变换)对音频信号进行频谱分析。内容涵盖从音频信号基础、傅里叶变换原理到完整的代码实现,包括分帧、加窗和频谱图可视化,帮助读者快速掌握数字信号处理的核心技能并应用于实际项目。

kmeans3miner的博客 333

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

Python实战:利用FFT分析音频信号并可视化频谱特征

本文详细介绍了如何利用Python进行音频信号分析,通过FFT(快速傅里叶变换)将时域信号转换为频域,并可视化其频谱特征。文章从环境搭建、合成测试信号入手,逐步讲解了FFT的核心原理、幅值校正、双边谱与单边谱的区别,并最终扩展到处理真实WAV文件及绘制专业频谱图。重点解析了频谱泄露现象及关键参数调优,为音频处理实践提供了完整指南。

code8的博客 702

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

快速傅里叶变换分析频谱详解及python代码示例

本文介绍了快速傅里叶变换(FFT)在频谱分析中的应用。通过Python代码示例,演示了如何生成复合频率信号(50Hz、70Hz、90Hz正弦波叠加)并进行FFT频谱分析。关键点包括:使用numpy的fft函数计算频谱,需对结果取绝对值并归一化;频谱具有共轭对称性,只需分析前半部分;增加采样时间可使频谱更接近理想脉冲形状。实验结果验证了FFT能准确识别信号频率成分及其振幅(如70Hz信号的振幅为2)。文章还提供了完整代码和不同采样时间下的频谱对比图。

weixin_46846685的博客 1405

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

Python实战:用NumPy和Matplotlib可视化调频信号频谱(附完整代码)

本文通过Python实战演示了如何使用NumPy和Matplotlib可视化调频信号频谱,涵盖从信号生成到频谱分析的完整流程。文章提供可直接复用的代码模板,详细讲解FFT频谱分析技巧,并通过参数实验揭示调制指数β对频谱的影响规律,帮助电子工程学生和Python开发者快速掌握信号处理可视化技术。

weixin_29090089的博客 182

傅里叶变换实战:如何用Python快速分析抽样信号频谱(附完整代码)

本文提供了一份傅里叶变换实战指南,通过Python演示如何快速分析抽样信号的频谱。文章从环境搭建、信号构造入手,详细讲解了使用NumPy进行FFT计算、频谱可视化以及应对频谱泄露的窗函数应用等核心步骤,并附有完整代码,帮助工程师和数据分析师将理论应用于实际信号处理项目。

redis7keeper的博客 1000

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

频域特征提取的Python实现(频谱、功率谱、倒频谱) 本文只对 频域特征值提取的MATLAB代码实现(频谱、功率谱、倒频谱) 做代码翻译,用python重写一遍,以加强对这些特征的理解 1. 频谱 from scipy.fftpack import fft, fftshift, ifft from scipy.fftpack import fftfreq import numpy as np i...

记录学习的过程 3万+

傅里叶变换实战:如何用Python快速实现信号频谱分析(附完整代码)

本文详细介绍了如何使用Python实现傅里叶变换进行信号频谱分析,涵盖从信号生成、FFT实现到频谱可视化的全流程。通过NumPy和Matplotlib库,结合正交变换技术,帮助工程师快速掌握频域分析技巧,适用于音频处理、振动分析等场景。

spice的博客 954

快速傅里叶变换python_使用Python进行FFT频谱分析

FFT频谱分析原理采样定理:采样频率要大于信号频率的两倍。N个采样点经过FFT变换后得到N个点的以复数形式记录的FFT结果。假设采样频率为Fs,采样点数为N。那么FFT运算的结果就是N个复数(或N个点),每一个复数就对应着一个频率值以及该频率信号的幅值和相位。第一个点对应的频率为0Hz(即直流分量),最后一个点N的下一个点对应采样频率Fs。其中任意一个采样点n所代表的信号频率:Fn=(n-1)*F...

weixin_39605326的博客 1046
上一篇: CMake传参实战:如何用SET和OPTION控制不同平台的编译逻辑(附低版本兼容方案)
下一篇: 手把手教你用TigerVNC实现CentOS 7.9远程桌面连接(附客户端配置)
随身带U盘
博客等级 码龄4年 30粉丝 1526原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值