You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python均匀化正弦/Chirp信号随时间变化的幅度

正弦/Chirp信号周期幅度归一化实现(Python)

核心思路

先提取信号的每个周期片段,计算整个信号范围内的最大峰峰值,再将每个周期的信号幅度缩放至该最大峰峰值,实现各周期幅度的统一。

步骤实现

1. 依赖库导入

import numpy as np
import matplotlib.pyplot as plt
from scipy.signal import hilbert, find_peaks

2. 生成测试信号(带幅度波动的正弦/Chirp)

# 采样率
fs = 1000
t = np.linspace(0, 5, int(fs*5))
# 随时间波动的幅度调制因子
amp_modulation = 0.5 + 0.5*np.sin(2*np.pi*0.1*t)

# 带幅度波动的正弦信号
signal_sine = amp_modulation * np.sin(2*np.pi*5*t)

# 带幅度波动的Chirp信号(扫频5Hz到20Hz)
freq_chirp = np.linspace(5, 20, len(t))
signal_chirp = amp_modulation * np.sin(2*np.pi*np.cumsum(freq_chirp)/fs)

3. 周期分割方法

  • 正弦信号:通过上升沿过零点检测分割周期
def split_sine_cycles(signal, fs):
    # 定位信号从负变正的上升沿过零点
    crossings = np.where(np.diff(np.sign(signal)) > 0)[0]
    # 按过零点切割出每个完整周期
    cycles = []
    for i in range(len(crossings)-1):
        cycles.append(signal[crossings[i]:crossings[i+1]])
    return cycles
  • Chirp信号:通过峰值检测分割周期(扫频时过零点间隔不稳定,峰值间隔更可靠)
def split_chirp_cycles(signal, fs):
    # 定位所有峰值点,设置最小间隔避免误检
    peaks, _ = find_peaks(signal, distance=int(fs/np.max(freq_chirp))*0.8)
    # 按峰值切割出每个完整周期
    cycles = []
    for i in range(len(peaks)-1):
        cycles.append(signal[peaks[i]:peaks[i+1]])
    return cycles

4. 计算全局最大峰峰值并归一化

def normalize_cycle_amplitude(cycles):
    # 计算每个周期的峰峰值
    cycle_pps = [np.max(cycle) - np.min(cycle) for cycle in cycles]
    # 取全局最大峰峰值
    max_pp = np.max(cycle_pps)
    # 对每个周期做幅度缩放
    normalized_cycles = []
    for cycle, pp in zip(cycles, cycle_pps):
        if pp == 0:
            normalized_cycles.append(cycle)
        else:
            normalized_cycles.append(cycle * (max_pp / pp))
    # 拼接回完整信号
    return np.concatenate(normalized_cycles), max_pp

5. 测试与可视化

# 处理正弦信号
sine_cycles = split_sine_cycles(signal_sine, fs)
normalized_sine, max_pp_sine = normalize_cycle_amplitude(sine_cycles)

# 处理Chirp信号
chirp_cycles = split_chirp_cycles(signal_chirp, fs)
normalized_chirp, max_pp_chirp = normalize_cycle_amplitude(chirp_cycles)

# 绘图对比原始与归一化信号
plt.figure(figsize=(12,8))
plt.subplot(221)
plt.plot(t, signal_sine)
plt.title('原始正弦信号')
plt.subplot(222)
plt.plot(t[:len(normalized_sine)], normalized_sine)
plt.title(f'归一化正弦信号(最大峰峰值:{max_pp_sine:.2f})')
plt.subplot(223)
plt.plot(t, signal_chirp)
plt.title('原始Chirp信号')
plt.subplot(224)
plt.plot(t[:len(normalized_chirp)], normalized_chirp)
plt.title(f'归一化Chirp信号(最大峰峰值:{max_pp_chirp:.2f})')
plt.tight_layout()
plt.show()

关键建议

  • 噪声预处理:如果信号含噪声,先通过scipy.signal.wiener或巴特沃斯滤波处理,避免过零点/峰值检测误判。
  • Chirp信号优化:快速扫频场景下,可通过Hilbert变换计算瞬时频率,精准预估每个周期的采样点数:
    analytic_signal = hilbert(signal_chirp)
    instantaneous_phase = np.unwrap(np.angle(analytic_signal))
    instantaneous_freq = np.diff(instantaneous_phase)/(2*np.pi)*fs
    
  • 边界处理:首尾的不完整周期建议直接丢弃,避免拉低归一化效果。
  • 实时流处理:针对实时信号,可采用滑动窗口检测周期,每识别出一个完整周期就完成归一化并输出。

内容的提问来源于stack exchange,提问作者VJA

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 04:01:05