简介:这份资源面向从事遥感图像分析、地质灾害识别与深度学习目标检测的研究生、算法工程师及科研人员,提供一套可直接用于泥石流目标检测训练的标注数据集,帮助解决地质灾害遥感场景下样本稀缺、标注成本高的问题。压缩包共232个文件,包含116张JPEG遥感影像与116个对应的XML标注文件,采用VOC2007格式组织,可直接接入YOLO、Faster R-CNN等主流检测框架进行训练与评估,整体约5.53MB,体量轻便便于快速下载与本地调试。目前已有1095人学习下载,说明其在遥感地质灾害检测方向具有一定参考价值。读者可借助该数据集完成从数据加载、标注解析到模型训练与指标验证的完整流程,也可用于对比不同检测算法在泥石流目标上的表现,或作为自建数据集的格式参考与扩充基础。
1. 遥感影像泥石流检测数据集:从标签噪声到可复现训练样本
泥石流灾害的遥感识别,难的不是模型结构,而是数据。我见过太多团队拿着公开的遥感影像目标检测数据集直接开训,mAP 卡在 0.3 上不去,排查一圈发现标注框把整条沟道都框进去了,模型学到的其实是“沟谷纹理”而不是“泥石流堆积体”。遥感影像、泥石流、目标检测、数据集这四个词放在一起,真正要解决的问题是:如何把大幅面、多光谱、带地理坐标的卫星或航拍影像,切成模型能吃的切片,并配上语义一致的边界框。这篇面向的是手里有遥感影像、想跑目标检测但被数据卡住的从业者,也适合做地质灾害监测、应急测绘、山区基础设施巡检的工程师。下面按“数据从哪来 → 怎么标 → 怎么切 → 怎么训 → 怎么避坑”的顺序,把可复现的路径写清楚。
2. 泥石流目标检测的数据来源与标注体系
2.1 遥感影像获取:公开源与自采影像的取舍
做泥石流检测,第一步是确定影像源。常见做法有三类:一是公开的灾害应急影像,比如高分系列、Sentinel-2、Landsat 8/9 的灾后产品,空间分辨率从 10 米到 0.8 米不等;二是商业卫星存档,按景购买,适合做小范围高精度验证;三是无人机航拍,分辨率能到厘米级,但覆盖范围有限,适合做局部精细标注。
我一般会先拉一份 Sentinel-2 的灾后影像做粗筛,因为它的重访周期短、免费、波段全,能快速定位泥石流发生的沟谷位置。确定候选区域后,再去找对应的高分二号或无人机影像做精细标注。这里有个血泪经验:不要用灾前影像直接标注泥石流,因为泥石流是灾后堆积体,灾前影像上根本没有这个目标,标出来的框全是错的。
影像下载环节,如果做公开数据集复现,常见做法是用 Google Earth Engine 或 Copernicus Open Access Hub 按时间和区域筛选。下面是一段用 Python 的sentinelsat库检索 Sentinel-2 影像的示例,注意这里只做检索和下载,不涉及任何网络代理配置。
from sentinelsat import SentinelAPI, read_geojson, geojson_to_wkt from datetime import date # 连接 Copernicus Open Access Hub api = SentinelAPI('用户名', '密码', 'https://scihub.copernicus.eu/dhus') # 定义研究区,这里用 GeoJSON 文件描述泥石流沟谷范围 footprint = geojson_to_wkt(read_geojson('debris_flow_aoi.geojson')) # 检索灾后 30 天内的 Sentinel-2 L2A 产品 products = api.query( footprint, date=(date(2023, 7, 1), date(2023, 7, 31)), platformname='Sentinel-2', producttype='S2MSI2A', cloudcoverpercentage=(0, 20) # 云量低于 20% ) # 下载检索结果 api.download_all(products)这段代码的逻辑是:先定义泥石流发生的感兴趣区,再按时间窗口和云量阈值筛选影像,最后批量下载。参数上,cloudcoverpercentage建议设在 20 以下,山区云层厚,阈值太高会漏掉可用影像;date窗口不要超过 30 天,否则灾后堆积体可能被植被或后续降雨改变形态。如果下载速度慢,可以只下载 B02、B03、B04、B08 四个波段,减少数据量。
2.2 标注体系设计:框什么、不框什么
泥石流在遥感影像上的表现是:沟道内或沟口的浅色堆积体,纹理粗糙,形状呈舌状或扇形,与周围植被和基岩有明显色差。标注时最容易翻车的地方是边界模糊——堆积体边缘和冲积扇过渡带没有清晰界线。我的做法是:只框堆积体主体,即色调最浅、纹理最均一的那部分,边缘过渡带不纳入框内。这样标注一致性高,模型学到的特征也更稳定。
标注工具用 LabelImg 或 CVAT 都可以,导出 YOLO 格式的 txt 文件。类别名建议用debris_flow,不要用mudslide或landslide混用,因为滑坡和泥石流的影像特征差异很大,混标会让模型困惑。如果要做多类别,可以细分debris_flow_deposit(堆积体)和debris_flow_channel(流通区),但新手建议先做单类。
标注完成后,必须做一次交叉验证:让另一个人随机抽 10% 的框检查,如果 IoU 低于 0.7 的比例超过 15%,说明标注标准不一致,需要重新对齐。这个步骤很枯燥,但能省掉后面调参的很多玄学问题。
2.3 影像切片:大幅面遥感图怎么切成训练样本
遥感影像动辄上万像素,直接送进网络不现实。常见做法是滑窗切片,窗口大小 512×512 或 640×640,重叠率 20% 到 30%。重叠率太低会切断目标,太高会产生大量冗余样本。我的经验是:泥石流堆积体通常占几百到几千像素,512 窗口加 25% 重叠比较稳。
切片时要注意两个参数:一是stride,即滑动步长,一般设为window_size * (1 - overlap);二是min_area,即框面积小于多少像素的切片直接丢弃,避免大量背景样本。下面是一段切片脚本,输入是原始影像和 YOLO 格式标签,输出是切片后的图像和对应标签。
import cv2 import numpy as np import os def slide_crop(image_path, label_path, output_dir, window_size=512, overlap=0.25, min_area=200): img = cv2.imread(image_path) h, w = img.shape[:2] stride = int(window_size * (1 - overlap)) # 读取 YOLO 标签并转换为像素坐标 boxes = [] with open(label_path, 'r') as f: for line in f: cls, x, y, bw, bh = map(float, line.strip().split()) x1 = (x - bw / 2) * w y1 = (y - bh / 2) * h x2 = (x + bw / 2) * w y2 = (y + bh / 2) * h boxes.append([cls, x1, y1, x2, y2]) count = 0 for y in range(0, h - window_size + 1, stride): for x in range(0, w - window_size + 1, stride): crop = img[y:y+window_size, x:x+window_size] crop_boxes = [] for cls, x1, y1, x2, y2 in boxes: # 计算框与切片的交集 ix1, iy1 = max(x1, x), max(y1, y) ix2, iy2 = min(x2, x + window_size), min(y2, y + window_size) if ix2 - ix1 > 0 and iy2 - iy1 > 0: area = (ix2 - ix1) * (iy2 - iy1) if area >= min_area: # 转换为切片内的 YOLO 归一化坐标 cx = (ix1 + ix2) / 2 - x cy = (iy1 + iy2) / 2 - y bw_new = (ix2 - ix1) / window_size bh_new = (iy2 - iy1) / window_size crop_boxes.append(f"{int(cls)} {cx/window_size:.6f} {cy/window_size:.6f} {bw_new:.6f} {bh_new:.6f}") if crop_boxes: cv2.imwrite(os.path.join(output_dir, f"crop_{count}.jpg"), crop) with open(os.path.join(output_dir, f"crop_{count}.txt"), 'w') as f: f.write('\n'.join(crop_boxes)) count += 1参数说明:window_size根据 GPU 显存选,8G 显存跑 YOLOv8 建议 640,12G 以上可以 1024;overlap设 0.25 是平衡漏检和冗余;min_area设 200 像素是为了过滤掉被切碎的极小目标。切片后要检查一下,如果某个切片里框只占几个像素,这种样本对训练没帮助,反而会拉低召回。
3. 从 YOLO 格式到训练:泥石流检测模型的落地路径
3.1 数据集划分与 YOLO 配置文件
切片完成后,按 7:2:1 划分训练集、验证集、测试集。划分时要保证同一景影像的切片不跨集,否则验证集精度会虚高。常见做法是按影像编号分组,整组划入同一集合。
YOLO 系列的数据集配置文件debris_flow.yaml写法如下:
path: /data/debris_flow_dataset train: images/train val: images/val test: images/test nc: 1 names: ['debris_flow']这里nc是类别数,单类就写 1。如果做堆积体和流通区两类,改成 2,names对应写['deposit', 'channel']。路径用绝对路径,避免训练时找不到文件。
3.2 训练参数:泥石流检测的必调项
用 YOLOv8 或 YOLOv11 训练时,下面几个参数对泥石流检测影响最大:
| 参数 | 建议值 | 说明 |
|---|---|---|
| imgsz | 640 | 与切片窗口一致,不要随意改 |
| batch | 8~16 | 根据显存调,太小梯度不稳 |
| epochs | 100~200 | 泥石流样本少,需要多轮 |
| lr0 | 0.001 | 默认 0.01 容易震荡 |
| mosaic | 0.5 | 增强小目标,但泥石流形状特殊,别设 1.0 |
| degrees | 0.0 | 遥感影像有地理方向,旋转增强会破坏语义 |
训练命令示例:
yolo detect train data=debris_flow.yaml model=yolov8n.pt epochs=150 imgsz=640 batch=8 lr0=0.001 mosaic=0.5 degrees=0.0这里用yolov8n是因为泥石流目标特征相对明显,小模型够用。如果漏检严重,换yolov8m或yolov11s。mosaic设 0.5 而不是默认 1.0,是因为泥石流堆积体的形状和周边环境有强关联,过度拼接会引入不合理的上下文。
3.3 数据增强的边界:哪些增强能用,哪些会翻车
遥感影像的增强和自然图像不一样。翻转、裁剪、亮度调整可以用,但旋转、透视变换要慎用。泥石流沟谷的走向和山体阴影方向有地理意义,旋转 90 度后模型学到的“沟谷朝向”特征就乱了。我的做法是:只开flipud=0.5、fliplr=0.5、hsv_h=0.015、hsv_s=0.7、hsv_v=0.4,其他增强全关。
如果样本量少于 500 张,可以加copy_paste=0.3,把泥石流目标复制粘贴到其他背景上,但粘贴位置要避开道路和建筑,否则会引入虚假关联。
4. 泥石流检测数据集常见坑与排查
4.1 标注框把整条沟道框进去,模型学的是沟谷不是泥石流
现象:训练 loss 下降正常,但验证集 mAP 只有 0.2 左右,可视化预测框发现模型把整条沟谷都框了。
原因:标注时图省事,沿着沟道画了大框,把两侧山体也包进去了。模型学到的是“暗色沟谷纹理”而不是“浅色堆积体”。
解决:重新标注,只框堆积体主体。可以用 NDVI 阈值辅助:泥石流堆积体 NDVI 低,植被 NDVI 高,先算 NDVI 再目视检查边界。
4.2 切片重叠率太低,目标被切断导致漏检
现象:训练集里明明有泥石流样本,但模型在验证集上对同一区域漏检。
原因:切片时overlap设了 0.1,堆积体刚好跨在两个切片边界上,每个切片里都只有半个目标,标注时被min_area过滤掉了。
解决:把overlap提到 0.25 到 0.3,重新切片。检查方法是统计每个目标的框中心到切片边界的距离,如果小于 50 像素的样本占比超过 10%,说明重叠不够。
4.3 灾前灾后影像混用,标签语义矛盾
现象:模型在灾后影像上表现尚可,但在灾前影像上疯狂误检。
原因:训练集里混入了灾前影像,且把灾前的沟谷也标成了泥石流。灾前根本没有堆积体,标签是错的。
解决:严格按灾后时间窗口筛选影像,灾前影像只能做负样本,且不能标任何泥石流框。负样本比例控制在 1:3 以内,太多负样本会让模型偏向背景。
4.4 类别不平衡导致小目标召回低
现象:大块堆积体检测很好,但小规模泥石流(几十平方米)几乎全漏。
原因:小目标样本少,且切片后小目标在 640 图像里只有十几个像素,YOLO 的下采样倍率导致特征丢失。
解决:一是切片窗口降到 320,让小目标占比变大;二是开copy_paste增强小目标;三是把imgsz提到 1024,但显存要够。如果还不行,换带 P2 检测头的模型结构。
4.5 验证集精度虚高,测试集崩盘
现象:验证集 mAP 0.75,测试集只有 0.4。
原因:划分数据集时按切片随机分,同一景影像的切片同时出现在训练集和验证集,模型记住了这景影像的背景特征。
解决:按影像编号分组划分,整景影像要么全在训练集,要么全在验证集。分组后验证集精度会降,但测试集精度会升,这才是真实水平。
5. 泥石流检测数据集的进阶用法:半自动标注与跨区域验证
当标注量上来之后,纯手工标效率太低。我现在的做法是:先用一个在公开遥感数据集上预训练的检测模型(比如在 DOTA 上训过的模型)对泥石流影像做推理,生成粗框,再人工修正。这样标注速度能快 3 倍左右,但要注意预训练模型的类别和泥石流差异大,粗框的召回高但精度低,人工修正时主要做删框和调边界,而不是从零画框。
半自动标注的脚本逻辑是:加载预训练权重,对切片推理,把置信度高于 0.3 的框导出为 YOLO 格式,再导入 LabelImg 做修正。置信度阈值不要设太高,0.3 左右能保证召回,漏掉的框人工补。修正完成后,用修正后的数据微调模型,再跑一轮推理,迭代两三次,标注质量会明显提升。
跨区域验证是另一个容易被忽略的点。泥石流在不同气候区、不同岩性区的影像特征差异很大。在西南山区训的模型,直接拿到西北干旱区用,mAP 可能掉一半。我的习惯是:至少留一个完全不同流域的影像做测试集,不参与任何训练和调参。如果跨区域测试 mAP 低于 0.3,说明模型过拟合了局部纹理,需要增加不同区域的训练样本,或者用域自适应方法做特征对齐。
最后说一个我踩过的坑:不要用同一颗卫星的影像训和测。不同卫星的传感器响应、分辨率、波段设置都不同,模型会学到传感器特征而不是泥石流特征。训练集里至少混入两种卫星源,测试集用第三种,这样训出来的模型才有泛化性。希望帮到你。
本文还有配套的精品资源,点击获取