简介:一套基于MATLAB的InSAR(干涉合成孔径雷达)数据处理工具箱,面向地表形变监测、地震与火山活动、城市沉降等地球动力学研究场景,为遥感、测绘和工程领域的研究者提供从SAR数据到形变信息的完整处理工具。压缩包共包含59个文件,全部为.m格式的MATLAB函数脚本,压缩后体积仅73KB,函数命名直观,职责明确,用户可根据处理流程按需调用。目前已有285人学习/下载,适合正在学习InSAR技术或需要快速搭建实验流程的入门及中级研究者。工具箱覆盖干涉图生成、相位解缠、几何校正、时序InSAR分析、形变模型拟合与结果可视化等核心模块,其中相位解缠部分提供了多种常用算法,时序分析支持SBAS与PSI等思路,并附有噪声过滤、大气延迟校正及误差分析相关函数。用户可以直接在MATLAB环境中调用这些脚本,结合自定义脚本完成数据预处理、干涉处理、形变反演与结果解释的完整工作流。
1. InSAR工具箱拿到手后别急着跑数据:先把它当成一套可拆解的MATLAB相位解缠演练场
做地表形变监测的人下载InSAR工具箱时,多半期待它能一口气把干涉图、解缠、形变场全部算出来。实际打开这个压缩包会发现,里面是几十个.m函数文件,并没有一键入口。这个InSAR工具箱的价值恰恰在这里:它把模拟SLC生成、复数多视、残差点统计、最小费用流解缠、DEM读写这一整条链路拆成了独立模块,适合刚入门的研究生和需要快速验证算法的工程师,在MATLAB里把每一步看得清清楚楚。想直接处理真实卫星数据的读者,也能把它当作解缠实验床,先跑通逻辑再接自己的数据。
2. 拆开工具箱的四个功能族:模拟、干涉、解缠、可视化的配合方式
2.1 从函数名反推设计意图:几十个m文件不是乱堆的
下载解压后,第一件事不是急着跑demo,而是先把工具箱目录加进MATLAB搜索路径,然后做一次“函数清单审计”。我一般会顺手敲一行which residues之类的命令,确认函数确实指向这个目录,避免后续被同名内置函数干扰。
把文件列表按名字过一遍,能看出设计者的大致分组。下表是我按功能族做的归类,每个族内部函数互相配合,跨族调用则构成完整工作流:
| 功能族 | 代表函数 | 典型用途 |
|---|---|---|
| 数据构造与仿真 | simslc、simulateslc、simstack、simnoise、siminterf | 生成模拟SLC、多时相堆叠、相位噪声注入、模拟干涉图 |
| 干涉处理 | cpxmultilook、oversample、normalize、cpxdetrend | 复数多视降噪、过采样插值、复数归一化、复相位趋势去除 |
| 相位解缠 | residues、mph、myrect、std_phase、std_phasePS | 残差点定位、路径跟踪解缠、区域选择、相位质量评估 |
| 几何形变与可视化 | heightamb、plotdem、freadhgt、fwritehgt、plotcbar、cpt2map | 高程模糊度计算、DEM读写与显示、色标渲染 |
从这个结构能看出,工具箱的目标不是“读取原始SAR数据然后输出形变场”的黑匣子,而是把InSAR处理里最核心、最需要反复调试的算法环节暴露出来。比如cpxmultilook负责复数多视,residues负责定位残差点,mph负责路径跟踪解缠——这三者的组合就是经典的解缠前处理链路。
2.2 模拟数据族是切入点:仿真SLC、堆叠与噪声参数的选型
真实InSAR数据处理的第一个门槛是数据准备:两景SLC需要精确配准、基线估计、轨道状态向量。新手往往卡在这里,连干涉图都生成不了。这个工具箱把simslc、simstack、simnoise放在一起,意思很明确:先造数据,把算法链路跑通,再去碰真实数据。
我一般会先用一个高斯漏斗形变场做模拟实验:定义一个地形面、叠加一个形变面,按相位公式转换成两幅SLC的相位差。simslc这类函数在平面波近似下做的事情,就是把这个相位差变成复数数组。simstack则用来生成多时相堆叠,适合测试时间序列分析;simnoise负责给SLC加相位噪声,用来模拟时间去相关。
三个参数需要认真选:波长、斜距、垂直基线。C波段波长约0.056米,垂直基线取80米左右,入射角约0.41弧度,这三者决定地形相位和高程模糊度的比例。很多人在模拟阶段随意填基线,结果地形相位坡度太陡,后面的解缠算法直接被密集条纹淹没。先跑通模拟,再根据实际数据调整这些参数,才是合理的顺序。
2.3 干涉与解缠链路:先质量评估后路径跟踪的标准动作
干涉相位处理的常规链路是:复数多视 → 共轭相乘生成干涉图 → 相位滤波 → 残差点统计 → 解缠。这个顺序不能乱,否则解缠结果会很难看。
cpxmultilook做的是复数域的多视平均,把复数幅度和相位一起平均,而不是只处理实部或幅度图。多视视数越大,相位噪声越低,但分辨率也越差。residues计算干涉图的残差点,也就是相位环绕的拓扑缺陷位置。残差点越少,解缠越容易;残差点密集时,路径跟踪算法会绕出很多不连续线,产生条带跳变。
mph是路径跟踪类解缠的典型实现,输入通常是缠绕相位图、权重图(一般用相干性或幅度归一化值)、残差点列表和有效像元掩膜。接真实数据时,我会先用std_phase或std_phasePS估算每个像元的相位标准差,把质量太差的像元直接屏蔽掉,再进解缠。工具箱也提供了myrect这样的矩形区域选择工具,方便把处理范围限制在感兴趣区。这一整套组合,其实就是一本可以动手翻的“解缠算法教科书”。
3. 跑通一次合成形变场实验:从SLC造数到形变反演的完整流程
3.1 步骤一:用基础复数运算造一对带形变的SLC
模拟数据是整个实验的地基。先构造一个256乘256的高斯漏斗形变场,再依据平面波近似的相位公式生成两幅SLC。代码如下:
% 参数区:C波段波长、斜距、垂直基线、入射角 lambda = 0.056; % 波长,单位m,约5.6cm R0 = 850000; % 参考斜距,单位m Bperp = 80; % 垂直基线,单位m theta = 0.41; % 入射角,单位rad x = linspace(-5, 5, 256); [X, Y] = meshgrid(x, x); topo = 20 * exp(-(X.^2 + Y.^2) / 4); % 地形高程,单位m defo = 15 * exp(-((X-0.8).^2 + (Y+0.6).^2) / 2.5); % 形变场,单位m phase_topo = 4*pi/lambda * Bperp/(R0*sin(theta)) * topo; % 地形相位 phase_ref = 4*pi/lambda * Bperp/(R0*sin(theta)) * (0.05*X); % 线性轨道趋势 phase_defo = 4*pi/lambda * defo; % 形变相位 slc1 = exp(1i * (phase_topo + phase_ref + 0.1*randn(size(X)))); slc2 = exp(1i * (phase_topo + phase_ref + phase_defo + 0.1*randn(size(X))));这段代码用复数指数直接构造SLC,幅度默认为1,相位由地形、线性趋势和形变三部分叠加。phase_ref模拟的是轨道误差造成的线性相位坡道,真实数据里通常需要去平地效应来移除,这里主动加进去,是为了后面验证解缠链路能否正确恢复。
参数选择上,defo的幅度15米偏大,但这在模拟里是故意的,因为相位解缠后的跳变越明显,越容易检验算法的鲁棒性。如果形变幅度只有几毫米,相位变化太小,反而不容易判断解缠结果是否出错。实际跑通后,可以把defo改成0.02甚至0.005,模拟更接近真实的地表沉降。
3.2 步骤二:复数多视、干涉图生成与残差点统计
生成两幅SLC后,先做多视降噪,再做共轭相乘得到干涉图,最后统计残差点:
% 距离向5视,方位向1视,视数越大噪声越低但分辨率越差 looks_r = 5; looks_a = 1; multi1 = cpxmultilook(slc1, looks_r, looks_a); multi2 = cpxmultilook(slc2, looks_r, looks_a); interf = multi1 .* conj(multi2); % 干涉图:共轭相乘取相位差 phase_i = angle(interf); % 缠绕相位,范围[-pi, pi] amp_i = abs(interf); % 幅度图,可用于质量权重 resid = residues(phase_i); % 残差点坐标与极性 figure; plot(resid(:,1), resid(:,2), '.'); title('残差点分布');干涉图生成这一步,90%的新手会翻车:直接把SLC的实部相减,或者把幅度图相减,结果全是噪声。正确做法是复数共轭相乘,angle取出相位差,这才能得到反映形变的干涉条纹。
cpxmultilook的输入参数顺序在不同工具箱里不完全一致,如果发现输出尺寸不对,把两个视数调换再试。residues的输出格式一般是N行2列的坐标数组,N是残差点个数,每一行的两个值分别是行列位置。画出来之后,如果残差点在整个图上均匀密集分布,说明多视视数不够或者噪声太大;如果只在边缘稀疏分布,说明数据质量可以进入解缠阶段。
3.3 步骤三:最小费用流解缠与形变场反演
有了缠绕相位、质量权重和残差点,就可以调用mph做路径跟踪解缠:
mask = ones(size(phase_i)); % 掩膜:全部有效 weight = amp_i ./ mean(amp_i(:)); % 用幅度归一化构造质量权重 unwrap_phase = mph(phase_i, weight, resid, mask); % 解缠入口 % 模拟数据里已知地形和轨道相位,直接减去,真实数据要用DEM合成相位再减 unwrap_phase = unwrap_phase - phase_topo - phase_ref; defo_est = unwrap_phase * lambda / (4*pi); % 相位转形变,单位mmph这类路径跟踪解缠的常见接口约定是:第一个参数是缠绕相位,第二个是权重图,第三个是残差点列表,第四个是有效像元掩膜。权重图的作用是引导解缠路径尽量绕过低质量像元,幅度归一化在这里是一个简单但有效的替代方案;如果有相干性系数图,用相干性做权重效果更好。
减去phase_topo和phase_ref这一步,对应真实处理里的“去地形相位”和“去平地效应”。真实数据场景下,需要用DEM配合卫星轨道参数正向模拟地形相位,而不是直接用已知数组相减。在这个模拟实验里,直接减掉即可,目的是验证解缠本身的正确性。
如果mph的输出还是出现在[-pi, pi]范围内的缠绕结果,说明当前工具实现的解缠输出可能做了相位重缠绕,需要检查函数注释,或者对结果再做一次展开。defo_est与真值defo的单位都是米,可以直接对比。
3.4 参数收敛性检查:多视视数与解缠结果的稳定性
解缠结果出来之后,不能只看单次输出就认为没问题。我的习惯是扫一组多视视数,观察解缠形变场的变化幅度:
for looks = [1 3 5 9] m1 = cpxmultilook(slc1, looks, 1); m2 = cpxmultilook(slc2, looks, 1); p = angle(m1 .* conj(m2)); % 当前视数下的缠绕干涉图 d = std(angle(exp(1i*(unwrap_phase - p)))); % 与参考解缠结果的相位差异 fprintf('looks=%d, phase diff std=%.3f rad\n', looks, d); end这段代码把不同视数下的干涉相位与参考解缠结果做差,再取缠绕后的标准差。如果视数从5提高到9,形变场变化小于0.5毫米,说明解缠结果基本收敛;如果差异大,说明原始相位噪声水平过高,需要回到滤波或者增加多视视数。这一步是很多人跳过但代价极高的检查,尤其是在准备把算法移植到真实数据之前。
4. 使用这个工具箱的避坑手册:五个常见现象的排查记录
4.1 现象一:干涉图出现密集条纹,解缠根本起不了步
生成干涉图后,如果整张图都是细密的条纹,像指纹一样,解缠函数几乎无法给出连续结果。原因是相邻像元之间的相位差超过了π,缠绕造成欠采样。这种状况通常是地形相位没有充分移除,或者模拟参数里垂直基线设得太大,导致高程灵敏度太高。
解决思路是先用heightamb算一下高程模糊度,也就是一个2π相位周期对应的高程变化量。比如C波段、垂直基线80米时,高程模糊度可能只有几十米,地形起伏稍大就会造成密集条纹。此时应减小基线,或者在生成干涉图之前增加多视视数,让像元尺寸变大,相位坡度相对变缓。工具箱没有独立的去平地函数,可以用cpxdetrend对复数干涉图做线性趋势去除,先把轨道相位项压下去。
4.2 现象二:解缠结果出现条带跳变,形变场无法解释
解缠输出后,画出的形变场沿着某些行列方向出现明显的台阶状跳变,像地垒一样一节一节。原因通常是残差点密集区域形成了解缠路径无法绕过的切割线,最小费用流算法被迫让相位跳变集中在某一条线上,从而产生条带。也可能是低相干像元没有屏蔽,解缠路径把噪声相位当成真实信号传播。
解决方法是按质量图做掩膜:先用std_phase或std_phasePS计算相位标准差,把标准差超过阈值比如0.3弧度的像元在掩膜里置零,再重新解缠。另一个实用技巧是用myrect把处理范围限制在形变场明显且相干性好的区域,避免边缘低质量像元污染全局路径。
4.3 现象三:函数名与新版MATLAB函数冲突,调用结果对不上
工具箱里有一批函数叫iseven、isint、isscalar、isvector,这些函数在老版本MATLAB里需要自己定义,但新版某些工具箱已经内置了同名功能。如果which iseven指向的是MATLAB内置目录,而不是工具箱目录,就会出现装好了却用不上,或者行为不一致的诡异问题。
我的处理办法是,在添加到路径之后立刻用which批量检查一遍关键函数,确认全部命中工具箱目录。如果发现冲突,优先把工具箱目录放到搜索路径最前面;如果还是不行,就把冲突函数改名后统一修改引用处。另外,工具箱路径里不要有中文、空格或特殊字符,某些老脚本对路径解析不健壮,会直接报Undefined function,排查起来非常玄学。
4.4 现象四:freadhgt读取结果方向颠倒或尺寸不对
用freadhgt或freadbk读取外部生成的DEM或二进制相位数据时,读出来的矩阵要么是上下颠倒,要么整体斜着错位,数值范围还完全不对劲。这通常不是函数坏了,而是文件格式没对上:字节序、数据类型、行数列数顺序、是否有文件头,这些任何一项不对,读出来的都是乱码。
排查顺序是:先用freadbk分别尝试'int16'和'float32'两种类型读取,看数值范围是否合理;再核对数据写入时的尺寸是行优先还是列优先,MATLAB的fread默认按列读,如果文件是按行存储,需要先转置或者调整尺寸顺序。写回时用fwritehgt,保持与读取一致的数据类型和行列数,否则下次读出来还是错。最后用plotdem可视化结果,如果地形轮廓能正确呈现,说明尺寸和方向都对上了。
4.5 现象五:simnoise加噪后反演不出形变
在模拟数据里叠加噪声,目的是模拟真实时间去相关,但噪声参数设置不当会把形变条纹完全淹没,解缠后恢复的形变场和真值差得很远。常见原因是相位噪声标准差给得过大,或者噪声空间相关尺度与像元尺寸不匹配,导致相位残差点密度过高。
这里我的经验是先做一条逐级加噪的曲线:从0.1弧度开始,每步增加0.1弧度,每次记录解缠形变场与真值的均方根误差。你会看到误差在某个噪声水平之后突然飙升,这个拐点就是该基线、该视数条件下的容噪极限。真实数据应用时,用std_phase估算实际相位噪声,如果超过这个极限,就需要提高多视视数、滤波或更换时相跨度更短的数据对。
5. 把“验证回路”焊死在流程里:合成干涉的误差定性实验
真实数据最麻烦的地方在于没有“真值”可以对照。而合成数据的优势是已知形变场,可以构建一个闭环验证:输入已知形变 → 生成SLC → 多视干涉 → 解缠反演 → 对比真值。这个回路我每次换工具、换参数、换数据区域都会强制跑一遍。
用第3章的结果继续往下做残差分析:
% 解缠相位与输入形变真值的残差(缠绕处理,避免2π跳变假象) residual = angle(exp(1i * (unwrap_phase - phase_defo))); misfit = std(residual(:)); fprintf('相位残差标准差: %.3f rad\n', misfit); figure imagesc(residual); colorbar; title('解缠相位与真值的残差分布(rad)');把残差画出来之后,重点看两个东西:一是整体标准差,二是残差的空间分布。C波段下,相位残差标准差0.3弧度对应形变误差约1.3毫米;如果残差只在形变场边缘高梯度区出现,说明解缠算法在相位跳变处有局部误差,这部分像元的形变结果应当标记为不可信而不是直接使用。如果残差在低相干区大范围铺开,说明多视视数或者掩膜策略需要调整。
从那以后,我每次拿到新的解缠参数或者滤波方案,都会先跑一遍这个合成回路,确认误差在可接受范围后再碰真实数据。这个习惯帮我筛掉了至少一半看似合理实则陷阱重重的参数组合。希望帮到你。
本文还有配套的精品资源,点击获取