资讯动态

MATLAB实现F-K滤波:定向压制面波与线性干扰的完整方案

发布时间:2026/9/20 18:59:50 来源:尧图企业网站定制
简介面向地震数据处理人员与地球物理专业学生的F-K滤波MATLAB实现资源专门用于压制地震记录中的地滚噪声。地滚波属于低频干扰传播距离远常常淹没有效反射信号F-K滤波的核心思想是借助二维傅立叶变换将时间-空间域的地震数据变换到频率-视速度域再依据信号与噪声在频率和传播方向上的差异设计特定的窗口函数进行选择性衰减。代码包仅包含两个文件一个名为fk_filter.m的脚本涵盖了地震数据读取与预处理、二维傅立叶变换、滤波窗口参数设定、滤波算子应用、逆傅立叶变换以及输出结果等完整流程另一个为fk_filter.jpg示意图可直观呈现滤波前后的剖面对比或流程示意。整个压缩包只有17KB极其轻量便于初学者快速下载学习目前已有662人学习过该资源。通过阅读和运行代码读者不仅可以从代码层面理解F-K滤波抑制地滚波的具体实现步骤还能根据实际数据调整频率范围、窗口形状等参数获得一套可扩展的基础处理工具非常适合作为地震信号处理与勘探地球物理课程中的上机练习材料。 干了十几年地震资料处理我最常被同行问到的就是面波和线性干扰压不掉怎么办多数人第一反应是频率滤波但当面波和有效反射在频率上重叠时带通滤波一刀切下去有效信号也跟着伤筋动骨。这时候就得请出 F-K 滤波频率-波数域滤波了。这次就说说我在 MATLAB 里实现 fk_filter 的完整思路和可复现代码。这个项目解决的问题很具体把地震记录从时间-空间域变换到频率-波数域f-k 域利用有效反射与规则干扰在视速度上的差异设计扇形滤波器达到定向压制面波、线性干扰的目的。适合正在做地震资料处理、搞信号分析或者实验室里需要压制规则干扰的同行参考。1. F-K 滤波的核心原理把“走时特征”变成“方向特征”1.1 为什么只做频率滤波不够先看一个最容易踩的坑。野外单炮记录里面波能量强、频率低很多人第一反应是直接高通滤波。可问题在于面波频率范围常常从几赫兹延伸到 30Hz 甚至更高而深层反射波的低频成分也集中在 10-30Hz 这个区间。一把高通滤波器扫过去面波确实弱了但深层反射的能量也快没了处理后剖面看起来干净实际信噪比并没有真正提升。这就是为什么需要在二维域里做文章。地震记录本身是时间 t 和空间 x 的二维函数不同波场不仅频率不同传播方向、视速度也不同。面波视速度一般只有几百米每秒到一千多米每秒反射波视速度动辄两千米每秒以上。在时间-空间域里这两种波的波形混在一起很难直接切开但把它们变换到 f-k 域之后反射波和面波会分居在不同方向上。F-K 滤波的本质就是利用传播方向这个维度做过滤。1.2 扇形滤波器的数学逻辑对一个二维信号做二维傅里叶变换得到的就是 f-k 谱。这里有个关键规律一个沿 x 方向以视速度 v 传播的线性同相轴在 f-k 域中能量会集中在通过原点的一条直线上并且满足k f / v换句话说斜率越小越靠近 k 轴代表视速度越低斜率越大越靠近 f 轴代表视速度越高。面波低速所以能量贴近 k 轴反射波高速能量贴近 f 轴。我们在 f-k 平面里画一个“扇形”区域只保留那些视速度大于某个门槛值的能量就实现了对低速干扰的定向压制。这个扇形滤波器在数学上可以写成H(f, k) 1 当 |f / k| ≥ vmin 且 f 在有效带内 H(f, k) 0 其他区域。实际实现时还会加过渡带让函数不是突变的 0/1否则反变换后会出现振铃效应。后面我们代码里会做 taper 处理这个细节非常重要。2. MATLAB 实现 F-K 滤波的完整步骤2.1 函数接口设计与数据准备这个 fk_filter 的 MATLAB 实现我建议封装成独立函数方便对不同数据集反复调用。输入参数可以包括function [data_out, f, k, spec_in, spec_out] fk_filter(data, dt, dx, vmin, fmax, taper_ratio) % data : 二维地震记录维度为 [nt, nx]行为时间列为道 % dt : 时间采样间隔单位秒 % dx : 空间采样间隔道距单位米 % vmin : 最低保留视速度单位米/秒 % fmax : 有效信号最高频率单位Hz % taper_ratio : 滤波核边缘平滑过渡的比例推荐0.1~0.3数据输入前我习惯先做一次能量均衡把每个地震道的振幅压到接近同一量级否则强面波会把弱反射的频谱特征完全淹没。同时也要确认数据的空间方向是沿着检波点排列方向的也就是列方向代表测线位置。如果数据存成了 [nx, nt]转置一下就行。2.2 二维傅里叶变换与坐标网格构建MATLAB 自带的 fft2 可以直接对二维数据做变换。但要注意fft2 默认变换后零频在矩阵的左上角需要配合 fftshift 把零频移到中心f 轴和 k 轴都要处理成中心对称的网格。[nt, nx] size(data); data data - mean(data(:)); % 去均值压制直流分量 D fftshift(fft2(data)); df 1 / (nt * dt); dk 1 / (nx * dx); f (-nt/2 : nt/2-1) * df; k (-nx/2 : nx/2-1) * dk; [K, F] meshgrid(k, f);这里有个细节f 和 k 的单位不同f 的单位是 Hzk 的单位是 1/米即波数。用 meshgrid 出来以后F 每行代表不同时间频率K 每列代表不同空间波数。后续计算视速度 v F ./ K 时要注意处理 K 0 的那一行避免除零。2.3 扇形滤波器构建与频谱相乘网格构建好以后滤波器就可以“画”出来了。通带条件为视速度的绝对值大于 vmin同时频率绝对值落在有效带内v_abs abs(F ./ (K eps)); mask zeros(nt, nx); valid (v_abs vmin) (abs(F) fmax) (abs(F) 3*df); mask(valid) 1;为什么还要限制最低频率如果你直接保留所有 f那么趋近于直流的区域f 和 k 都很小在数值上很不稳定而且这部分噪声基本是低速环境噪音保留价值不大。加一个最低门槛可以显著改善输出信噪比。直接把 mask 变成 0/1反变换回来在空间上会出现吉布斯振铃。我更建议做一次平滑过渡让滤波器边缘不是一刀切if taper_ratio 0 se ones(round(taper_ratio * min(nt, nx))); se se / sum(se(:)); mask conv2(double(mask), se, same); end这是一步简单有效的空间平滑。如果你希望更精细可以对速度边界单独做余弦 taper但对于大多数实际数据处理这个卷积平滑已经足够。然后滤波核乘上频谱D_filtered D .* mask; data_out real(ifft2(ifftshift(D_filtered)));到这里一次标准的 F-K 滤波就算完成了。下面我用一个合成数据例子把整个过程串起来方便直接抄作业。3. 实操过程从合成记录到滤波效果的完整测试3.1 构造带面波干扰的合成记录为了验证滤波效果我构造了一个简单模型包含双曲线反射波和低速线性面波。这样谁优谁劣一目了然。% 参数设置 dt 0.002; % 2ms采样 dx 10; % 道距10m nt 512; % 512个时间点 nx 96; % 96道 t (0:nt-1) * dt; x (0:nx-1) * dx; % 生成雷克子波 function w ricker(f0, dt, nt) t0 -1/f0:dt:1/f0; w (1 - 2*pi^2*f0^2*t0.^2) .* exp(-pi^2*f0^2*t0.^2); w w(:); end w_ref ricker(35, dt, nt); % 反射子波35Hz w_surf ricker(12, dt, nt); % 面波子波12Hz data zeros(nt, nx); % 加入反射同相轴双曲线 for ix 1:nx t0 0.25; v 2800; t_ref sqrt(t0^2 (x(ix)/v)^2); idx round(t_ref / dt) 1; if idx length(w_ref) - 1 nt data(idx:idxlength(w_ref)-1, ix) ... data(idx:idxlength(w_ref)-1, ix) 0.8 * w_ref; end end % 加入线性面波视速度约800m/s v_surf 800; for ix 1:nx t_line 0.3 x(ix) / v_surf; idx round(t_line / dt) 1; if idx length(w_surf) - 1 nt data(idx:idxlength(w_surf)-1, ix) ... data(idx:idxlength(w_surf)-1, ix) 1.5 * w_surf; end end注意我这里写了一个内嵌的 ricker 函数MATLAB 新版可以直接放在脚本末尾老版本的话建议单独存成 ricker.m。子波长度不需要太长我看到不少人把子波延到 200ms频率成分基本没变化计算量倒是白白增加了。3.2 运行时观察 f-k 谱的变化调用我们前面写的 fk_filter把滤波前后的 f-k 谱画出来对比% 查看滤波前频谱 D_before fftshift(fft2(data - mean(data(:)))); spec_before 20 * log10(abs(D_before) 1e-6); % 执行滤波 [data_out, f, k, spec_in, spec_out] fk_filter(data, dt, dx, vmin1800, fmax90, taper_ratio0.15); % 绘图对比 figure(Color, w); subplot(2, 2, 1); imagesc(x, t, data); axis xy; title(原始记录); subplot(2, 2, 2); imagesc(k, f, spec_before); axis xy; title(F-K谱滤波前); subplot(2, 2, 3); imagesc(x, t, data_out); axis xy; title(F-K滤波后); subplot(2, 2, 4); imagesc(k, f, spec_out); axis xy; title(F-K谱滤波后);实测下来只要 vmin 设在 1800 附近面波带基本被削干净反射双曲线完整保留。如果 vmin 设得过高比如超过 3000反射波的远偏移距部分也会被切掉因为远道反射的视速度会比较低。这一点后面参数选择部分还会细说。3.3 滤波后处理与剖面输出检查滤波输出后别急着完事我一般会先看单炮上的残差。把原始记录减去滤波结果得到的就是滤掉的部分。如果滤掉的面波里还混有明显反射波形态说明 vmin 设得太低或 taper 太宽需要回调参数。removed data - data_out; figure(Color, w); subplot(1, 2, 1); imagesc(x, t, data_out); axis xy; title(保留成分); subplot(1, 2, 2); imagesc(x, t, removed); axis xy; title(滤除成分);这一步很关键它能帮你看清滤波器有没有“误伤”。我在实际项目中遇到过面波速度差别不大的地区滤波后反射同相轴出现了假频样的锯齿。后来检查发现不是 F-K 滤波本身的问题而是空间假频没处理数据在 f-k 域发生了混叠。这个问题下面专门讲。4. 关键参数怎么选速度范围、频带与过渡带4.1 视速度的边界怎么定vmin 是整个 F-K 滤波里最重要的参数。它的物理含义是视速度低于这个值的波场全部被压制高于这个值的波场全部保留。确定方法我推荐两个一是直接从原炮集上量面波的线性同相轴斜率用拾取两点坐标算视速度二是在 f-k 谱上读取干扰能量带的斜率范围。第二种更直观打开 f-k 谱图面波能量通常在靠近 k 轴的一条窄带里量出这条带的边界斜率就是 vmin 的参考下限。实际处理时我会把 vmin 定在“面波最大视速度”和“反射波最下视速度”之间。反射波远偏移距的视速度经常降到 2000m/s 以下所以 vmin 不能无脑取 3000。一个保守的经验是先取面波速度的 1.2 倍作为初值观察滤波结果再微调。4.2 频率带、时间窗和空间假频fmax 设有效信号最高频率这个好理解。比较隐蔽的是 fmin也就是最低频率门槛。我之前做过一个煤矿数据面波频率极低5Hz以下而深层反射信号也集中在 8-20Hz。如果把 fmin 设得太高反射就没了设得太低滤波器在低频区会保留很多背景噪声。比较稳的做法是取 2-3 个频率点看效果取一个不影响主要反射频带的门槛。空间假频更值得警惕。根据采样定理空间方向能够无混叠表示的最大波数是 1/(2dx)。当面波速度很低时它对应的空间波数可能超过这个值就会折叠到高频高速区域里混在反射波方向中。这时候你再怎么调 vmin 都滤不掉。解决思路有两个一是预处理时先对空间道做插值加密道距或者重采样到更小的 dx二是先做一次低速面波分频压制把假频能量先压掉再进 F-K。具体选哪个要根据目标层频率和计算效率权衡。5. 常见问题与排查技巧实录5.1 滤波后剖面出现横纹或振铃这个几乎每个人都会遇到。主要原因就是滤波核太陡、边界太锐利。用我前面代码里的 conv2 平滑处理后振铃基本能压下去。如果还明显建议降低 taper_ratio 或者对 filter 核用更平滑的窗函数。再有就是检查是否在反变换前做了 fftshift 反向操作少了这一步频谱就乱了。5.2 二维 FFT 后直流分量异常大地震记录里如果有的道均值没去掉二维 FFT 后零频附近会有一个巨大的尖峰它会污染附近大量频率成分。我的习惯是滤波前必须去均值必要时还可以对每条道做一次去趋势。去均值不会影响反射信号的带内成分但对稳定输出帮助很大。5.3 滤波后有效反射变弱或出现畸变当你发现目标反射同相轴变弱时多半是 vmin 压到了有效信号。反射波在 f-k 域不是一个点而是沿着一定斜率展布的带。远偏移距、深层的反射视速度可能并不高。这时候可以看看是不是该分时窗处理对浅层高速区用一个 vmin对深层低速区用另一个 vmin分别滤波再拼接。也可以用分频处理把数据先滤波成分频段每段单独求 f-k 滤波。5.4 干扰与有效波速度接近F-K 滤波失效这是 F-K 滤波的硬伤。当面波速度和反射波速度接近或者干扰本身就是大倾角线性噪声扇形滤波器很难把两者切开。这时候不要硬扛。比较实用的组合拳是先做速度分析把有效反射方向拉平到水平然后在 f-k 域对残余干扰进行窄带陷波或者换用 f-x 域预测滤波来做随机/相干噪声压制。F-K 滤波是工具箱里的一件利器但不是万能钥匙什么工具配什么场景这个判断比工具本身更重要。根据我个人的实际使用体会F-K 滤波在规则干扰压制上确实是 MATLAB 里性价比很高的方案代码量不大原理直观效果反馈迅速。只要把 vmin、fmax、taper 这三个参数调整到位它能解决绝大多数面波和线性干扰的问题。真到了参数调到极限还不满意的情况再考虑时变/空变滤波或者多域组合压制。如果你正准备在自己的数据上试建议先拿合成记录跑通流程再上实际炮集这样对参数和现象的理解都会快很多。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价