4. 声呐图像预处理与增强

前视声呐、侧扫声呐或多波束成像声呐输出的原始图像,与光学相机图像有本质差异:它记录的是回波强度而非反射光,成像过程受波束宽度、传播损失、混响、多径和底质特性共同影响。典型原始声呐图往往呈现三个特征:整体偏暗、目标与背景灰度接近(低对比度)、叠加大量斑点噪声与条纹干扰。如果直接把这样的图像送入边缘检测或目标识别环节,检测算子会把噪声当成边缘,分割阈值也难以稳定选取。因此,预处理与增强是避障感知链路中不可跳过的一环,其目标不是"把图变好看",而是让后续算法能稳定地提取目标轮廓与障碍物区域。

一、声呐图像的三类典型退化

理解退化机理才能选对方法。第一类是斑点噪声(speckle):声呐回波由大量随机散射体叠加而成,相干成像导致相邻像素灰度随机起伏,表现为颗粒状明暗斑,属于乘性噪声,用简单的均值滤波会同时抹平目标边缘。第二类是低对比度与亮度不均:声波随距离衰减,图像近端亮、远端暗,目标回波强度差异被压缩在很窄的灰度区间内。第三类是条纹与旁瓣干扰:波束旁瓣、水面/水底反射和多径效应会在图像中形成亮线或弧形伪影,容易被误判为障碍物。

针对这三类退化,工程上通常按"去噪 → 灰度拉伸 → 边缘增强"的顺序处理,但顺序并非绝对,例如强条纹干扰可先做方向性滤波再降噪。下图给出了一条完整的声呐图像增强处理链,以及每一级处理前后的典型图像特征变化:

原始声呐图 暗、噪、目标模糊 滤波去噪 斑点减弱、边缘保留 灰度变换 动态范围拉开、目标变亮 边缘增强 轮廓清晰、可分割 输出 增强图 → 检测/分割 各级处理的关键参数与作用 滤波去噪:中值滤波窗口 3×3~5×5(去椒盐/斑点);Lee 滤波 / 双边滤波(保边去乘性噪声) 灰度变换:对数变换压缩远端衰减;CLAHE 分块直方图均衡,clipLimit≈2.0,tile 8×8 边缘增强:Sobel / Canny 提取梯度;形态学顶帽突出亮目标;非锐化掩模提升局部对比 判据:目标与背景灰度差增大、边缘连续、伪影不新增;用同一组参数复现

二、滤波去噪:先分清噪声类型再选算子

声呐图像的斑点噪声是乘性噪声,模型可近似写为 g(x,y) = f(x,y)·n(x,y),其中 f 为真实回波强度,n 为随机调制因子。对这类噪声,线性均值滤波虽然能压低方差,但会把目标边缘一起模糊,导致后续边缘检测的定位精度下降。实践中更常用三类方法:

  • 中值滤波:对 3×3 或 5×5 邻域取中值,对孤立的亮斑/暗斑(椒盐型干扰)抑制效果好,计算量小,适合实时性要求高的前视声呐。缺点是窗口过大时细小目标会被吞掉。
  • Lee 滤波:针对乘性噪声设计,按局部方差与均值的比值自适应调整权重,在均匀区域强平滑、在边缘区域弱平滑,是声呐图像去斑的经典选择。
  • 双边滤波:同时考虑空间距离与灰度差,能在去噪的同时较好保持目标轮廓,代价是计算量高于中值滤波,适合离线或算力充裕的平台。

选择原则可以概括为:如果干扰以孤立亮点为主,优先中值滤波;如果整幅图颗粒感明显且目标较大,用 Lee 滤波;如果目标轮廓的保持比平滑程度更重要,用双边滤波。实际调参时,窗口尺寸应与目标在图像中的像素尺度匹配——目标只有十几个像素宽时,5×5 以上的窗口就可能把它抹掉。

三、灰度变换:把被压缩的差异拉开

声呐图像远端回波弱,灰度常集中在低值区,直接做全局直方图均衡往往把噪声也一并放大。更稳妥的做法是组合使用:

  1. 对数变换 s = c·log(1+r):压缩高灰度、扩展低灰度,正好对应声呐近端强回波、远端弱回波的分布,能提升远处目标的可见度。
  2. CLAHE(限制对比度自适应直方图均衡):把图像分成若干小块分别均衡,并用 clipLimit 限制对比度放大倍数,避免均匀水域区域噪声被过度增强。典型参数为 tile 8×8、clipLimit 2.0,可按图像尺寸微调。
  3. Gamma 校正 s = 255·(r/255)^γ:γ<1 提亮暗部,γ>1 压暗亮部,用于整体亮度偏置的快速修正。

判断灰度变换是否有效的依据不是"看起来更亮",而是目标区域与背景区域的灰度差是否增大、直方图是否从窄峰展宽为可分离的双峰或多峰。可以在处理前后各取一块目标区和一块纯背景区,计算两者均值之差,差值明显增大说明变换方向正确。

四、边缘增强:为检测算子准备干净的梯度

去噪和灰度拉伸之后,目标轮廓通常仍偏软。边缘增强的常用手段包括 Sobel 梯度、Canny 边缘检测、形态学顶帽变换和非锐化掩模。对声呐图像而言,有两点需要特别注意:其一,Canny 的双阈值对噪声敏感,应在去噪之后使用,且高阈值不宜设得过低,否则混响区域会产生大量伪边缘;其二,形态学顶帽变换(原图减去开运算结果)能突出比背景亮的孤立目标,对检测沉底或悬浮的小目标很有效,结构元素尺寸应略大于目标尺度。

五、实战任务:一段可复现的增强流程

下面给出一个基于 Python + OpenCV 的示例流程,输入为一幅单通道 8 位前视声呐灰度图(示例参数为合理假设,实际使用时按设备输出调整)。流程依次完成中值去噪、CLAHE 增强、Sobel 边缘增强,并输出处理前后的对比指标。

import cv2
import numpy as np

img = cv2.imread("sonar_raw.png", cv2.IMREAD_GRAYSCALE)

# 1) 中值滤波去斑点,窗口 3x3
denoised = cv2.medianBlur(img, 3)

# 2) CLAHE 灰度增强,tile 8x8,clipLimit 2.0
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
enhanced = clahe.apply(denoised)

# 3) Sobel 梯度幅值作为边缘增强图
gx = cv2.Sobel(enhanced, cv2.CV_32F, 1, 0, ksize=3)
gy = cv2.Sobel(enhanced, cv2.CV_32F, 0, 1, ksize=3)
mag = cv2.magnitude(gx, gy)
edge = cv2.normalize(mag, None, 0, 255, cv2.NORM_MINMAX).astype(np.uint8)

# 4) 定量对比:目标区与背景区灰度差
def region_mean(im, x, y, w, h):
    return float(im[y:y+h, x:x+w].mean())

tgt_before = region_mean(img, 120, 90, 40, 30)   # 目标区示例坐标
bg_before  = region_mean(img, 20, 20, 40, 30)    # 背景区示例坐标
tgt_after  = region_mean(enhanced, 120, 90, 40, 30)
bg_after   = region_mean(enhanced, 20, 20, 40, 30)

print("增强前目标-背景差:", tgt_before - bg_before)
print("增强后目标-背景差:", tgt_after - bg_after)

cv2.imwrite("sonar_enhanced.png", enhanced)
cv2.imwrite("sonar_edge.png", edge)

运行后应重点观察三件事:一是增强图中目标轮廓是否连续、是否出现新的亮斑伪影;二是"增强后目标-背景差"是否明显大于增强前(示例中若从约 15 灰度级提升到 40 以上,说明对比度改善有效);三是边缘图中混响区是否产生大片伪边缘。若伪边缘过多,应回头提高 Canny 高阈值或增大中值滤波窗口;若目标被抹掉,则应减小滤波窗口或降低 CLAHE 的 clipLimit。参数调整应遵循"一次只改一个变量、用同一幅图对比"的原则,保证结果可复现。

预处理参数没有放之四海皆准的固定值。建议为每型声呐建立一组基准参数,并在不同距离、不同底质(泥沙、岩石、水草)的样本上验证,记录目标-背景灰度差与伪边缘数量两个指标,形成可追溯的参数档案。
不要为了追求视觉上的"清晰"而过度增强。过度 CLAHE 或过强的非锐化掩模会把噪声放大成假目标,导致避障规划器对虚警做出急转或急停,反而降低航行安全性。增强的最终判据是下游检测与分割的稳定性,而非图像观感。