3. 地震道振幅均衡与异常振幅压制

为什么先做振幅均衡,再做异常振幅压制

CMP 道集里同时存在两类会破坏速度谱聚焦的振幅问题:一类是横向能量不均——近偏移距能量强、远偏移距能量弱,或某几道整体偏亮/偏暗;另一类是局部异常振幅——单道单时窗内的野值(尖脉冲、强能量噪声、坏炮残余)。前者会让速度谱的能量团被强偏移距道“拉偏”,后者会在谱上形成虚假能量脊。处理顺序应为:先做道均衡把各道能量拉到同一量级,再用中值滤波类方法识别并压制偏离邻域统计的异常振幅,最后用分偏移距能量曲线和振幅直方图验证。

处理链与判读逻辑

CMP 道集 N 道 × M 样点 偏移距 h₁…hₙ 近道强 / 远道弱 含单道野值 ① 道均衡 按道计算 RMS 能量 Aᵢ(t) ← Aᵢ(t)/RMSᵢ 时窗:全道或滑动窗 目标:各道能量同量级 注意:野值会抬高 RMS ② 异常振幅压制 邻域中值 M(t) 与偏差 |A(t)−M(t)| > k·σ → 衰减 k 取 2.5~3.5(示例) 输出:替换/限幅/置零 保留有效反射同相轴 ③ 处理前后对比验证 分偏移距 RMS 曲线 振幅直方图 / 分位数 道集剖面目视检查 速度谱能量团聚焦度 通过 → 进入速度谱拾取 未通过:调整 k 或均衡时窗后重跑 处理前:道能量随偏移距衰减 + 单道野值 野值 偏移距增大 → 处理后:各道能量拉平,野值被压制 已压制 偏移距增大 →

关键实现:道均衡 + 中值偏差异常振幅压制

下面给出一个可直接运行的 Python 实现,输入为二维数组 gather(形状 [n_traces, n_samples],行=道、列=时间样点)。道均衡采用全道 RMS 归一化;异常振幅压制采用沿时间方向的滑动中值作为局部参考,用邻域绝对偏差的中值估计尺度 σ,超过 k·σ 的样点按比例限幅。两个参数 win(中值窗长)与 k(阈值倍数)是本节最需要调的对象。

import numpy as np

def trace_balance(gather, eps=1e-10):
    """按道 RMS 归一化,使各道能量处于同一量级。"""
    rms = np.sqrt(np.mean(gather**2, axis=1, keepdims=True)) + eps
    return gather / rms

def despike_median(gather, win=11, k=3.0, eps=1e-10):
    """沿时间方向滑动中值,压制偏离邻域统计的异常振幅。"""
    n_tr, n_s = gather.shape
    half = win // 2
    out = gather.copy()
    pad = np.pad(gather, ((0, 0), (half, half)), mode="reflect")
    for i in range(n_s):
        seg = pad[:, i:i + win]                 # [n_tr, win]
        med = np.median(seg, axis=1)            # 局部中值 M(t)
        dev = np.abs(seg - med[:, None])
        sigma = np.median(dev, axis=1) + eps    # 稳健尺度估计
        a = gather[:, i]
        mask = np.abs(a - med) > k * sigma
        # 超阈值样点限幅到 k*sigma 边界,保留符号
        clipped = med + np.sign(a - med) * k * sigma
        out[:, i] = np.where(mask, clipped, a)
    return out

# 示例:构造含近强远弱与单道野值的道集
rng = np.random.default_rng(7)
n_tr, n_s = 24, 400
t = np.arange(n_s)
gather = np.zeros((n_tr, n_s))
for it in range(n_tr):
    amp = 1.0 / (1.0 + 0.08 * it)               # 近道强、远道弱
    gather[it] = amp * np.sin(2 * np.pi * t / 40.0) + 0.02 * rng.standard_normal(n_s)
gather[5, 180] = 8.0                            # 注入单道野值
gather[12, 260] = -6.5

bal = trace_balance(gather)
clean = despike_median(bal, win=11, k=3.0)

def trace_rms(g):
    return np.sqrt(np.mean(g**2, axis=1))

print("原始  RMS 范围: %.3f ~ %.3f" % (trace_rms(gather).min(), trace_rms(gather).max()))
print("均衡后 RMS 范围: %.3f ~ %.3f" % (trace_rms(bal).min(), trace_rms(bal).max()))
print("压制后 峰值: %.3f" % np.abs(clean).max())
print("野值点 (5,180) 处理前 %.2f → 处理后 %.2f" % (bal[5, 180], clean[5, 180]))

参数选择与结果判读

参数含义示例取值调整方向与判据
win中值滤波时间窗长(样点)11窗长应大于一个子波周期、小于同相轴时差;过小会误伤有效反射,过大会漏检窄脉冲
k异常判定阈值倍数3.0k 越小压制越激进;若有效同相轴被削平则增大 k,若野值残留则减小 k
均衡方式全道 RMS / 滑动窗 RMS全道道内能量随时间变化剧烈时改用滑动窗,避免浅层被过度压制

判读要点:① 均衡后各道 RMS 应落在同一量级(示例中原始 RMS 差异可达数倍,均衡后应接近 1);② 压制后单道最大绝对值应显著下降,且野值点幅值回落到邻域水平;③ 目视检查有效反射同相轴连续性未被破坏;④ 若后续速度谱上仍出现横向条带状虚假能量,说明异常振幅未压干净,应减小 k 或缩短 win 重跑。

道均衡会改变道间相对振幅,若后续需要做 AVO 类振幅分析,应在均衡前保留原始振幅副本;本节均衡仅用于改善速度谱拾取的输入条件,不用于振幅保真处理。
验证时优先看“分偏移距 RMS 曲线是否被拉平”和“振幅直方图长尾是否收窄”这两个量化指标,比单纯目视剖面更可靠;两者都通过后再进入速度谱拾取。