探地雷达的剖面图(B-scan)上,经常有一些横向几乎不变的条带或底色——直达波、天线环回响、系统本底。它们跟具体的地下反射没关系,却往往占了大头,把真正想看的弱反射压在下面看不清。背景去除就是想办法把这些共模背景估出来再减掉。

先跟 dewow 划清界限:dewow 沿时间轴(每道内部)去道自己的低频漂移;背景去除沿空间轴(道与道之间)去横向的共模背景。两者方向正交。统一写成一个公式就是 D − α·B̂——估一个背景 B̂,乘个强度系数 α 再减掉,alpha 默认 1.0 就是全减。

难点不在「减」,在「背景 B̂ 怎么估才估得准」。试下来几种路子各有擅长的场景。

mean / median:沿线平均,最朴素

最直接的是沿空间方向(跨道)求平均当背景。直达波这种几乎每道都一样的东西,一平均就冒出来了,减掉很干净。把均值换成中位数(median)就是 median 法,好处是抗异常——少数几道的强反射不会把整体背景带偏。

这一类对「横向基本恒定」的背景效果好。但雷达数据里的背景不总是规规矩矩水平的,有时候是斜的(剖面沿线有倾角)、有时候是周期性振铃(ringing),mean 沿线一平均,倾斜的条带平均不掉、振铃也对付不了,这时候就得换家伙。

SVD 低秩:背景本质是低秩的

换一个角度看:一条横向恒定的背景,在「道×时间」这个矩阵里其实就是秩为 1 的成分(每一道都差一个常数)。倾斜的条带也一样,本质还是秩 1,只是均值法没顺着它的斜路去减。

SVD 法就是利用这个——对数据矩阵做奇异值分解,最大那几个奇异值对应的,往往就是这些占大头的背景结构。砍掉前 k 个主分量(比如 k=1),用剩下的奇异值重构,背景就没了:

def _svd_background(data, k=1):
U, S, Vt = np.linalg.svd(data, full_matrices=False)
S[:k] = 0 # 砍掉前 k 个最大奇异值
return (U * S) @ Vt # 重构 = 背景

它的好处是数据驱动,不假设背景水平——倾斜条带、振铃这种 mean 减不动的,SVD 砍掉对应的秩就干净了。代价是要算一次 SVD,数据大的时候比 mean 慢,工程上可以降到 float32 省时间。

f-k 频域:压掉低空间波数

还有一招是变换到频率-波数域(f-k 域)处理。思路是:横向缓变的背景,在空间频率(波数 kx)上表现为低波数成分——波长很长、变化很慢。反过来,局部反射是高波数。所以在 f-k 域把低空间波数(|kx| 小于某个截止 fk_kcut)的成分抠出来当背景减掉,留下的就是局部变化:

截止 fk_kcut 的单位是「每道多少个周期」,默认取 0.02 左右,大致意思是波长超过 50 道的才算背景。这招对横向恒定的背景特别彻底,残差能压到很小,同时局部凸起(真正的反射)原样留下。它跟 SVD 都是「空间低通当背景、减完得空间高通」的思路,f-k 是频域的砖墙低通,更锐利。

alpha:留一手护住连续界面

有个旋钮 alpha 得单独说,它控制减多少。默认 1.0 是全减,但有时候不能减这么狠。雷达里有一类东西是「连续的水平界面」——层间脱空、连续裂隙,它们本身就是横向延展的,长得跟背景很像。背景去除开满,会把这种连续界面也当背景一起抹掉,该看到的病害反而没了。

碰到这种情况就把 alpha 调小(部分减除),或者把窗开大、甚至关掉这一步。经验上是:要同时看钢筋点状反射和脱空这种连续界面,alpha 不能给到 1,得留一部分背景护住连续界面。这也是背景去除最容易翻车的地方——减得太干净,连该留下的东西一起干净了。

怎么选

水平静态背景(直达波最典型)→ mean 就够,又快又简单;剖面有倾角、有振铃 → 上 SVD;横向强缓变背景、想干净留局部凸起 → f-k;碰到连续水平界面型病害 → alpha 调小或跳过这一步。位置上,背景去除放在 dewow 和带通之后、增益之前。

背景去除的核心其实就一句话:背景和反射在「空间方向上的变化快慢」上不一样,背景慢、反射快,想方设法把慢的估出来减掉就行。mean 是最朴素的估法,SVD 和 f-k 是更聪明的估法,alpha 是防误伤的保险——选哪个,看背景长什么样、有没有不能误伤的连续界面。