简介:这是一份面向目标检测学习与研究者的山体滑坡数据集,共包含823张清晰现场图像,以矩形框标注了950个landslide目标,可用于YOLO、Faster R-CNN等常见检测框架的训练、验证与模型效果对比。压缩包内同时提供VOC与YOLO两套标注体系:JPEGImages文件夹存放原始jpg图片,Annotations文件夹存放对应的xml标注文件,labels文件夹存放YOLO格式的txt标签文件,目录结构清晰,标注类别名称统一为landslide,图像未做增强,方便直接接入现有训练流程。压缩包共约2000个文件,以jpg图像、xml标注和txt标签三类文件为主,整体大小约63MB,下载后无需额外整理即可使用。该数据集特别适合滑坡识别、地质灾害监测等场景的算法实验,也可作为毕业设计或论文复现的补充数据。目前已有480人学习下载,适合需要真实滑坡样本的开发者快速上手。
1. 823张山体滑坡数据集:先搞清它到底能干什么用
做地质灾害监测的人拿到“目标检测山体滑坡数据集823张YOLO+VOC格式.zip”这个压缩包,第一反应往往是直接解压丢进训练脚本。但823张这个量级,背后藏着一个很现实的问题:它既不是ImageNet那种千万级基准,也不是随便凑出来的玩具集,而是一个典型的“中小规模垂直场景数据集”——足够验证算法思路、做预训练微调、跑通整套检测流程,但不足以直接撑起一个高泛化能力的生产模型。
这类数据集的影像来源通常是卫星遥感、无人机航拍或灾害应急公开影像,标注对象集中在滑坡体、滑坡后壁、堆积区、裂缝等可见地物特征。打包成YOLO和VOC双格式,是为了让拿到手的人不用自己写转换脚本就能直接喂给主流检测框架——YOLO系用txt归一化坐标,VOC系用xml多边形标签,同一批图片两套标注,省掉的是最容易被搞错的一步。
这篇文章会把这823张数据从目录结构、标注格式、训练配置到格式互转全部过一遍。适合谁看?准备用YOLOv8或MMDetection跑滑坡检测的算法工程师、做灾害遥感应用的研究生、以及想快速验证检测方案可行性的应急信息化从业者。读完你至少能回答三个问题:这823张能不能直接训练、训练参数怎么设、踩到标注格式的坑怎么排。
2. YOLO格式与VOC格式的底细:同样是标注,差别在哪
很多人以为YOLO和VOC只是文件后缀不同,其实这两种格式的标注哲学完全不一样。YOLO是“归一化中心点+宽高”,VOC是“像素坐标系下的多边形顶点”。同一个滑坡体,在两种格式里表达出来的数值范围、坐标基准、类别组织方式都不同。不理解底层逻辑,转换脚本迟早写错。
2.1 YOLO的txt标注:归一化坐标与class_id
YOLO格式的标注文件是纯文本,每行代表一个目标对象,结构是:类别ID、归一化中心x、归一化中心y、归一化宽w、归一化高h。五个值全部用空格分隔,x、y、w、h都是0到1之间的小数,除以了图片的宽和高。
拿823张数据里的典型滑坡影像来说,如果图片是1920×1080,某个滑坡体的像素框是x_min=480, y_min=270, x_max=1440, y_max=810,那么对应的YOLO行是:
0 0.5 0.5 0.5 0.5计算逻辑是:中心点x = (480+1440)/2/1920 = 0.5,中心点y = (270+810)/2/1080 = 0.5,宽 = (1440-480)/1920 = 0.5,高 = (810-270)/1080 = 0.5。注意,YOLO的w和h不是右下角坐标减去中心点,而是整个框的宽高除以图片宽高。
这里有两个高频翻车点。第一,归一化的除法必须用float,不能用整数除法,否则823张图里超过一半的标注会变成0。第二,如果数据集里混入了不同分辨率的图片——比如卫星图和无人机图混在一起——每张图的归一化基准不同,训练时YOLO会通过letterbox统一缩放,但标注值本身必须严格落在0到1的闭区间内。任何一个值大于1,意味着标注框超出了画面边界,ultralytics在训练时通常会告警但不会报错,模型会在某个类别上悄悄学歪。
2.2 VOC的xml标注:多边形框与逐对象元信息
VOC格式沿用了Pascal VOC的标注规范,每张图片对应一个同名xml文件,里面记录filename、size、object列表。每个object包含name类别名、pose、truncated、difficult,以及bndbox四个顶点坐标xmin、ymin、xmax、ymax。注意,VOC的xmax和ymax是真实像素值,不是减去1之后的OpenCV坐标系值。
一份典型的滑坡标注xml里,bndbox长这样:
<annotation> <folder>landslide</folder> <filename>slope_001.jpg</filename> <size> <width>1920</width> <height>1080</height> <depth>3</depth> </size> <object> <name>landslide</name> <bndbox> <xmin>480</xmin> <ymin>270</ymin> <xmax>1440</xmax> <ymax>810</ymax> </bndbox> </object> </annotation>xml的价值在于可读性和可扩展性。它能把difficult这类训练难度标记、pose这类角度信息、甚至segmentation的分割顶点都塞进去。但问题也出在这里:格式越自由,越容易出错。比如字段拼写错误、xml结构不闭合、bndbox里的数值写成了字符串而不是数字,这些在解析时都可能抛出异常。ultralytics本身不直接读xml,需要先转成txt;而MMDetection的VOC格式支持有一套独立的xml解析器,对xml结构的要求更严格。
2.3 为什么数据集常同时打包两种格式
一份数据集同时给YOLO和VOC两份标注,这不是冗余,而是分发策略。YOLO格式的好处是轻量、直接、训练零转换,适合用ultralytics跑快速验证;VOC格式的好处是信息完整、生态兼容,能直接接进MMDetection的VOCDataset、或者转成COCO格式做多任务扩展。
823张双格式的数据集,实际拿到手后目录结构常见是这样的:
landslide_823/ ├── images/ │ ├── train/ │ └── val/ ├── labels/ │ ├── train/ │ └── val/ ├── annotations/ │ ├── train/ │ └── val/ └── data.yamlimages放图,labels放YOLO的txt,annotations放VOC的xml,data.yaml放类别和路径配置。这种结构的好处是train/val划分已经帮你做好了,不用自己写split脚本去踩随机划分的坑。但需要重点检查的是train和val的划分比例与内容相似度——如果val里混入了和train几乎同源的影像,验证指标会虚高,后面上真实场景直接翻车。
3. 跑通YOLOv8训练:环境、目录与参数一次配齐
数据拿到手,第一个实操动作不是写模型,而是把训练环境跑起来。这里用YOLOv8 + Anaconda的常见组合,因为它对823张这种小数据量的兼容性最好,默认增强策略不容易出幺蛾子,也方便后续用yolov8训练自己的数据集这一步直接套用。
3.1 Anaconda环境配置与依赖安装
YOLOv8跑在PyTorch上,环境配置的基本要求是Python 3.8以上、PyTorch 1.8以上,CUDA按显卡驱动来选。用conda建独立环境是最稳的,避免把系统Python搅乱:
conda create -n yolo python=3.9 -y conda activate yolo pip install ultralytics torch torchvision --index-url https://download.pytorch.org/whl/cu118逻辑说明:第一行创建名为yolo的独立环境,Python 3.9是ultralytics兼容性最稳的版本;第二行激活;第三行同时装ultralytics和带CUDA 11.8编译的PyTorch。如果显卡是30系或40系,CUDA 11.8基本通吃;如果是20系以下的老卡,建议装cu117版本,否则驱动可能带不动。
装完后立刻验证:
python -c "import torch; print(torch.cuda.is_available())"输出True再进下一步。如果输出False,说明PyTorch装成了CPU版,或者CUDA驱动没对上。这里有个玄学问题:conda install的torch经常自动装成cpuonly版本,所以直接用pip从pytorch官网指定index-url装是最稳的。
3.2 数据目录核对与data.yaml配置
解压zip之后不要急着开训,先把目录结构捋一遍。常见做法是检查images/train与labels/train的文件名是否一一对应,以及标注文件是否为空。这里用一条命令快速排查:
for f in images/train/*.jpg; do base=$(basename "$f" .jpg) if [ ! -f "labels/train/$base.txt" ]; then echo "missing label: $base" fi done这段脚本遍历images/train下所有jpg,把文件名去掉后缀,再去labels/train里找同名txt。找不到就打印缺失列表。823张图里只要缺了十几张的标注,训练时损失曲线就会莫名其妙地抖动,因为模型在拿空标注学背景。
目录没问题后,改data.yaml:
path: /your/absolute/path/landslide_823 train: images/train val: images/val names: 0: landslidepath写绝对路径,不要写相对路径,这是无数人在服务器上训练时踩过的坑。train和val指向相对path的图片目录。names里的索引必须从0开始且连续,如果数据集里只有landslide一个类,就只写0这一行。
3.3 训练命令与关键参数
823张属于小数据集,训练命令不建议上来就用默认参数硬跑。常见的起手命令:
yolo detect train \ data=data.yaml \ model=yolov8n.pt \ epochs=200 \ imgsz=640 \ batch=16 \ patience=30 \ optimizer=AdamW \ lr0=0.001 \ augment=True逻辑说明:model用yolov8n.pt预训练权重,n是nano版本,参数最少,对823张的收敛压力最小。epochs给到200是因为小数据集需要更多轮次来充分拟合,但配合patience=30做早停——30轮验证指标不涨就自动停,避免无效空转。imgsz=640是速度和精度的平衡点,滑坡体通常占画面比例不小,640够用,不需要强行上1280。batch=16在主流12G显卡上跑nano模型毫无压力。
一个容易被忽略的参数是augment。ultralytics默认开增强,但对遥感影像来说,默认的HSV增强会把植被和土壤的颜色带跑偏,滑坡检测任务里颜色纹理是重要特征,不建议开太猛。第一次训练建议保持默认,看曲线再调。
训练结束后看results.csv里的val_loss和mAP50。823张的训练集,mAP50在0.75以上属于正常水平;如果只有0.4以下,大概率是标注框有错位,或者类别定义不统一。
4. VOC转YOLO格式:四步转换与四个边界坑
虽然这份数据集已经双格式打包了,但你很可能会拿到别的单格式数据——比如从网络上找的VOC格式历史灾害影像、或者用LabelImg新标注的批数据。VOC转YOLO是目标检测数据准备里最常写的一类脚本,四步走:解析xml → 提取bndbox → 归一化 → 写入txt。
4.1 解析xml并提取标注框
用Python的xml.etree.ElementTree解析xml,提取每个object的name和bndbox四个坐标:
import xml.etree.ElementTree as ET def voc_to_yolo(xml_path, img_w, img_h, class_names): tree = ET.parse(xml_path) root = tree.getroot() lines = [] for obj in root.findall('object'): name = obj.find('name').text if name not in class_names: continue class_id = class_names.index(name) bndbox = obj.find('bndbox') xmin = int(float(bndbox.find('xmin').text)) ymin = int(float(bndbox.find('ymin').text)) xmax = int(float(bndbox.find('xmax').text)) ymax = int(float(bndbox.find('ymax').text)) x_center = (xmin + xmax) / 2.0 / img_w y_center = (ymin + ymax) / 2.0 / img_h width = (xmax - xmin) / img_w height = (ymax - ymin) / img_h lines.append(f"{class_id} {x_center:.6f} {y_center:.6f} {width:.6f} {height:.6f}") return lines逻辑说明:class_names是类别列表,比如["landslide", "crack"],class_names.index(name)拿到类别ID。所有坐标先用int强制转换再归一化,绕开xml里可能存在的浮点字符串。归一化的分母必须来自图片的实际宽高,而不是xml里的size字段,因为有些标注工具的size字段写的是原图尺寸,但图片被压缩过,两者一旦不一致,框全部偏移。
4.2 批量转换脚本
单张转换没问题后,批量跑。这里有一个关键细节:VOC的xml和图片文件不一定在同一个目录,先把路径配置好:
import os from PIL import Image voc_xml_dir = "annotations/" yolo_label_dir = "labels/" img_dir = "images/" class_names = ["landslide"] for xml_file in os.listdir(voc_xml_dir): if not xml_file.endswith(".xml"): continue base = os.path.splitext(xml_file)[0] img_path = os.path.join(img_dir, base + ".jpg") if not os.path.exists(img_path): print(f"image not found: {base}") continue with Image.open(img_path) as img: img_w, img_h = img.size lines = voc_to_yolo( os.path.join(voc_xml_dir, xml_file), img_w, img_h, class_names ) with open(os.path.join(yolo_label_dir, base + ".txt"), "w") as f: f.write("\n".join(lines) + "\n")这段脚本的健壮性体现在三处:跳过后缀不是xml的文件、图片缺失时打印警告但不中断、每张图重新读取尺寸以像素为准。823张数据批量转换时,最怕的就是中途因为一张坏图中断,前面生成的文件还得删掉重来。
4.3 四个边界坑:坐标、后缀、空框、重叠
第一个坑是坐标越界。转出来的txt里如果出现大于1或小于0的值,会直接导致训练loss变成NaN。通常原因是标注框的xmax写超了图片宽度。解决方法是转换后统一裁剪,把越界值clip到0和1之间。
第二个坑是jpg与png后缀混用。数据集里最常见的文件组织方式是同名不同后缀,有的图是jpg,有的是png。如果脚本只找jpg,png对应的标注全部丢失。处理方式是先用glob把所有图片后缀都扫出来,再按实际后缀拼接。
第三个坑是空标注文件。有些xml里object为空但bndbox存在,或者图片上根本没有目标物体。转出来的txt是0字节空文件。YOLO训练允许空文件存在,但ultralytics的detect模式遇到空label会跳过该图,导致实际训练图片数量比预期少。排查时用find labels -size 0 | wc -l统计空文件数量,超过总标注数5%就要回查标注质量。
第四个坑是同一张图多个框重叠。滑坡场景里滑坡体与裂缝经常存在包含关系,两个框高度重叠时,模型会不知道该学哪个特征为主。常规做法是在转换时做NMS过滤或保留外层大框,这个操作没有标准参数,我一般保留面积更大的框,因为滑坡体的整体轮廓对检测更有判别性。
5. 避坑记录:823张数据训练常见的五个问题
数据量越小的数据集,训练时踩的坑越隐蔽。这里五条都是实际项目里的血泪经验,按现象、原因、解决的顺序写,方便你照着排查。
5.1 class_id不连续导致背景被识别成目标
现象:训练正常,loss下降也正常,但推理时大量把植被、道路误检成滑坡。
原因:这是最常见的标注格式问题。数据集的labels里class_id可能不是从0开始连续排列的——比如先写了2,再写0,中间跳过了1。ultralytics在解析data.yaml时,names字典的索引必须严格从0递增,某类缺失会导致类别映射错位,模型把属于空位的特征学成了目标物。
解决:检查所有txt文件里出现过的class_id集合:
cat labels/train/*.txt | awk '{print $1}' | sort -u输出的集合如果包含非连续数字,用sed批量改写class_id,或者在data.yaml里按实际类别顺序重排names列表。排查效率最高的方式就是这条命令,改成连续ID后重训,问题通常立刻消失。
5.2 图片与标注文件名不匹配
现象:训练日志里每个epoch的images数量明显低于train目录下的实际图片数,且不报错。
原因:ultralytics加载数据时如果某张图片没有对应的txt标注,会静默跳过。823张数据集里有几张图标注丢失或文件名不一致,不会报错但会少训。
解决:启动训练前先用前面的for循环脚本做一次全量比对,把缺失标注的图片单独移出。不要补空txt文件强行对齐,空标注会让模型把该学到的东西丢掉。
5.3 标注框越界导致loss异常波动
现象:loss曲线在下降过程中突然出现尖峰,然后又回落,验证集mAP反复横跳。
原因:某个txt里的归一化坐标超过1,可能是转换脚本里整数除法导致的,也可能是标注框本身就画出了图像边界。
解决:用脚本扫描所有标注值:
awk '$2>1 || $3>1 || $4>1 || $5>1 || $2<0 || $3<0 {print FILENAME, $0}' labels/train/*.txt把打出来的文件单独修订,越界值clip到边界内。特别要注意第4列和第5列,宽度和高度大于1意味着框比整张图还大,这在滑坡检测里极少发生,一旦出现先怀疑数据标注顺序搞反了。
5.4 滑坡体特征与背景过于相似导致过拟合
现象:训练集mAP接近1.0,验证集mAP只有0.5左右,而且训练到一半就开始发散。
原因:823张数据量偏小,遥感影像里滑坡体与裸露岩石、干枯河床在颜色纹理上高度相似,模型学到的可能不是“滑坡”的完整语义,而是某些局部颜色特征的组合。验证集里一旦出现颜色差异较大的滑坡影像,立刻暴露泛化能力不足。
解决:优先检查验证集的划分是否有意图泄露——同一区域的不同时间切片不能分别出现在train和val里。尽可能加入更多样的影像源做数据增强,回填train集:
augment: True hsv_h: 0.02 hsv_s: 0.5 hsv_v: 0.3 flipud: 0.5滑坡体特征不完全依赖颜色,所以HSV增强的幅度可以稍微调大而不是关闭,flipud上下翻转对滑坡这种地形特征有正向帮助。增强参数是玄学,必须盯着验证集调,不要拿训练集曲线判断效果。
5.5 zip解压后目录缺失部分文件
现象:解压后images里有823张,labels里只有780个txt,缺了43个。
原因:压缩包内含子目录或文件名包含中文/特殊字符,在Windows上用系统自带解压可能出现隐藏失败;另外zip伪加密也会导致部分文件解压中断后被跳过。
解决:换用7-Zip或命令行工具重新解压:
unzip -o landslide_823.zip -d landslide_823/-o覆盖已有文件,-d指定目标目录。解压后用diff <(ls images) <(ls labels)快速比对文件名集合。如果压缩包里套了一层外层目录,别忘了去掉这一层,否则路径配置会把ultralytics绕晕。
6. 小样本滑坡检测的进阶用法:数据增强与迁移策略怎么整合
823张数据的价值不在“直接训生产模型”,而在“验证检测方案可行性和沉淀迁移能力”。最后的落地经验是三步走:先用预训练权重微调,再叠加针对性增强,最后用半监督方式扩展数据。
第一步,不要从yolov8n.yaml随机权重开始训,直接用yolov8n.pt预训练权重。823张对随机权重来说太少,预训练模型已经具备通用的边缘和纹理先验,滑坡体在遥感影像上的轮廓特征与自然场景的小目标有重叠,迁移收益非常明显。我通常把backbone冻结前50层不动,只训练head部分,等loss收敛后再解冻全部微调。做法是在训练完第一轮后加载best.pt继续第二轮,ultralytics的yolo detect train里直接传model=runs/detect/train/weights/best.pt即可。
第二步,增强策略上做针对性选择。滑坡检测对光照和季节变化敏感,但对图像旋转不敏感——滑坡体无论从哪个角度看都是滑坡。degrees=180随机旋转可以放心开,但translate=0.1不要给太大,遥感影像在平移后容易把滑坡体的一部分切出画面,导致标注框大量越界。mixup在小样本场景里效果不稳定,我实测823张数据开mixup后验证mAP反而掉了3个点,原因是合成图的滑坡纹理被破坏,建议先关掉,等数据量到2000张以上再开。
第三步,用训练好的模型做伪标注扩展数据。拿模型对未标注的遥感影像做推理,置信度阈值设到0.9以上,筛选出的检测框人工复查后加入训练集。这个方法在小样本滑坡检测里效果非常好,823张为基础通常能再扩展出几百张可用样本。注意伪标注数据的分布与原始训练集不要重复,比如同一个区域的不同时间影像可以加,完全同一张图重复加不行,那只会放大过拟合。
最后说一个每次都要做验证的习惯:训练完别急着收工,单独留出20张完全没有参与过训练和验证的滑坡影像,跑一次批量推理,统计不同光照和地形条件下的漏检率。这比任何指标曲线都更能说明模型在真实场景里能不能用。
823张数据集的边界很明显——它做不了通用滑坡识别的大模型底座,但完全够你把一套检测系统从零到一跑通,把数据流转、格式兼容、训练调参这些坑全部踩平。等换到大数据集的时候,这些经验会帮你少熬好几个通宵。希望帮到你。
本文还有配套的精品资源,点击获取