遥感滑坡泥石流数据集VOC转YOLO与训练避坑指南

发布时间:2026/10/8 4:45:52
遥感滑坡泥石流数据集VOC转YOLO与训练避坑指南 简介这套航拍滑坡与泥石流检测数据集面向目标检测算法研究和地质灾害智能识别应用提供VOC与YOLO双格式标注文件。数据对应5619张432x432分辨率航拍影像标注类别包括Debris-flow泥石流和landslide滑坡矩形框总计17715个其中滑坡框16199个、泥石流框1516个类别分布可支撑有针对性的模型训练图像统一分辨率和矩形框标注方式也简化了预处理环节。压缩包约183.46MB共2000个文件以VOC格式xml标注为主1999个另附YOLO类别说明txt目录简单、便于批量读取。需要留意的是该数据集未划分训练/验证/测试集也不附带预训练权重精度不作保证用户需自行完成数据划分、训练与评估。目前已有63人学习适合作为滑坡、泥石流检测方向的起步数据集或算法对比基准。1. 拿到这份 5619 张的双格式遥感数据集你真正需要的是什么汛期前的排查季遥感单位最忙的时候不是飞无人机而是盯着屏幕上几万像素的航拍影像做人工判读。一个滑坡体在影像上可能只占据几十个像素放大、比对、调对比度一天看不完多少张漏判还得回头返工。把这段流程换成目标检测第一个拦路的东西就是数据要不没有带标注的正样本要不标注格式跟 YOLO 对不上。这份航拍滑坡泥石流检测数据集 5619 张VOCYOLO 双格式解决的正是这个“从零开始”的问题。它把 5619 张影像和对应标注打包在一起Pascal VOC 的 XML 和 YOLO 的 txt 都在压缩包里解压之后不用再手工整理直接进入训练流程。适合遥感地灾方向的算法工程师、研究生也适合刚接触 YOLO、想找一个正经遥感目标数据集练手的人。有一点先说清楚双格式不是多此一举它在后面会帮你省掉很多换框架时的格式转换时间。2. VOC 与 YOLO 两种标注格式的底牌从 XML 到 txt 的坐标换算与转换脚本2.1 Pascal VOC 的 XML 与 YOLO 的 txt一个存绝对坐标一个存归一化坐标VOC 格式的标注是 Pascal VOC 时代定下的 XML 结构一张图对应一个 XML 文件里面size记录图像宽高每个object挂一个bndbox存 xmin、ymin、xmax、ymax 四个绝对像素值。优点是可直接读、人对得懂缺点是换个分辨率就得重新换算。这里要注意object里还有一层difficult表示这个目标是不是难以辨认的转换时如果你不想把困难样本混进训练就可以在脚本里把 difficult 为 1 的目标过滤掉。YOLO 格式的标注是纯文本一张图对应一个.txt每行五个数类别索引、归一化中心点 x、归一化中心点 y、归一化宽 w、归一化高 h四个坐标全部除以图像宽高落在 0~1 之间。归一化的好处是换分辨率、换输入尺寸不敏感训练时模型按比例缩放就行。代价是肉眼可读性差看到一个0.7321 0.4510 0.0223 0.0188你完全不知道它框的是什么必须画回图上才直观。这份 5619 张的数据集同时给了两套就是为两种生态准备的。你在 mmdetection、mmrotate 这类库里跑遥感旋转框检测VOC 的 XML 结构可以直接扩展成robndbox这就是 DOTA 数据集那套 poly 格式的基本思路你在 ultralytics 生态里跑 YOLOtxt 直接能用。双格式等于给了你两条路换框架不必重新转换标注。作为对比很多遥感数据集只发布 COCO 格式的 JSON你转成 YOLO 时要处理嵌套的 annotation 结构比 XML 转 txt 麻烦得多。2.2 手写一个 VOC 到 YOLO 的转换脚本带完整注释这个转换脚本我从第一次接触遥感数据集起就一直在用逻辑很直接从 XML 里读出宽高和每个目标框做归一化写一行 txt。下面是完整脚本保存为voc2yolo.py放在解压后的根目录# voc2yolo.py # 把 Pascal VOC 的 XML 标注转换为 YOLO 格式的 txt 标注 # 用法: python voc2yolo.py --xml_dir Annotations --label_dir labels import argparse import xml.etree.ElementTree as ET from pathlib import Path def collect_classes(xml_dir): 扫描所有 XML 里的 object name自动收集类别列表并排序。 不要手动写死类别名避免跟实际标签不一致。 classes set() for xml_path in Path(xml_dir).glob(*.xml): root ET.parse(xml_path).getroot() for obj in root.iter(object): classes.add(obj.find(name).text) return sorted(classes) def convert_one(xml_path, classes, out_path): 单个 XML 转 txt root ET.parse(xml_path).getroot() size root.find(size) img_w int(size.find(width).text) img_h int(size.find(height).text) lines [] for obj in root.iter(object): name obj.find(name).text if name not in classes: continue cls_id classes.index(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) # 注意: YOLO 要求中心点坐标和宽高全部归一化到 0~1 cx (xmin xmax) / 2.0 / img_w cy (ymin ymax) / 2.0 / img_h w (xmax - xmin) / img_w h (ymax - ymin) / img_h # 防止标注越界导致的负数或大于 1 的值 cx max(0.0, min(1.0, cx)) cy max(0.0, min(1.0, cy)) w max(0.0, min(1.0, w)) h max(0.0, min(1.0, h)) lines.append(f{cls_id} {cx:.6f} {cy:.6f} {w:.6f} {h:.6f}) out_path.parent.mkdir(parentsTrue, exist_okTrue) # 没有目标时写入空文件保持 labels 与 images 一一对应 out_path.write_text(\n.join(lines), encodingutf-8) def main(): parser argparse.ArgumentParser() parser.add_argument(--xml_dir, defaultAnnotations) parser.add_argument(--label_dir, defaultlabels) args parser.parse_args() classes collect_classes(args.xml_dir) # 把类别列表写成一个 txt后续生成 yaml 时要靠它 Path(classes.txt).write_text(\n.join(classes), encodingutf-8) for xml_path in Path(args.xml_dir).glob(*.xml): out_txt Path(args.label_dir) / f{xml_path.stem}.txt convert_one(xml_path, classes, out_txt) print(f转换完成共 {len(classes)} 个类别: {classes}) if __name__ __main__: main()逻辑说明脚本先扫描全量 XML 收集类别名这一步很关键很多数据集里的类别不是你以为的那几个先收集再排序可以避免类别索引错位。转换时把绝对坐标换算成中心点加宽高的归一化值再补一层越界裁剪避免标注框超出图像边界产生负数坐标负坐标会让 YOLO 在计算损失时出现奇怪的行为轻则 loss 抖动重则训练直接发散。参数说明--xml_dir指向解压后的 Annotations 目录--label_dir是输出的 txt 目录。如果你的 zip 里目录名不是这两个先看一眼压缩包结构再改路径。跑完后去 labels 目录随便打开一个 txt确认每行是类别ID 中心x 中心y 宽 高五个数。还有一个容易忽略的点压缩包里图片可能是.JPG大写后缀XML 里的filename写的却是小写.jpg在 Windows 上没问题传到 Linux 服务器上训练时就报找不到图片转换前建议用脚本统一重命名成小写。2.3 转换前先画框预览一遍人工确认标注没有离奇转换脚本跑完之后不要急着去训练。把转换出来的 txt 画回原图看一眼这一步是血泪经验换来的航拍影像里滑坡体经常跟周围裸土颜色接近标注边界有一点偏移训练出来的模型边界就跟着偏。画框预览的脚本顺手写一个# preview.py # 用 OpenCV 把 YOLO txt 标注画回原图按任意键翻页按 q 退出 import cv2 from pathlib import Path def draw_one(img_path, txt_path, classes): img cv2.imread(str(img_path)) h, w img.shape[:2] colors [(0, 0, 255), (0, 255, 0), (255, 0, 0), (0, 255, 255)] if not txt_path.exists(): return img for line in txt_path.read_text().strip().splitlines(): cls_id, cx, cy, bw, bh map(float, line.split()) # 把归一化坐标还原成绝对像素 x1 int((cx - bw / 2) * w) y1 int((cy - bh / 2) * h) x2 int((cx bw / 2) * w) y2 int((cy bh / 2) * h) name classes[int(cls_id)] if int(cls_id) len(classes) else str(int(cls_id)) color colors[int(cls_id) % len(colors)] cv2.rectangle(img, (x1, y1), (x2, y2), color, 2) cv2.putText(img, name, (x1, max(0, y1 - 5)), cv2.FONT_HERSHEY_SIMPLEX, 0.6, color, 2) return img if __name__ __main__: classes Path(classes.txt).read_text().splitlines() for img_path in list(Path(JPEGImages).glob(*.jpg))[:50]: txt_path Path(labels) / f{img_path.stem}.txt img draw_one(img_path, txt_path, classes) cv2.imshow(preview, img) if cv2.waitKey(0) 0xFF ord(q): break cv2.destroyAllWindows()说明这段代码把归一化坐标还原成像素坐标再画框和类别名。检查时重点看两类问题一是框是否明显偏离滑坡体核心区域二是同一张图里类别名是否张冠李戴。航拍数据集的标注常见问题就是边界灰度和周围地形太像人标的时候把泥石流沟道标成了滑坡体转换后只有画出来才能发现。如果你打开图片发现窗口卡住不动多半是waitKey(0)在等你按键盘点一下图片窗口再按任意键切下一张。预览 50 张心里有数后再进入数据划分这是唯一能拦住“标注离奇”这个问题的环节跳过它后面所有指标都会失真。3. 数据体检与划分先统计类别分布和尺寸再按场景组拆分避免数据泄漏3.1 第一步不是训练是统计类别分布、空图率和尺寸一致性5619 张听起来量不小但遥感航拍数据的真实分布往往跟你预期差别很大。我一般拿到压缩包后第一件事是全量扫描统计每张图里有几个目标、每个类别多少实例、有没有完全没标注的“空图”。空图在训练里不是坏事适度保留可以降低误检但如果是标注人员漏标导致的大批空图你得知道这个事实否则训练完会发现验证集 mAP 很高、一到实飞全是误报。下面这个统计脚本对所有 XML 做全量扫描输出类别实例数、目标数分布和图像尺寸集合# stats.py # 统计 VOC XML 标注的类别分布、每张图目标数量、空图数量 import xml.etree.ElementTree as ET from pathlib import Path from collections import Counter xml_dir Path(Annotations) cls_counter Counter() img_target_counts [] empty_count 0 size_set set() for xml_path in sorted(xml_dir.glob(*.xml)): root ET.parse(xml_path).getroot() size root.find(size) w int(size.find(width).text) h int(size.find(height).text) size_set.add((w, h)) objs list(root.iter(object)) img_target_counts.append(len(objs)) if len(objs) 0: empty_count 1 for obj in objs: name obj.find(name).text cls_counter[name] 1 print(类别分布:) for name, cnt in cls_counter.most_common(): print(f {name}: {cnt}) print(f总图片数: {len(img_target_counts)}) print(f空图数: {empty_count}) print(f图像尺寸种类: {size_set}) print(f单图目标数: 最小 {min(img_target_counts)}, f最大 {max(img_target_counts)}, f平均 {sum(img_target_counts) / len(img_target_counts):.1f})这段统计的逻辑很简单但很有用图像尺寸种类直接决定训练时要不要统一调整尺寸。如果主体是 1024x1024少数是 2000x1500那训练时输入尺寸不能统一设太大否则小尺寸图被强行拉伸滑坡体比例失真。类别分布则决定要不要做类别重加权。空图数超过 10% 时我倾向在训练集里保留一部分并在验证集里也加一点防止模型学成“见地就报”。还有一种情况值得注意如果某张图里的目标数远大于平均值比如有张图标了 50 个滑坡体那就是密集堆积区域这种图的数量虽然少但对 loss 的影响很大。训练时最好单独看一眼这些图有没有标错密集区域的标注错误会被高权重放大。3.2 按“场景组”拆分训练/验证/测试而不是按文件随机拆这里是本数据集最容易翻车的地方航拍影像往往是从一张大正射影像切出来的瓦片同一条沟、同一个滑坡体会出现在连续好几张切片里。如果按文件随机划分两张内容高度重叠的切片可能一张进训练、一张进验证验证指标会被虚高到不可信实际部署时才发现模型根本没学会泛化。常见做法是先把图片按命名前缀分成“场景组”再对组做划分。比如ortho_001_1.jpg、ortho_001_2.jpg属于同一个场景ortho_001拆分组而不是拆单图。下面是划分脚本# split_dataset.py # 按文件名前缀分组组级别划分 train/val/test避免数据泄漏 import random import shutil from pathlib import Path random.seed(42) # 固定随机种子保证可复现 image_files list(Path(JPEGImages).glob(*.jpg)) def group_key(path: Path) - str: # 取文件名前两段作为场景组名 # 例如 ortho_001_5.jpg - ortho_001 # 如果你的命名规则不同先打印几个文件名看看再改这里 parts path.stem.split(_) return _.join(parts[:2]) groups {} for img in image_files: key group_key(img) groups.setdefault(key, []).append(img) group_names sorted(groups.keys()) random.shuffle(group_names) n len(group_names) train_groups set(group_names[:int(n * 0.8)]) val_groups set(group_names[int(n * 0.8):int(n * 0.9)]) test_groups set(group_names[int(n * 0.9):]) for split, selected in [(train, train_groups), (val, val_groups), (test, test_groups)]: img_out Path(images) / split lab_out Path(labels) / split img_out.mkdir(parentsTrue, exist_okTrue) lab_out.mkdir(parentsTrue, exist_okTrue) for key in sorted(selected): for img in groups[key]: shutil.copy(img, img_out / img.name) txt Path(labels) / f{img.stem}.txt if txt.exists(): shutil.copy(txt, lab_out / txt.name) print(f{split}: {len(selected)} 组, f{sum(len(groups[k]) for k in selected)} 张)说明这个脚本把文件按组划分后复制到images/train、images/val、images/test三个目录标签分别放进对应的labels/train等目录。选组还是选文件差别就是验证集里会不会出现“长得几乎一样”的图。我第一次跑遥感数据集时图省事直接随机拆文件结果 val 的 mAP 0.85换到另一条沟的影像上直接掉到 0.4后来才发现是组间泄漏。比例上用 8:1:1如果你的场景组数量很少可以改成 8:2 只留训练和验证测试用另一条航线的影像。分组的时候还要注意有些切图命名的前缀只到ortho_001这一层但不同航次可能共用同一个前缀这时分组键得加上航次信息否则又把不同场景的图混到一个组里。拿不准时可以打印每个组的图片数和首图路径人工抽查几组确认。3.3 生成训练用的 data.yaml类别名和路径一次写对YOLO 训练需要一个 yaml 文件指定数据路径和类别列表。类别列表直接取classes.txt不要手敲# landslide.yaml # 路径用绝对路径最稳因为 yolo 命令的工作目录经常跟你预期不一致 path: /data/landslide/ train: images/train val: images/val test: images/test # nc 和 names 由 classes.txt 生成下面只是示例占位 # 请以你解压后的 classes.txt 实际内容为准 nc: 2 names: 0: landslide 1: debris_flow注意上面的names需要跟你解压后的实际标签一一对应。常见做法是直接从classes.txt复制过来或者用脚本自动写 yaml。类别顺序必须和第 2 章转换脚本里的classes列表完全一致否则训练时类别索引错位模型学得越久错得越离谱。这个错位是新手最容易犯的错之一症状是训练 loss 正常下降但画出来的检测框名字和框内容对不上。验证 yaml 是否正确的方法很简单终端里跑一句yolo detect train datalandslide.yaml modelyolov8s.pt epochs1 imgsz640如果数据路径或标签缺文件ultralytics 会在第一轮就报错提示比训练到一半再发现省时间得多。4. 用 YOLO 跑通这条数据流从 yaml 到验证指标的全过程4.1 选模型遥感小目标场景yolov8s 起步最稳如果你是 YOLO 入门阶段遥感数据集第一个模型建议直接yolov8s.pt预训练权重。理由有三条s 参数量适中单卡 6GB 显存能跑训练速度快能快速验证数据本身有没有问题m 或 l 参数多但对 640 输入下的滑坡这种小目标帮助有限航拍小目标提升更依赖输入尺寸和切片策略而不是盲目加大模型x 在 5619 张这个规模上容易过拟合数据增强做得再狠也压不住。预训练权重是在 COCO 80 类上训出来的类别跟你不同但这没关系ultralytics 会自动把最后一层检测头替换成你的类别数。最新几代 YOLO 里v9 的 PGI 结构对中小目标更友好v11 在 C3K2 模块上做了轻量化改进但它们的预训练权重对遥感数据的适配并不比 v8 明显更好。我一般先用 v8s 跑通全流程拿到基线再拿同样的数据换 v9s 或 v11s 对比一轮用验证集 mAP 说话。不要一上来就追最新版本数据流没跑通之前换模型只会让问题更难排查。4.2 训练命令与四个关键超参数据划分完成、yaml 检查无误后训练命令很简单# 终端里直接跑 yolo detect train \ datalandslide.yaml \ modelyolov8s.pt \ epochs200 \ imgsz640 \ batch16 \ patience30 \ device0 \ projectruns \ namelandslide_v8s如果你习惯在 Python 里写训练流程等价写法是from ultralytics import YOLO model YOLO(yolov8s.pt) model.train( datalandslide.yaml, epochs200, imgsz640, batch16, patience30, projectruns, namelandslide_v8s, )四个关键超参说明imgsz是输入分辨率遥感数据建议 640 起步如果你的显卡显存够且多数原图是 1024 以上可以加到 1280小目标召回会明显变好但训练时间约翻倍。batch由显存决定6GB 卡用 1612GB 卡可以 32再大就用batch-1让框架自动探测。patience是早停轮数设 30 表示验证集指标连续 30 轮不提升就停遥感数据集噪声大这个值太小容易在平台期被误停。epochs设 200 但通常跑不到早停会拦下。还有两个跟增强相关的参数值得单独说。mosaic默认是 1.0对遥感切片图来说mosaic 把四张图拼在一起时很容易把小目标的框裁掉一半如果发现小目标掉点可以设mosaic0.5并配close_mosaic10意思是最后 10 轮关闭 mosaic 让模型收敛稳定。另外遥感数据不要开过大的scale增强滑坡体的纹理和灰度特征在拉伸后会失真模型学到的可能是被扭曲的纹理而不是滑坡本身。损失函数部分不用过度投入YOLO 的分类分支用 BCE框回归分支用 CIoU 加 DFL训练时你只需要盯着 loss 曲线是不是在下降、val 指标是不是同步上升。如果训练 loss 一直降、val loss 先降后升说明过拟合增大增强或缩小模型。4.3 训练过程中看什么loss 曲线、混淆矩阵和 PR 曲线训练跑起来之后别干等。打开runs/landslide_v8s/目录里面有每轮的results.png重点看三块训练 loss 应该在前 20 轮快速下降之后缓慢下降val/box_loss 和 val/cls_loss 如果跟训练 loss 拉开距离就是过拟合信号这时候可以把patience再调小一点让它早点停验证集 PR 曲线下面积就是 mAP 的浓缩曲线越靠近右上角越好但滑坡泥石流这类目标形状不规则mAP 0.6 在遥感场景已经算可用的基线。另外每轮结束后的confusion_matrix.png必看。它会暴露两类问题一是两类目标互相混淆滑坡被识别成泥石流这通常是标注边界不统一造成的回头清洗数据比调参有效二是背景误检率高很多非目标区域被当成滑坡这时候考虑在训练集里加空图。训练 loss 曲线偶尔会有玄学一样的抖动单轮抖动不用管连续多轮不降才是问题。我习惯每个项目训练时开一个终端定时看日志看到 val 指标连续 5 轮不动就手动去查数据而不是傻等。5. 航拍滑坡泥石流数据集训练的避坑指南五个必踩的坑5.1 坑一成对样本导致验证指标虚高实飞现原形现象训练时验证集 mAP 0.85模型看起来很强换到另一条沟、另一批影像上测试检测结果惨不忍睹。原因同一张大正射影像切出来的瓦片高度重叠划分时按文件随机拆训练集和验证集里出现了“内容几乎一样”的图模型相当于背了答案。解决按场景组划分也就是第 3.2 节的脚本确保同一场景的切片全部落在同一个集合里。除此以外还要对图片做一次去重用md5sum *.jpg找出哈希完全一致的重复图这些重复图即使场景前缀不同也属于同一内容混进两个集合会让验证集虚高。这个坑不看混淆矩阵看不出来因为训练过程一切正常只有换场景实测才会翻车是我所有踩过的坑里最阴的一个。5.2 坑二小目标框太多640 输入下直接漏检现象滑坡体在影像里只占 20x20 像素训练完模型漏掉大部分尤其是泥石流沟道的细长形目标。原因YOLO 的检测头在 80x80 的特征图上对 20 像素的目标本来就不敏感加上预设的 anchor 尺寸偏大、小目标样本占比少模型学到的框普遍偏大。解决优先把imgsz提到 1280这一步对小目标召回提升最直接显存不够就降 batch再用 SAHI 这类切片推理工具把大图切成 640 的块分别检测再拼接具体命令在第 6 章进阶做法是改用 NWD 损失西北工业大学提出的 Normalized Wasserstein Distance 用高斯分布距离代替 IoU能缓解微小框对 IoU 的剧烈抖动适合小目标场景。遥感场景里“小目标漏检”是常态不要指望换个大模型就能解决先看输入和切片。5.3 坑三类别不均衡泥石流类被滑坡类“吃掉”现象滑坡类有几千个实例泥石流类只有几百个训练完泥石流召回率不到滑坡的一半。原因YOLO 默认对所有类别等权训练样本多的类别在损失里占主导模型把有限的学习能力全花在滑坡上。解决先统计类别分布用第 3.1 节的脚本再给少数类抬高 loss 权重ultralytics 里在model.train()时传class_weights数组权重按“总实例数 / 该类实例数”归一化后传入即可。还有一个土办法单独对泥石流类做一次微调把验证集换成泥石流为主的子集看类别级 mAP 到底差多少再决定是加数据还是加权重。类别不均衡在遥感数据集里非常常见因为很多泥石流堆积扇在影像上跟裸地很难区分标注也少。5.4 坑四标注边界不统一同一个滑坡体不同 XML 里框的偏置方向不同现象训练收敛慢val mAP 波动大且预测框总比真实滑坡体大一圈。原因航拍影像里滑坡体边界是灰度渐变不同标注员对边界位置的判断不同有的框到裸露土石边缘有的框到植被线。解决用第 2.3 节的画框预览脚本抽查几十张定一个统一的边界规则比如“框到滑动面可见边缘不含外围拉裂区”对明显偏的样本重新标注。时间不够就做标签清洗用训练好的粗模型对训练集重新预测取预测框与原始框 IoU 低于 0.3 的样本拉出来人工复核。这项清洗通常能带来 2~3 个点的 mAP 提升比换模型划算得多。5.5 坑五zip 解压时路径、杀毒和文件损坏看起来小却卡住一整天现象解压到一半报failed to copy spatial iop zip之类的错误或者解压后训练时提示找不到图片检查发现某几张图或 XML 文件缺失。原因压缩包里如果带了中文文件名或过深的目录层级Windows 自带解压工具会截断路径部分杀毒软件会把某些文件当威胁直接隔离。解决解压前先看压缩包内目录结构用 7-Zip 或 WinRAR 解压到纯英文路径不要解压到桌面再移动。解压后用第 2 章的转换脚本跑一遍全量 XML缺一个文件都会立刻报错比训练时才报错好处理得多。数据文件从解压到训练全流程走通后把Annotations、labels、images三个目录的文件数各自统计一遍三者数量不一致就是有文件丢失先补齐再训。6. 验证闭环与进阶SAHI 滑窗推理和多时相变化检测6.1 用 SAHI 跑航拍大图的滑窗推理训练结束后验证模型最直接的手段是yolo detect val但 640 输入直接推理大图会漏小目标。我一般会用 SAHI 做切片推理把大图切成 640x640 的块带 20% 重叠推理后再拼接NMS 合并重叠框pip install sahifrom sahi import AutoDetectionModel from sahi.predict import get_sliced_prediction detection_model AutoDetectionModel.from_pretrained( model_typeyolov8, model_pathruns/landslide_v8s/weights/best.pt, confidence_threshold0.3, image_size640, devicecuda:0, ) result get_sliced_prediction( imagetest_images/ortho_001.jpg, detection_modeldetection_model, slice_height640, slice_width640, overlap_height_ratio0.2, overlap_width_ratio0.2, ) result.export_visuals(export_diroutput/)overlap_height_ratio和overlap_width_ratio设 0.2 以上避免目标恰好被切在切片边界上导致漏检。这一步对遥感小目标的提升通常比换大模型更明显也是我验证阶段最常用的技巧。6.2 进阶把 5619 张当作预训练底料做面积估算与多时相变化检测这套数据训出来的检测器并不止于“框出来”。检测框可以直接换算成滑坡体像素面积再结合影像分辨率估算真实面积更进阶的做法是把模型拿去做多时相变化检测的预训练编码器对同一区域汛期前后的影像分别检测再对齐比对自动识别新增滑坡。这个方向门槛不高但收益很大很多地灾单位的日常工作就是这种“前后对比”。这几年我做遥感目标检测被数据集坑的次数远超被模型坑的次数。标注边界不统一、小目标漏检、成对数据泄漏每一类都是先付了时间成本才长记性。这份 5619 张的数据集双格式齐备已经帮你省掉了格式转换那一半的坑剩下的一半要靠你自己跑一遍统计、划分和预览来避开。希望帮到你。本文还有配套的精品资源点击获取