实现叠前地震数据的动校正(NMO)和叠加(Stack)
function [stack_section, nmo_corrected] = nmo_stack(data, t, offsets, velocity, dt)
% NMO_STACK 对叠前地震道集进行动校正和叠加
% 输入参数:
% data - 地震道集数据矩阵 [时间采样点数 × 道数]
% t - 时间轴向量 (单位: 秒) [时间采样点数 × 1]
% offsets - 炮检距向量 (单位: 米) [1 × 道数]
% velocity - 均方根速度 (单位: 米/秒) [标量 或 与t长度相同的向量]
% dt - 时间采样间隔 (单位: 秒)
%
% 输出参数:
% stack_section - 叠加剖面 [时间采样点数 × 1]
% nmo_corrected - 动校正后的道集 [时间采样点数 × 道数]% 参数检查
if nargin < 5error('需要5个输入参数: data, t, offsets, velocity, dt');
end[nt, ntr] = size(data);
if length(t) ~= nterror('时间轴t的长度必须与data的行数一致');
endif length(offsets) ~= ntrerror('炮检距offsets的长度必须与data的列数一致');
end% 如果velocity是标量,扩展为常数向量
if isscalar(velocity)velocity = velocity * ones(nt, 1);
elseif length(velocity) ~= nterror('速度向量velocity的长度必须与时间轴t一致');
end% 初始化动校正后的道集
nmo_corrected = zeros(nt, ntr);% 对每个时间点进行动校正
for it = 1:ntt0 = t(it); % 零偏移距双程旅行时v = velocity(it); % 当前时间点对应的速度% 计算每个道的NMO校正量tx = sqrt(t0^2 + (offsets).^2 / v^2); % 有偏移距的旅行时% 找到有效数据范围 (tx <= 最大记录时间)valid_idx = (tx <= t(end));% 插值获取动校正后的振幅for itr = find(valid_idx)% 计算最近的时间采样点索引tidx = round(tx(itr) / dt) + 1;% 确保索引在有效范围内if tidx >= 1 && tidx <= ntnmo_corrected(it, itr) = data(tidx, itr);endend
end% 叠加处理 (沿道方向平均)
stack_section = mean(nmo_corrected, 2);% 可视化结果
figure('Name', 'NMO校正与叠加结果', 'NumberTitle', 'off');subplot(1, 3, 1);
imagesc(offsets, t, data);
colormap('gray'); colorbar;
title('原始道集');
xlabel('炮检距 (m)'); ylabel('时间 (s)');
axis tight;subplot(1, 3, 2);
imagesc(offsets, t, nmo_corrected);
colormap('gray'); colorbar;
title('NMO校正后道集');
xlabel('炮检距 (m)'); ylabel('时间 (s)');
axis tight;subplot(1, 3, 3);
plot(stack_section, t, 'k', 'LineWidth', 1.5);
set(gca, 'YDir', 'reverse');
title('叠加剖面');
xlabel('振幅'); ylabel('时间 (s)');
grid on; axis tight;
end
示例:
% 生成合成地震道集示例
dt = 0.004; % 时间采样间隔 (4ms)
t = (0:dt:2)'; % 时间轴 (0-2秒)
offsets = 50:50:500; % 炮检距 (50-500米)
velocity = 1500; % 均方根速度 (1500 m/s)% 创建合成数据 (包含同相轴)
[tt, xx] = meshgrid(t, offsets);
data = sin(2*pi*20*(tt - sqrt(tt.^2 - xx.^2/velocity^2)))';
data = data .* exp(-0.5*tt); % 添加衰减% 添加随机噪声
rng(0);
data = data + 0.1*randn(size(data));% 运行NMO校正和叠加
[stack, nmo_corrected] = nmo_stack(data, t, offsets, velocity, dt);
关键功能说明:
-
动校正 (NMO):
- 使用公式:\(t_x = \sqrt{t_0^2 + \frac{x^2}{v^2}}\) 计算校正量
- 通过插值将原始数据映射到零偏移距时间轴
- 自动处理边界条件(超出记录时间的部分置零)
-
叠加处理:
- 对动校正后的道集进行道间平均
- 输出零偏移距模拟剖面
-
可视化:
- 显示原始道集、NMO校正后道集和叠加剖面
- 使用灰度色谱展示地震数据
参数说明:
-
输入:
data
:地震道集(时间×道号)t
:时间轴向量offsets
:对应每道的炮检距velocity
:均方根速度(可常数或时间序列)dt
:时间采样间隔
-
输出:
stack_section
:叠加剖面nmo_corrected
:动校正后的道集
参考源码 叠前地震数据动校正和叠加的matlab模块 www.youwenfan.com/contentcne/78145.html
事项:
- 速度模型需要准确(实际应用中需用速度分析获取)
- 大炮检距或浅层数据可能出现拉伸畸变(需切除处理)
- 实际数据需先进行预处理(去噪、增益等)
- 对于复杂介质,需考虑高阶时差校正(如DMO)
此模块适用于教学和小规模数据处理。对于实际生产数据,建议使用专业地震处理软件(如SeisSpace、Madagascar等)或MATLAB的地震工具箱。