ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

多波束与侧扫声纳数据融合的底质分类实践指南

2026/9/18 16:36:47 拓冰建站 浏览量
多波束与侧扫声纳数据融合的底质分类实践指南 简介一份面向海洋测绘与海底底质分类研究者的技术资料文档聚焦大数据背景下多波束与侧扫声纳数据的融合处理与分类应用适合从事声纳数据处理、海洋遥感及机器学习算法研究的相关人员参考。全文系统论述了多波束测深数据的姿态改正、吃水改正、声速改正与滤波方法以及侧扫声纳图像的斜距改正、灰度均衡和去噪增强流程。针对多源数据融合提出基于等深线和轮廓线的同名特征点配准法并利用二进小波变换实现图像融合在底质分类环节结合影像纹理与多重分形特征引入遗传算法优化的BP神经网络及SOM网络进行监督与非监督分类展示了从数据预处理到智能识别的完整技术路线。资源为单个PDF文档大小7.53MB已有359人学习下载对于海洋测绘、环境监测及大数据算法应用领域的科研与工程人员具有较高的参考价值。1. 从两套声纳数据到一张底质分类图多波束测深系统和侧扫声纳是海洋勘察里搭配最频繁的一对组合但绝大多数项目直到交付数据库时两者仍然各存各的多波束输出规则格网的 bathymetry侧扫输出带斜距校正的 mosaic 影像。等到做海底底质分类时才发现单靠多波束的深度和反向散射强度分得出硬底和软泥却分不出沙波区和砾石滩的纹理差异单靠侧扫影像能看到沉船、沙波和岩礁的轮廓却拿不到这些目标所在位置的真实水深和坡度。数据融合要解决的正是这种“各有各的盲区”的问题——把多波束测深网格提供的地理位置和地形参量与侧扫声纳影像提供的灰度纹理信息放进同一个坐标框架和特征空间里让分类算法同时利用两者的互补信息。这篇文章面向的是正在做海底勘察数据处理、或者准备把多波束和侧扫数据喂给机器学习模型的工程师我会把融合思路、处理流程、特征提取和分类落地讲完整。2. 融合前必须想清楚两种声纳的数据到底差在哪2.1 波束脚印与像素的差异为什么不能直接叠加多波束和侧扫声纳虽然都往海底发射声波但它们的观测几何和采样逻辑完全不同。多波束换能器阵列在垂直航迹方向发射一个扇形波束通过接收阵列的相位差来估计每个波束到达海底的到达角和往返时间最终输出的是每个波束脚印对应的坐标和水深值。侧扫声纳则发射一个很宽的、垂直于航迹的波束接收来自海底不同掠射角的散射回波强度输出的是沿航迹方向的一条条 scan line每条 scan line 上每个像素的灰度值代表该斜距位置的后向散射强度。这两种数据最直观的差别是空间形态多波束水深点的脚印直径随水深增大而增大浅水区可能只有几十厘米深水区能达到数米而侧扫声纳的像素分辨率通常由斜距采样率和脉冲宽度决定往往比同区域多波束脚印更细。更麻烦的是坐标定位方式——多波束每个测深点都有独立的经纬度和深度可以直接构造成散点或者格网侧扫影像在做 slant range correction 之前像素在水平方向上的位置是斜距不是平面距离如果直接拿未校正的侧扫影像和多波束格网叠加海底隆起的地方会出现几何错位。常见的做法是先对侧扫数据做slant range correction把每个像素从斜距映射到水平距离再根据声速剖面和拖鱼/船体姿态做 geo-referencing。这一步做完侧扫影像在平面位置上才具备和多波束格网叠加的基础。即便如此两者的目标分辨率仍然不一致多波束格网常用的是 1m 到 5m 的网格间距侧扫 mosaic 则可能到 0.5m融合时要么把侧扫重采样到多波束格网分辨率要么反过来把多波束派生特征重采样到侧扫像素分辨率具体取决于下游分类想要保留哪种信息。2.2 多波束能提取的派生特征不止是水深多波束数据经过 tide correction、声速剖面修正和异常值剔除之后可以生成高精度的数字水深模型DBM。但从 DBM 中除了水深本身还能提出很多底质分类有用的特征这是融合时的核心价值之一。坡度是最直接的例子。海底底质分类中基岩露头区往往坡度较大而泥质平原坡度很小所以坡度是区分硬底和软底的重要线索。但我一般不会直接用原始 DBM 求最大坡度而是先做一次低通滤波再求因为多波束数据在深水区的噪声常常会带来假坡度。水深方差也能用它刻画的是微地貌起伏沙波区的水深方差明显大于平坦泥底。除了这些地形因子多波束的 backscatter 强度数据也是重要输入。很多多波束系统在测深的同时会记录海底反向散射强度优化后可以作为底质分类的强度特征比如基准强度、强度方差、强度随入射角的变化斜率。需要提醒的是多波束 backscatter 强度与侧扫影像的灰度不是一回事前者经过 AVG角响应增益补偿校正后者经过 TVG时间增益补偿两者的辐射尺度不同融合前分别归一化即可不必强行统一。表多波束数据可提取的底质分类特征类型特征类型计算方式底质指示意义水深DBM 直接取值区分不同沉积环境坡度取 DBM 梯度模长岩礁与泥质平原区分粗糙度局部窗口内水深标准差沙波、砾石区反映明显地形起伏窗口内最大最小水深差识别陡坎、海沟反向散射强度多波束原始强度归一化硬底回波强软泥回波弱强度方差局部窗口强度标准差混合底质识别这些特征在 GIS 里用邻域统计就能算比如在 QGIS 的栅格计算器或者 ArcGIS 的焦点统计里做。但在批量处理多个测区时脚本方式效率更高后面章节会给具体方案。2.3 侧扫声纳能提取的特征纹理比灰度更可靠侧扫影像上硬底质的后向散射强度高显示为亮色泥质软底散射弱显示为暗色。但仅凭灰度值做分类非常不可靠因为声呐方程中的传播损失、掠射角变化和 TVG 参数都会影响绝对灰阶。所以行业里做侧扫底质分类重点是纹理特征和局部统计特征而不是单像素灰度。GLCM灰度共生矩阵是侧扫影像底质分类中使用最广泛的特征提取方法。通过计算某个距离和方向上的像素对灰度共现频率可以导出对比度、能量、熵、相关性等二阶统计量。在侧扫影像中砾石滩的灰度变化剧烈对比度特征值高泥质底灰度均匀能量高、熵低。另一个常用特征是局部二值模式LBP它对光照变化不敏感适合侧扫灰度存在条带差异的情况。需要说明的是侧扫影像在 mosaic 过程中经常存在航迹间的辐射差异同一底质在不同条带内的灰度可能不同。因此在提取纹理特征之前我一般会对 mosaic 做一次分条带的直方图匹配或者从每一 ping 数据中做相对辐射归一化否则 GLCM 特征会在条带接边处出现明显的伪纹理。3. 多波束与侧扫声纳数据融合的层次与坐标基础3.1 融合的三个层次数据级、特征级、决策级传感器数据融合在理论上分三个层次多波束和侧扫声纳的融合也同样适用。数据级融合要求两种数据在像素级严格对应这对侧扫声纳和多波束来说很难做到因为分辨率差异、采样几何差异使它们天然不在同一采样网格上强行重采样到同一像素格网会引入插值误差。因此在实践项目中数据级融合并不常见。特征级融合是主流做法分别从多波束 DBM 和侧扫影像中提取特征形成一组多通道特征图每个位置上的特征向量由两部分特征拼接而成。例如在某个像元位置上水深 42.3m、坡度 3.2 度、粗糙度 0.7m、侧扫 GLCM 对比度 0.43、GLCM 熵 6.1这些数值拼成一个五维向量供后续分类模型使用。特征级融合的好处是允许两种数据保持各自最佳分辨率再在统一的格网上合成。决策级融合则是各自先做分类再用投票、D-S 证据理论等规则合成结果。多波束分类结果和侧扫分类结果可能有冲突比如侧扫影像显示亮斑疑似岩石但多波束坡度很小此时决策级融合需要用置信度或证据权重来处理。实际应用中特征级融合的效果通常优于决策级融合因为分类器能直接学习到两个传感器特征之间的相关性。3.2 坐标统一与网格对齐的具体操作无论选哪个融合层次坐标统一都是绕不开的第一步。多波束测深数据的坐标通常是 WGS84 经纬度加深度或者 UTM 投影坐标加高程侧扫数据后处理软件如 SonarWiz、Discover、Triton输出 mosaic 时也会指定投影坐标系。两个图层拿到 GIS 里后第一步就是确认二者坐标系完全一致否则叠加时会出现整体偏移。坐标一致之后还要处理网格对齐问题。常见做法是以多波束 DBM 的格网为基准定义网格的原点、cell size 和行列数然后用双线性插值把侧扫 mosaic 重采样到这个网格上。反过来以侧扫像素为基准也可以但侧扫 mosaic 的像素尺寸往往很小会导致多波束特征被插值出大量冗余增大内存和计算量。我一般以多波束 DBM 格网为基准同时把多波束派生特征保持在原始分辨率只侧扫做一次重采样。以下是用 GDAL 完成坐标统一和重采样的最小 Python 脚本也是一个可以直接套用的融合预处理流程from osgeo import gdal, gdalconst # 打开多波束 DBM以其为基准网格 dbm_path multibeam_dbm.tif sidescan_path sidescan_mosaic.tif dbm gdal.Open(dbm_path, gdalconst.GA_ReadOnly) gt dbm.GetGeoTransform() proj dbm.GetProjection() cols dbm.RasterXSize rows dbm.RasterYSize # 用 gdal.Warp 完成侧扫影像的投影转换和重采样 result gdal.Warp( sidescan_regridded.tif, sidescan_path, dstSRSproj, formatGTiff, resampleAlggdalconst.GRA_Bilinear, outputBounds(gt[0], gt[3] gt[5] * rows, gt[0] gt[1] * cols, gt[3]), widthcols, heightrows ) result None这段脚本的核心逻辑是先读取多波束 DBM 的地理变换参数和投影信息再用 gdal.Warp 将侧扫影像投射到同样的坐标范围和网格尺寸。outputBounds参数四元组顺序是左上角 X、左上角 Y、右下角 X、右下角 YGTiff 格式无需显式指定 driverGDAL 会根据扩展名推断。重采样算法用的是双线性如果后续要提取纹理特征也可以用三次卷积避免平滑导致纹理退化。3.3 融合数据中的位置精度误差控制坐标统一后还有一个容易忽视的问题多波束和侧扫声纳在航迹方向上的位置精度存在系统性偏差。多波束利用 GNSS 定位船体姿态通过 MRU 测量精度相对可控侧扫如果是拖鱼模式拖鱼位置是根据电缆放出长度和入水角度估算的拖鱼深度在浅水区变化会直接导致侧扫拖迹偏离船体 GNSS 位置这在侧扫 mosaic 上表现为图像沿航迹方向发生偏移。融合前检查这种偏移的最直接方法是在 GIS 中打开两个图层找一个特征明显的海底目标——沉船、礁石、管道等——比较其在 DBM 和侧扫影像上的位置差值。如果偏差大于一定阈值说明侧扫的 layback 参数没有校正好需要回到侧扫后处理软件中调整拖鱼位置偏移而不是在融合阶段做位移补偿。人工校正拖鱼位置后再重新导出 mosaic比在融合脚本里硬移像素靠谱得多。4. 构建多波束与侧扫声纳融合特征集并训练底质分类模型4.1 样本数据准备与标签设计融合特征集准备好之后下一个关键步骤是准备训练样本。底质分类的标签来源有三种常见方式一是采样点比如抓斗取样、箱式取样获得的点位底质类型二是水下视频或照片判读三是根据已知地质资料划分的区域。采样点是最可靠的但往往数量有限一个测区可能只有几十个点直接训练机器学习模型容易过拟合。应对小样本的常见做法是将每个采样点扩大为一个邻域窗口窗口内每个像素都继承该点位的类别标签并提取对应窗口的特征。这里的窗口大小选择有讲究如果开 3x3样本数量增加有限如果开 15x15则可能跨越不同底质边界把混合区样本引入训练集。我一般用 5x5 或 7x7同时按底质类别做分层抽样保证各类别样本量大致均衡。底质分类的类别粒度也要提前确定。常见的分类体系有 Folk 分类和 Wentworth 粒度分级但工程上更多简化为岩石、砾石、砂、泥或这些类型的组合。如果采样记录中有“砂质泥”“泥质砂”这种过渡类型在类别映射时要决定是保留为独立类别还是并入主类。保留过渡类型会增加分类难度但信息更完整这取决于最终应用对分类精度的容忍度。4.2 特征融合与归一化的完整代码下面给出用 Python 完成特征提取、融合和归一化的完整流程代码。数据格式假设为 GeoTIFF多波束 DBM 一个文件坡度特征一个文件粗糙度特征一个文件侧扫灰度一个文件。实操中这些特征栅格可以用 QGIS 或 GDAL 先行生成也可以在本代码中直接计算这里为了代码简洁假设它们已经存在。import numpy as np import pandas as pd from osgeo import gdal from sklearn.preprocessing import StandardScaler def read_raster(path): ds gdal.Open(path, gdalconst.GA_ReadOnly) band ds.GetRasterBand(1) arr band.ReadAsArray() ds None return arr # 读取所有特征栅格 depth read_raster(dbm.tif).astype(np.float32) slope read_raster(slope.tif).astype(np.float32) roughness read_raster(roughness.tif).astype(np.float32) sidescan read_raster(sidescan_regridded.tif).astype(np.float32) # 将多通道特征堆叠为一个三维数组 (rows, cols, features) features np.stack([depth, slope, roughness, sidescan], axis-1) rows, cols, _ features.shape # 生成标签栅格假设已有标签点栅格化文件格式也为 GeoTIFF labels read_raster(labels_resampled.tif).astype(np.int16) # 取有效样本所有特征非空且标签大于0 mask (np.nanmin(features, axis-1) -9999) (labels 0) X features[mask] y labels[mask] # 特征名称后续输出特征贡献度要用 feature_names [depth, slope, roughness, sidescan_intensity] # 标准化 scaler StandardScaler() X_scaled scaler.fit_transform(X) # 查看各类别样本量 print(pd.Series(y).value_counts())这段代码的逻辑要点在于先堆叠特征通道再用一个布尔掩码过滤无效像元和背景像元。labels_resampled.tif需要预先将采样点矢量栅格化为与特征栅格完全相同的网格可以用 GDAL 的 RasterizeLayer 完成。标准化时只需要对特征向量做标签不需要。如果类别样本量极不均衡可以考虑后续在模型中设置 class_weight。4.3 随机森林与梯度提升的分类效果对比底质分类模型的选择上随机森林和 XGBoost/LightGBM 是比较稳妥的起点。随机森林对特征交互不敏感、不需要过度调参、能输出特征重要性适合样本量不大、特征维度不高的场景。梯度提升模型通常精度略高但调参成本高且小样本下容易过拟合。用随机森林分类器在融合特征上完成训练和评估的最小代码如下from sklearn.model_selection import train_test_split from sklearn.ensemble import RandomForestClassifier from sklearn.metrics import classification_report, confusion_matrix # 划分训练集和测试集按类别分层抽样 X_train, X_test, y_train, y_test train_test_split( X_scaled, y, test_size0.3, stratifyy, random_state42 ) # 随机森林模型 rf RandomForestClassifier( n_estimators500, max_depth12, min_samples_leaf5, n_jobs-1, random_state42 ) rf.fit(X_train, y_train) # 预测并输出分类报告 y_pred rf.predict(X_test) print(classification_report(y_test, y_pred, digits3)) print(Confusion Matrix:\n, confusion_matrix(y_test, y_pred)) # 特征重要性 importance pd.Series(rf.feature_importances_, indexfeature_names).sort_values(ascendingFalse) print(importance)这里的stratifyy保证训练集与测试集中各类别比例一致对底质样本这种常存在类别不平衡的数据尤其重要。min_samples_leaf5限制叶子节点最小样本数能有效抑制过拟合配合适度 max_depth 即可。特征重要性输出会告诉我们四种特征中哪个贡献最大——实践中绝大多数情况下侧扫特征对区分硬底与软底的贡献突出而多波束坡度对岩礁识别贡献更大这正是融合的意义所在。4.4 与单一数据源分类的对比实验设计要验证融合是否有效需要设计对照组实验只用多波束特征训练一个模型只用侧扫特征训练另一个模型最后用融合特征训练第三个模型比较三者在同一测试集上的精度。这个对比直接回应了“融合是否有必要”的问题。对照实验的代码可以复用上面的随机森林训练流程只需修改 X 的构建方式。用多波束的三个特征训练时X features[:, :, :3]用侧扫时X features[:, :, 3:4]融合时X features。统一使用相同训练/测试划分固定 random_state和相同模型参数这样精度差异才归因于特征组合而不是模型变化。还需要注意的是坐标对齐误差也会影响对比结论。如果在重采样时侧扫影像与多波束格网存在偏移那么融合特征中同一个位置的侧扫灰度和水深其实并非来自同一海底位置分类精度会下降但原因不是融合方法本身。所以在对照实验之前先做目视检查或者计算两个图层与地面控制点的互相关偏移确认对齐质量。5. 融合分类结果的精度评估与验证技巧5.1 交叉验证在底质分类中的正确用法底质分类样本在空间上存在自相关性——相距 1m 的采样点类别几乎必然相同相距 100m 的采样点类别也可能相同。这种情况下使用普通 K 折交叉验证会高估模型精度因为训练集和验证集中可能含有空间上相邻的样本相当于模型已经见过答案的近似版本。常见改进是使用基于空间的分组交叉验证按采样点所在区块分组将整个区块作为验证集。如果采样点是随机分布的可以按空间网格划分区块比如将测区分成多个 500m x 500m 的网格每个网格内的样本作为一个分组。用 scikit-learn 的GroupKFold可以很容易实现from sklearn.model_selection import GroupKFold # group_id 为每个样本所属的空间区块编号 # 例如将样本坐标分入对应的网格 group_kfold GroupKFold(n_splits5) fold_scores [] for train_idx, val_idx in group_kfold.split(X_scaled, y, groupsgroup_ids): rf_clf RandomForestClassifier( n_estimators500, max_depth12, min_samples_leaf5, n_jobs-1, random_state42 ) rf_clf.fit(X_scaled[train_idx], y[train_idx]) score rf_clf.score(X_scaled[val_idx], y[val_idx]) fold_scores.append(score) print(f空间交叉验证精度: {np.mean(fold_scores):.3f} (/- {np.std(fold_scores):.3f}))group_ids需要用样本的经纬度或行列号按网格划分生成核心思想是同一网格的样本只进训练集或只进验证集。由此得到的精度更接近模型在真正未探测海域的表现也更经得起审查。5.2 分类结果图中查不准的区域该怎么排查分类完成后输出的底质分布图通常在块状均匀底质区域表现良好问题集中在两类区域一是不同底质类型的过渡带二是侧扫影像中存在阴影区或盲区的位置。过渡带本来就是模糊分类问题抓斗采样只能得到点位类型而点位附近几米内的底质可能已经变化这种标签噪声会显著影响模型学习。排查时先做分类置信度图。随机森林的predict_proba能输出每个类别的概率取最大概率作为置信度。在 GIS 中把置信度图叠加在侧扫影像上低置信度区域往往对应阴影区、测线边缘或粒度过渡区。如果大量低置信度区域都在阴影区可以考虑在特征提取时把阴影区域标记为 missing value而不是让它用暗灰度参与训练——阴影区的灰度低并不是因为底质软而是没有回波。如果某类底质整体查不准比如岩礁总是被误分为砾石那么回顾训练样本大概率是岩礁样本太少或采样位置不够典型。此时补充采样点比调模型参数更有效因为分类问题本质是特征空间中类别样本的分布边界问题样本量不够任何算法都无能为力。本文还有配套的精品资源点击获取