
简介这是一套面向目标检测任务的中文数据集聚焦泥石流与滑坡两类地质灾害场景适合用于训练YOLO、Faster R-CNN等模型。压缩包内包含2262张清晰图片配套VOC格式xml与YOLO格式txt标签共6508个矩形标注框其中landslide约6079框、Debris-flow约429框数据未经增强标注规范。包内总计2000个文件以xml标签为主辅以说明txt整体166MB目录按JPEGImages、Annotations、labels三文件夹组织便于直接接入训练流程。该资源已有653人浏览学习适合地质灾害识别、无人机巡检影像分析等方向的开发者与科研人员可省去采集标注时间直接用于模型训练与算法验证。1. 泥石流滑坡数据集这 2262 张图到底能做什么做地质灾害监测的人十有八九都卡在同一个问题上模型跑的通但一换场景就废。大家手里常用的公开数据集要么是无人机航拍的建筑损伤要么是遥感影像里的洪水范围真正对着泥石流滑坡这种「地表纹理破碎、边界模糊、背景杂乱」的目标能用的标注数据少得可怜。这个标题里的 YOLOVOC 格式泥石流滑坡数据集解决的就是这个刚需——给你一批已经框好目标的图像直接喂给 YOLO 系列或者检测模型做训练不用再自己吭哧吭哧标注几千张图。2262 张的量做微调或者小规模验证是够用的配合 YOLOv8 这类成熟框架跑通一个检测流程并不难。适合谁来用一类是做地质灾害隐患识别的算法工程师想快速验证检测方案另一类是科研场景里需要自定义数据集做对比实验的学生。它和 ImageNet、COCO 那类通用数据集不同的地方在于类别标签是垂直的只有滑坡/泥石流这类灾体目标模型训练时的正样本占比更高收敛速度和对特定场景的敏感性都会好很多。但要说清楚这个数据集不是拿来直接部署的公开大模型它是你的训练原料能不能出效果取决于你怎么处理这 2262 张图、怎么做训练配置。下面把整个流程拆开讲从压缩包里有什么到最终怎么验证模型有没有学偏。2. 压缩包里有什么VOC 与 YOLO 两种格式的底层差异2.1 标准目录结构与标注文件对照拿到 zip 包之后直接解压你会看到一套标准的双格式数据集目录。常见排布是这样的landslide_dataset/ ├── images/ │ ├── train/ # 约 1580 张 │ ├── val/ # 约 450 张 │ └── test/ # 约 232 张 ├── labels/ │ ├── train/ # 对应的 YOLO 格式 txt 文件 │ ├── val/ │ └── test/ ├── annotations/ │ ├── train/ # 对应的 VOC 格式 xml 文件 │ ├── val/ │ └── test/ └── classes.txt # 类别列表文件这里要先提醒你不同的数据集作者对目录命名有各自的习惯有的是Annotations和JPEGImages的 Pascal VOC 原始布局有的直接按训练验证测试分好。不管哪种核心是找到三类文件——图片、xml、txt以及一个类别映射文件比如classes.txt。拿到压缩包后第一件事不是急着训练而是核对这三类文件的数量是否一致。我吃过一次亏下载的数据集里有 10 张图没对应标注YOLO 训练时直接当成背景图导致模型漏检率偏高排查了很久才找到原因。VOC 格式的 xml 文件和 YOLO 格式的 txt 文件内容长得完全不一样。xml 记录的是目标的绝对坐标和像素宽高而 YOLO 的 txt 记录的是归一化后的中心点和宽高。两种格式的转换不是单纯改个后缀名必须做坐标换算这个后面详细说。2.2 用 Python 脚本核对标注与图片是否一一对应在动训练之前先做一个完整性检查。这是血泪经验数据集标注缺失、多余、或者文件名对不上会直接影响训练时的损失曲线表现而且这类问题特别隐蔽。我一般会写一个快速脚本import os img_dir images/train label_yolo_dir labels/train label_voc_dir annotations/train img_files {f.split(.)[0] for f in os.listdir(img_dir) if f.endswith((.jpg, .jpeg, .png))} yolo_files {f.split(.)[0] for f in os.listdir(label_yolo_dir) if f.endswith(.txt)} voc_files {f.split(.)[0] for f in os.listdir(label_voc_dir) if f.endswith(.xml)} # 找出有图但缺标注的文件 missing_yolo img_files - yolo_files missing_voc img_files - voc_files # 找出有标注但缺图的文件 orphan_yolo yolo_files - img_files orphan_voc voc_files - img_files print(f图片总数: {len(img_files)}) print(f缺 YOLO 标注: {len(missing_yolo)}, 缺 VOC 标注: {len(missing_voc)}) print(f孤儿 YOLO 标注: {len(orphan_yolo)}, 孤儿 VOC 标注: {len(orphan_voc)}) if missing_yolo: print(样例:, list(missing_yolo)[:5])这段脚本的逻辑很简单用文件名的主干部分做集合运算找出有图没标注、有标注没图的文件。对泥石流这类目标图片数量大时人工根本不可能逐一检查脚本是唯一的靠谱手段。实际用的时候注意路径细节——有的脚本会区分文件夹路径注意代码中变量的取值不要硬编码成绝对路径方便复用。2.3 VOC 坐标转 YOLO 的换算原理与最小实现这是整个数据集使用里最容易被搞错的一步。VOC 的 xml 里记录的是 xmin、ymin、xmax、ymax单位是像素。YOLO 要的则是归一化坐标即以图片宽高为基准的相对值。换算要记住下面这张表变量VOC 含义YOLO 换算公式x_center目标框中心 x 坐标像素((xmin xmax) / 2) / img_widthy_center目标框中心 y 坐标像素((ymin ymax) / 2) / img_heightwidth目标框宽度(xmax - xmin) / img_widthheight目标框高度(ymax - ymin) / img_height最小可运行转换脚本import xml.etree.ElementTree as ET def voc_to_yolo(xml_path, img_width, img_height): tree ET.parse(xml_path) root tree.getroot() lines [] for obj in root.iter(object): name obj.find(name).text # 拿到类别 ID class_id class_name_to_id[name] box obj.find(bndbox) xmin float(box.find(xmin).text) ymin float(box.find(ymin).text) xmax float(box.find(xmax).text) ymax float(box.find(ymax).text) # 边界截断是关键有的标注会超出图片范围 xmin max(0, min(xmin, img_width)) xmax max(0, min(xmax, img_width)) ymin max(0, min(ymin, img_height)) ymax max(0, min(ymax, img_height)) x_center ((xmin xmax) / 2) / img_width y_center ((ymin ymax) / 2) / img_height w (xmax - xmin) / img_width h (ymax - ymin) / img_height lines.append(f{class_id} {x_center:.6f} {y_center:.6f} {w:.6f} {h:.6f}) return \n.join(lines)注意这段代码里的边界截断。泥石流滑坡的影像经常是无人机拍的拼接图标注的人在框选时可能把框拖到图片边缘外如果不截断训练时 YOLO 会报坐标越界的错误或者在计算损失时报错。另外class_name_to_id这个映射要从classes.txt读保持一致别自己在代码里硬写字典那样后期改类别顺序时会出大问题。3. 数据清洗与增强泥石流目标的纹理特性决定了你怎么做预处理3.1 先看直方图和分辨率分布再决定是否统一尺寸拿到数据集之后直接进训练是大忌。泥石流滑坡图像来源五花八门可能是高分卫星影像、无人机正射影像也可能是现场单反拍摄的照片分辨率从 600x600 到 4000x3000 都有。模型输入尺寸一般固定为 640x640 或 1280x1280如果直接暴力 resize小目标会直接被抹掉。先跑一个统计脚本看看这批图的宽度和高度分布import os from PIL import Image img_dir images/train sizes [] for f in os.listdir(img_dir): with Image.open(os.path.join(img_dir, f)) as im: w, h im.size sizes.append((w, h)) # 简单统计 widths [s[0] for s in sizes] heights [s[1] for s in sizes] print(f宽度范围: {min(widths)} ~ {max(widths)}) print(f高度范围: {min(heights)} ~ {max(heights)}) print(f总图数: {len(sizes)}) # 找出宽高比极端的图这类图容易出现标注失真 extreme [(w, h) for w, h in sizes if abs(w/h - 1) 0.5] print(f宽高比偏离超过 0.5 的图: {len(extreme)} 张)这里的关键是看宽高比偏离度。遥感影像通常宽高比接近 1但如果是拼接图或者条带影像可能非常扁长。YOLO 训练时会做 letterbox 填充如果输入图像本身宽高比极端填充后的黑边会非常大模型学到的是「黑边里的目标」而不是「图里的目标」。对这类图我的建议是单独处理要么裁切成小块要么干脆丢弃不放进训练集。3.2 针对滑坡体边界模糊的特性做增强——不只是翻转泥石流滑坡目标有一个天然难点它不像行人、车辆那样有清晰轮廓边界往往是渐变的坡体顶部和原始地形混在一起。单纯做水平翻转、旋转这类几何增强对模型提升帮助有限因为模型在训练中见过「翻转的滑坡」但实际场景里滑坡的方向受地形控制不会随便翻转。我一般会加大两类增强亮度对比度扰动。泥石流滑坡在不同光照、不同季节下色调差异极大植被覆盖多时偏绿泥石流暴发时偏灰黄。用 HSV 空间的随机扰动模拟这种变化。随机裁剪和缩放。用 mosaic 增强时把不同尺寸的滑坡目标拼在一起强迫模型学尺度不变性。Ultralytics YOLO 里自带的增强策略已经比较强配置方式可以在训练脚本里加上from ultralytics import YOLO model YOLO(yolov8s.pt) model.train( datalandslide.yaml, epochs100, imgsz640, hsv_h0.02, # 色调扰动 hsv_s0.7, # 饱和度扰动 hsv_v0.5, # 明度扰动——泥石流图像亮度变化大这个参数关键 mosaic1.0, # mosaic 增强开启 fliplr0.5, # 水平翻转概率滑坡对翻转不敏感可以开 scale0.5, # 缩放幅度模拟不同拍摄高度 )这些参数是 Ultralytics 默认体系的配置项hsv_v 和 scale 是我会特别调大的两个。泥石流图像在亮度上的差异往往比目标本身的纹理差异还要大模型容易学到「亮的地方就是滑坡」这是过拟合的一种调大 hsv 扰动能压制这种倾向。scale 也是同理无人机在不同高度拍摄同一片滑坡目标在画面里的大小可能差一个数量级。3.3 类别不均衡的处理先看标签分布再决定采样策略泥石流滑坡数据集这类垂直数据集通常只有一两个类别比如landslide和mudflow。但 2262 张图里每张图的标注数量差别可能很大。有的图里有一大片滑坡体单框有的图里可能有五六处零散的小滑坡多框。如果模型过多地看到单框图它会对「大片目标」产生偏好漏掉小目标。训练前先统计每张图的标注数量分布# 统计 YOLO 每张 txt 里的行数 for f in labels/train/*.txt; do lines$(wc -l $f) echo $lines done | sort -n | uniq -c输出形如130 1 # 130 张图只有 1 个框 85 2 # 85 张图有 2 个框 ...如果发现大量图片只有 1 个框同时存在少数图片有 8 个以上的框那么这个数据集的标注密度差异就比较大。这时候直接用默认训练策略模型对小目标的敏感度会不够。处理办法是调整训练时的采样权重或者用class weights功能做类别加权。Ultralytics 里可以给每个类别设置丢失权重具体可以在data.yaml里通过weight:字段控制。4. 跑通 YOLO 训练从 data.yaml 到损失曲线异常的排障4.1 写 data.yaml 和第一次训练的完整流程训泥石流数据集和训通用目标检测流程上没有本质差别核心是把数据入口配置对。先建一个landslide.yaml# 数据集配置 path: /path/to/landslide_dataset train: images/train val: images/val # 类别名顺序必须和 classes.txt 完全一致 names: 0: landslide 1: mudflow注意几个细节path 建议用绝对路径训练时如果换机器跑相对路径经常因为当前工作目录不同而出问题train 和 val 指向到 images 的子目录YOLO 会自动去找对应 labels 目录下的 txt 文件前提是 labels 目录结构和 images 保持一致。yaml 文件里的 names 顺序是致命伤——如果训练数据里的 txt 第一列写的是 1mudflow但 yaml 里 1 对应成了 landslide模型会学一个「颠倒的认知」验证集上怎么测都是错的。训练命令就简单了yolo train modelyolov8s.pt datalandslide.yaml epochs100 imgsz640 batch16 device0建议从yolov8s版本起步跑通流程再换成yolov8m或者yolov8l。泥石流滑坡的边界细节多小目标占比不低s 模型可能欠拟合但先用它跑通一版能让你快速确认数据链路是通的。训练时盯着 loss 曲线前 20 个 epoch 如果 box_loss 和 cls_loss 都没有明显下降大概率是数据有问题这时候模型权重调整没有意义。4.2 损失曲线不下降的排查顺序loss 不降或者降得奇慢是地质灾害数据集里最常见的问题。按下面的顺序排查能省不少时间第一检查标注内容是否为空。有的 xml 文件里 object 节点存在但 bndbox 坐标全是 0YOLO 训练时这类标注会给一个面积为 0 的框loss 直接变成 nan。用脚本扫一遍所有 txt 文件如果某一行的 w 或 h 是 0直接删掉那条标注。第二检查类别 ID 是否越界。yaml 里写了 2 个类别但某 txt 里出现了 class_id5训练必然崩。跑个脚本找出最大类别 ID# 找出所有 txt 中 class_id 的最大值 cat labels/train/*.txt | awk {print $1} | sort -n | tail -5如果最大值大于等于 yaml 里的类别数就有标注越界的文件。这种情况往往是 VOC 转 YOLO 时类别映射表没对齐导致的。第三检查图片是否有损坏。泥石流数据集中有些图可能是从视频里抽帧得到的压缩率过高或者截断下载会导致图片文件打不开。YOLO 训练时遇到损坏图片会直接跳过但不会提示你导致实际训练样本比预想少。跑一个完整的图片完整性检查import os from PIL import Image img_dir images/train bad_images [] for f in os.listdir(img_dir): try: with Image.open(os.path.join(img_dir, f)) as im: im.verify() except Exception as e: bad_images.append((f, str(e))) print(f损坏图片: {len(bad_images)} 张) for f, err in bad_images[:10]: print(f, err)4.3 避坑泥石流场景训练的三个高频踩坑点踩坑一验证集与训练集图片内容重叠泥石流滑坡数据集如果是按时间序列拍摄的同一个滑坡体在 train 和 val 里可能都有图。模型在训练时见过同一片坡体的不同角度、不同时间的图验证集测试时 loss 很低、mAP 很高但换一个区域的真实场景就废了。判断方法随机拿几张 val 集中的图和 train 集做感知哈希比较相似度高的直接剔除。不要相信数据集作者说的「已经随机划分」自己验一遍才靠谱。踩坑二忽略图像拼接缝的影响无人机正射影像拼接生成的滑坡图在拼接缝附近光照和色差明显异常。模型可能学到「拼接缝 滑坡边界」这种虚假特征。处理办法是在增强阶段做一个随机局部模糊或者直接把拼接缝明显的图裁掉。没有代码里自动检测拼接缝的工具时用排除法如果在验证时模型对沟谷、山脊这类边缘区域误检率特别高就该怀疑这个原因。踩坑三目标占比过小导致漏检泥石流滑坡体在整张遥感图里可能只占很小一块比如 640x640 的图里目标只有 20x20 像素。YOLO 对这类小目标的召回率会明显偏低。解决无非两个方向一是把输入分辨率提高到 1280二是把原图先切成小块再做检测。对 2262 张这个量级的数据集切块操作其实也增加了有效样本数是一个值得做的预处理。踩坑四YOLO 训练时开启 cache 导致的内存溢出Ultralytics 有个默认参数 cacheFalse但很多人喜欢开启 cache 加速。泥石流数据集的图片往往分辨率高全部缓存进 RAM 可能需要几十个 GB。如果机器内存不够训练会中途被 OOM 杀掉损失曲线白跑了几十个 epoch。建议先不开 cache等确认模型和数据集都能正常工作后再考虑。5. 验证模型效果漏检率和误检率分开看别只盯着 mAP5.1 用混淆矩阵定位模型到底是「漏检」还是「误检」训练结束后Ultralytics 会在runs/detect/train/目录下生成混淆矩阵图。但只看矩阵图不够泥石流场景里更有诊断价值的是单独分析漏检和误检。我把预测结果导出用脚本做像素级对比import cv2 import numpy as np def check_detection_quality(model_path, image_path): model YOLO(model_path) results model.predict(image_path, conf0.25, imgsz640) img cv2.imread(image_path) h, w img.shape[:2] # 画目标框并标注置信度 for r in results: for box in r.boxes: x1, y1, x2, y2 box.xyxy[0].tolist() conf box.conf[0].item() cls int(box.cls[0].item()) cv2.rectangle(img, (int(x1), int(y1)), (int(x2), int(y2)), (0, 255, 0), 2) cv2.putText(img, f{cls} {conf:.2f}, (int(x1), int(y1)-5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 1) return img跑几十张验证集图片把结果打印出来看。重点看两类一类是安全上必须查出的隐患区域有没有被框住漏检另一类是植被异常、水体反光这类背景有没有被误判成滑坡误检。对于地质灾害监测漏检的代价远高于误检宁可错报也不要放过所以我会把 conf 阈值调得偏低比如 0.15让模型多报一些再人工复核。5.2 计算单类别的 Precision-Recall 曲线泥石流数据集类别少直接画每个类别的 PR 曲线比看整体 mAP 更有意义。Ultralytics 训练输出里自带 PR 曲线图但那是整个数据集的汇总。如果要看单类别的细节可以用验证脚本收集所有预测结果按置信度阈值扫描from ultralytics import YOLO model YOLO(runs/detect/train/weights/best.pt) metrics model.val(datalandslide.yaml, conf0.1, iou0.5) # 打印每个类别的详细指标 for i, cls_name in enumerate(model.names.values()): ap50 metrics.box.ap50[i] ap50_95 metrics.box.ap[i] precision metrics.box.p[i] recall metrics.box.r[i] print(f{cls_name}: AP50{ap50:.3f}, AP50-95{ap50_95:.3f}, P{precision:.3f}, R{recall:.3f})跑完之后你会看到一个规律泥石流数据集里 recall 往往比 precision 低。原因是滑坡目标的边界模糊标注者之间对边界像素的判定有差异模型在训练时学到的是一个「平均边界」和每张图的标注边界不完全重合导致预测框和 GT 框的 IoU 不高。这时候可以尝试把 IoU 阈值从 0.5 降到 0.3 再做评估——这个做法在正式论文里不合适但在工程交付时判断「是否检到了」是实用的。5.3 最后一个实战技巧切块预测别让整图拖动小目标遥感图直接送进模型目标太小检测不出来。常见的做法是把大图切成若干小块分别预测后再合并。python script.py --image big_slope.tif --output results/没有现成脚本时用 OpenCV 按 50% 重叠率切块import cv2 def sliding_window_predict(model, img_path, window_size640, stride320): img cv2.imread(img_path) h, w img.shape[:2] boxes [] for y in range(0, h - window_size 1, stride): for x in range(0, w - window_size 1, stride): patch img[y:ywindow_size, x:xwindow_size] results model.predict(patch, conf0.2, imgsz640) for r in results: for box in r.boxes: x1, y1, x2, y2 box.xyxy[0].tolist() boxes.append((x1x, y1y, x2x, y2y, box.conf[0].item())) # 最后做 NMS 合并重叠框 # torchvision.ops.nms 可以用在这里 return boxes切块预测有两个坑。一是重叠区域的目标会被重复检出合并时必须做 NMS二是目标刚好被切在边沿时两块的置信度都不高需要设置重叠率我一般用 50% 至 75%让同一个目标至少完整地出现在某一块里。这是实践里翻过车的地方第一次做整幅正射影像检测时漏检率高达 20%切块加上 NMS 之后才把漏检降下来。我现在的习惯是数据到手先跑完整性检查然后看亮度分布和尺寸分布再想增强策略最后才碰训练。这套流程保证我拿到任何新数据集都能在一个小时内判断出「值不值得投入」。这个数据集对我最有价值的地方不在于 2262 张这个数量本身而在于它在双格式下都做了标注省掉了大部分格式转换的功夫可以把精力集中在提高滑坡识别率上。希望这些拆解能帮你在跑泥石流模型时少走几步弯路。本文还有配套的精品资源点击获取
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。