ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

卫星遥感舰船检测数据集:17类2238张VOC/YOLO双格式,YOLO训练直接可用

卫星遥感舰船检测数据集:17类2238张VOC/YOLO双格式,YOLO训练直接可用 简介面向遥感目标检测、船舶识别等视觉任务该数据集对应2238张卫星遥感舰船影像的检测标注采用Pascal VOC与YOLO两种主流格式可直接用于Faster R-CNN、SSD、YOLO系列模型的训练与验证有效解决公开舰船遥感样本稀缺、标注格式分散难统一的问题。包内共2000个文件以1999个XML标注文件为主体另含TXT使用说明打包后约109.32MB标注覆盖航空母舰、辅助舰、货船、指挥舰、集装箱船、巡洋舰、驱逐舰、船坞、护卫舰、气垫船、登陆舰、油轮、其他船舶、其他军舰、滚装船、潜艇、游艇等全部17类舰船目标每类均有独立类别标签适合训练多类别遥感舰船检测器。该类数据在海洋监控、航道管理、国防安全等场景中具有实用价值。目前已有835人学习下载资源内附使用前必读说明可帮助用户快速理解标注文件结构免去自行整理与格式转换的时间成本。1. 卫星遥感舰船检测这个17类2238张双格式数据集为什么值得备一份做卫星遥感目标检测的人手头最缺的往往不是模型而是干净、带专业类别标注的数据。舰船检测和通用目标检测不一样它要面对的是小尺寸目标、密集停泊的港口、形似度极高的不同舰型以及光学影像里难以避免的云雾和阴影。这份名为「卫星遥感舰船检测数据集VOCYOLO格式2238张17类别.7z」的资源核心内容很直接2238张卫星遥感jpg图片每张图片配套一个Pascal VOC格式的xml标注文件和一个YOLO格式的txt标注文件覆盖17个舰船相关类别——从航空母舰、驱逐舰到气垫船、潜艇、游艇都在列表里。对于正在做YOLO系列模型训练、需要现成遥感舰船数据跑通流程的从业者来说这是可以直接拿来替换自己手中那批杂乱数据集的落地资源省去从原始影像里重新标注的几天时间。适合的人群也很明确一是刚入门YOLO目标检测、需要一份类别完整且格式规范的数据集来试验训练流程的新手二是已经在做船舶检测、想补充更多类别或验证模型泛化能力的算法工程师。唯一要提前说清楚的是这份数据集的txt标注里不包含分割路径只是纯粹的类别加坐标所以它是检测任务专用不是实例分割任务的数据。接下来我会从数据格式的底层逻辑开始一路拆到训练参数怎么设、坑在哪些地方。2. 数据集的底细VOC与YOLO两种标注怎么对应、目录怎么摆拿到压缩包之后第一件事不是解压跑训练而是先搞懂里面的两种标注格式是怎么描述同一张图的。很多人在这一步就翻车了以为xml和txt是两种独立标注结果发现它们表述的是同一个目标只是坐标体系不同用错一个就会导致训练时边界框偏移。2.1 一张图配两种标注xml 与 txt 到底差在哪Pascal VOC格式的xml文件记录的是绝对坐标和类别名。一个典型的firc_ship_2222.xml里每个object节点下面会有name标签、bndbox子节点里面存着xmin、ymin、xmax、ymax四个值单位是像素。它的信息是给人看的也方便你用LabelImg这类工具二次编辑。YOLO格式的txt文件则是给模型训练吃的每一行对应一个目标格式是类别索引 中心点x 中心点y 宽度 高度而且全部做了归一化取值范围在0到1之间。类别索引不是直接写类别名而是按类别顺序映射成整数。所以如果你改了类别顺序txt里的每一行意义就全变了。把两者对应起来的关键公式是# 假设 xml 里的 bndbox 给出绝对坐标 xmin, ymin, xmax, ymax # 图片原始宽高为 img_w, img_h # 计算 YOLO 格式需要的中心点坐标和宽高 center_x ((xmin xmax) / 2) / img_w center_y ((ymin ymax) / 2) / img_h box_width (xmax - xmin) / img_w box_height (ymax - ymin) / img_h这个转换逻辑是所有VOC转YOLO脚本的底层原理。归一化之后坐标和图片尺寸解耦模型训练时resize输入图才不会破坏标注的有效性。如果你拿到的数据集里xml和txt都是配好的那直接用即可如果要自己改类别、筛目标就得重新跑一遍这个公式生成新的txt而不是手工改。2.2 17个类别的清单与标注约定这份数据集标注了17个类别覆盖了民用商用船舶和军用舰艇两个维度。类别清单本身就是一个重要参考它决定了模型的天花板——你能检测出什么取决于数据集里有什么。类别索引类别名称说明0Aircraft Carrier航空母舰属大型水面舰艇1Auxiliary Ships辅助舰船如补给舰等2Cargo货船3Commander指挥舰4Container Ship集装箱船5Cruiser巡洋舰6Destroyer驱逐舰7Dock船坞8Frigate护卫舰9Hovercraft气垫船10Landing登陆舰11Oil Tanker油轮12Other Ship其他船只13Other Warship其他军舰14RoRo滚装船15Submarine潜艇16Yacht游艇这里要注意几个容易忽略的细节。Dock是停泊设施而不是船它出现在目标框里说明这张图是港口场景模型会把码头也当作一个语义目标来学。Auxiliary Ships和Other Warship这类类别是典型的“兜底类”它们的存在说明数据源方的标注策略是针对不确定性目标专门开了桶而不是硬塞进相近类别。这其实是好事因为强制把不明舰船归入Destroyer或Frigate反而会让模型产生类别混淆。2.3 拿到压缩包之后目录结构与解压检查解压之后你会看到三类文件混在一起2238张jpg、2238个xml、2238个txt。没有额外的子目录分层train/val/test的划分要自己来做。这看起来简单但有一个隐藏风险——文件名前缀都是一样的firc_ship_加上不连续的数字编号比如firc_ship_18、firc_ship_27、firc_ship_1092如果脚本里用了glob读文件然后按字母序index容易出现训练集和验证集之间类别失衡。我拿到压缩包后的习惯是先在Linux或Windows下做一轮文件完整性核对# 列出所有 jpg、xml、txt 文件个数确认三者为 2238 ls -l *.jpg | wc -l ls -l *.xml | wc -l ls -l *.txt | wc -l # 抽出没有对应 xml 的孤儿图片这类图要剔除 find . -name *.jpg | sed s/\.jpg$// jpg_names.txt find . -name *.xml | sed s/\.xml$// xml_names.txt comm -23 jpg_names.txt xml_names.txt这里每一步都是必要的。第一步确认三个文件数目都是2238能第一时间发现下载损坏或解压遗漏第二步找孤儿图片是为了防止训练时xml缺失导致YOLO直接跳过该样本而你以为数据全在。7z压缩包解压目前在Linux上最常见的是用p7zip工具链命令是7z x 文件名.7z如果是带密码的包则在命令后补上-p密码。Windows下用Bandizip或7-Zip图形界面解压都可以但要注意解压路径不要带中文否则YOLO训练时opencv读图会偶尔报奇怪错误。3. 把数据喂给YOLO目录改写、类别配置与训练参数的一次成型数据本身是VOCYOLO双格式但真正训练YOLO时模型只认txt文件和data.yaml配置。这一章的目的是让你从解压好的散装文件一步到位整理成能跑YOLOv5或YOLOv8训练的标准目录结构。不要图省事把txt直接丢进训练命令里YOLO的训练管线对目录结构是有强约定的。3.1 从解压目录整理成 YOLO 可用的 data.yamlYOLO系列的train.py、val.py在读取数据时靠的是data.yaml里的路径和类别信息。你需要在数据集根目录下新建images和labels两个文件夹并把图片和txt分别放进去。更规范的做法是在images内部再划分train和val子集labels保持同样的划分结构。我的建议是直接用脚本做这一步千万别手动拖2238个文件人手操作必然出错import os import random import shutil from pathlib import Path # 定义路径 src_dir Path(D:/ship_dataset) # 解压后的目录 images_dir src_dir / images labels_dir src_dir / labels # 建立目录 for split in [train, val]: (images_dir / split).mkdir(parentsTrue, exist_okTrue) (labels_dir / split).mkdir(parentsTrue, exist_okTrue) # 读取全部 jpg 文件名排除无标注的孤儿图 jpg_files [p for p in src_dir.glob(*.jpg)] random.seed(42) random.shuffle(jpg_files) # 按 9:1 划分 val_count int(len(jpg_files) * 0.1) val_files jpg_files[:val_count] train_files jpg_files[val_count:] for split, file_list in [(train, train_files), (val, val_files)]: for img_path in file_list: # 复制图片 shutil.copy(img_path, images_dir / split / img_path.name) # 复制对应标签 txt_path src_dir / (img_path.stem .txt) if txt_path.exists(): shutil.copy(txt_path, labels_dir / split / txt_path.name)这里有几个参数值得注意。random.seed(42)固定随机种子确保每次划分的结果一致方便复现val_count直接按总数量的10%取这是遥感数据常见的划分法如果某个稀有类别恰好全落进val可以再调整。复制文件而非移动文件是保留原始数据的习惯方便后面回退重来。接着在数据集根目录新建data.yamlpath: D:/ship_dataset train: images/train val: images/val nc: 17 names: 0: Aircraft Carrier 1: Auxiliary Ships 2: Cargo 3: Commander 4: Container Ship 5: Cruiser 6: Destroyer 7: Dock 8: Frigate 9: Hovercraft 10: Landing 11: Oil Tanker 12: Other Ship 13: Other Warship 14: RoRo 15: Submarine 16: Yacht注意names的索引顺序必须和txt里每行开头的整数完全对应。这份数据集原始txt的类别顺序就是从0到16的所以上面这个yaml改都不用改。如果你自己过滤过类别一定要同步重写txt里的索引否则训练不会报错但模型永远学不对。3.2 标注质量检查可视化这一步不能省在花几小时跑训练之前先用最笨的办法抽查一下标注长什么样。我一般会随机挑40张train图片把xml里的框画上去保存成拼图看一眼。这一步能发现大量隐性问题框偏向一侧、目标整体偏小、类别串味等。import cv2 import random import xml.etree.ElementTree as ET def draw_voc_boxes(img_path, xml_path, output_path): img cv2.imread(str(img_path)) tree ET.parse(str(xml_path)) root tree.getroot() for obj in root.iter(object): name obj.findtext(name) bndbox obj.find(bndbox) xmin int(float(bndbox.findtext(xmin))) ymin int(float(bndbox.findtext(ymin))) xmax int(float(bndbox.findtext(xmax))) ymax int(float(bndbox.findtext(ymax))) cv2.rectangle(img, (xmin, ymin), (xmax, ymax), (0, 255, 0), 2) cv2.putText(img, name, (xmin, ymin - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 1) cv2.imwrite(str(output_path), img) # 随机挑 40 张可视化 random.seed(1) for i in random.sample(range(2238), 40): jpg src_dir / ffirc_ship_{i}.jpg xml src_dir / ffirc_ship_{i}.xml if jpg.exists() and xml.exists(): draw_voc_boxes(jpg, xml, fD:/check/{i}.jpg)用xml来画而不是用txt是因为xml保留的类别名是人可读的txt里只有数字看到0你还得去翻映射表。可视化结果里如果出现框完全超出图像边界或者框和船身不贴合说明这个样本标注质量差需要从训练集里剔掉。3.3 启动训练YOLOv8 与 YOLOv5 的差异按当前生态YOLOv8和YOLOv5都在大量使用二者读取的数据集结构几乎一致。启动训练主要差在命令行入口# YOLO8 训练img 设为 1280 以适配遥感小目标 yolo detect train dataD:/ship_dataset/data.yaml \ modelyolov8s.pt \ imgsz1280 \ batch8 \ epochs100 \ projectruns/ship_detect # 同一份数据跑 v5关键参数名字略有不同 python train.py --data D:/ship_dataset/data.yaml \ --weights yolov5s.pt \ --img 1280 \ --batch 8 \ --epochs 100 \ --project runs/ship_detect_v5imgsz设为1280是我在这个数据集上的建议后文会专门讲为什么。batch8是常规显存假设如果你用4090或更高显存卡可以调到16但数据本身就2000多张batch的影响远没有学习率和imgsz大。epochs100对这个小数据集来说够跑出收敛趋势但如果loss还在明显下降可以继续加到150。4. 针对卫星舰船场景的调参小目标、密集排列、类别相似三个硬骨头很多人拿通用目标检测的参数直接套遥感舰船数据结果mAP50看着还行mAP50-95惨不忍睹。这不是模型不行是没理解卫星影像里舰船目标的特殊性。这一章把三个最影响结果的点单独拿出来说每个都配了可抄的参数修改方案。4.1 卫星舰船为什么难检先理解数据分布把数据集里的目标框统计一遍就能发现规律。我建议你写个小脚本把2238张图里的目标宽高分布打出来大概率看到的结果是超过70%的目标框边长小于图片边长的一半很多是几十像素到一百多像素的小块。这符合卫星遥感影像的典型场景——卫星轨道高度和分辨率决定了船只目标在整幅影像里本身就不大港口里并排停靠的军舰更是密集排列目标之间几乎没有间隔。这就带来两个连锁问题。第一默认下采样倍数过大的YOLO结构对小目标不友好特征图缩小到原来的1/32时几十像素的船可能只剩下几个特征点。第二密集排列会导致NMS误杀两个紧挨着的框置信度都挺高但后处理的NMS阈值设高了会保留一堆重叠框设低了会把两条紧贴的船删成一个。4.2 针对小目标加大输入分辨率与多尺度策略处理小目标最直接有效的手段是提高输入分辨率。YOLO默认的640分辨率会直接把小船的细节抹掉而imgsz1280相当于把输入图的面积放大四倍深层的特征图能保留更多舰船结构信息。代价是显存占用和训练时间上升batch8在1280分辨率下显存压力已经不小。除了分辨率多尺度训练也是遥感场景的常见做法。YOLO自带的hyp参数里有个scale字段控制每张图在训练时随机缩放的比例# 官方 hyp.scratch.yaml 里的多尺度增强参数 scale: 0.5 # 图片随机缩放比例范围我把scale从0.5放宽到0.9让模型随机看到从小到大不同尺度的船只增强对尺度变化的适应力。但要注意scale调太大容易让目标缩到几乎不可见反而拉低收敛速度0.5到0.9之间是个安全区间。另外YOLOv8里有tune的自动调参工具但我在这个数据集上不推荐直接跑autoanchor之前先看anchor质量。YOLO默认的anchor是为COCO设计的检测的是占据画面大比例的目标。卫星舰船目标普遍小直接沿用默认anchor会导致正样本匹配数量偏低。AutoAnchor其实是有效的它会在训练前重新聚类anchor但如果你关闭了它就得手动改# 在 data.yaml 里显式指定 anchor先由 kmeans 计算 # 常见做法用聚类工具对训练集所有标注框跑 kmeans得到 9 个 anchor python tools/autoanchor_yolo.py --data D:/ship_dataset/data.yaml --num_clusters 9跑完会输出一组适合当前数据的anchor宽高填到模型配置文件的anchors字段里。航拍和遥感数据集几乎都需要走这一步我用COCO原始anchor在这个数据集上训练mAP50-95比聚类anchor低了差不多3个点。4.3 针对密集排列NMS 参数与 loss 层面的调整密集停靠的港口是舰船检测里最典型的坑。相邻两艘驱逐舰的框IoU能到0.6以上如果NMS的IoU阈值设成0.45置信度稍低的一艘很可能被高置信度的另一艘直接吞掉。我的经验是把这个数据集上的NMS IoU阈值调到0.3同时把conf_thres放低到0.1让模型先召回大量候选框再从里面挑。# 推理阶段调整 NMS 参数 yolo detect predict modelruns/ship_detect/weights/best.pt \ sourceD:/ship_dataset/images/val \ imgsz1280 \ conf_thres0.1 \ iou_thres0.3conf_thres降低带来的副作用是预测框数量暴增但对密集场景来说多出来的都是被NMS压住的真值宁可看到一堆重叠的冗余框也不要让两艘相邻军舰被合并成一个。训练阶段还有一个相关参数是YOLOv8的close_mosaic它控制最后10个epoch是否关闭Mosaic增强。我会在最后15个epoch关掉Mosaic由模型适应真实分布否则模型在验证集上经常出现小目标漏检。5. 避坑与排查7z解压、标注不匹配、类别错位和显存不足的处置记录数据集的坑往往不在算法层面而在数据工程层面。这一章把我实际踩过和见过别人踩过的坑集中列出来每条按现象、原因、解决的顺序写清楚你遇到同样问题时可以直接按图索骥。5.1 7z解压失败解出来的文件是0字节现象下载的.7z文件用Windows自带解压功能或者老版本解压工具打开时提示文件损坏强行解压后大量图片0字节。原因7z是比zip压缩率更高的格式但Windows系统默认右键解压不支持7z很多在线解压工具对超过一定体积的7z文件支持不完整。解决Linux下用p7zip-full工具链Windows下用7-Zip或Bandizip不要用浏览器插件或在线网站。命令行里最常见的解压命令是7za x 文件名.7z -o输出目录注意7za和7z是两个不完全相同的命令7za功能精简部分带加密头的7z文件解压失败我遇到过不止一次换成7z命令就正常了。5.2 训练日志显示图片数为0现象命令行启动训练后第一轮迭代没有报错但训练日志里显示images数量为0模型完全不学习。原因YOLO读取标签时txt文件名必须和jpg文件名完全一致且labels目录结构和images目录结构必须一一对应。很多人解压后直接新建了labels文件夹把txt扔进去但忘了images里也建train和val子目录YOLO找不到对应的图片。解决按照第3章的脚本重新整理目录确保images/train里有jpglabels/train里有同名txt两边数量一致再用yolo check或脚本验证一遍。5.3 类别索引错位txt 里第 0 类不是航空母舰现象训练结束后模型把一艘驱逐舰识别成航空母舰但验证集mAP又很高。原因是下载的数据集压缩包里的txt文件类别顺序和README里描述可能不一致有人手动增删过类别后没有重排txt导致txt里面的0实际是Cargo。解决不要依赖原始txt里的数字顺序按xml里的实际类别名重新生成一遍YOLO txt以xml为唯一事实来源。这也是我总是推荐用VOC xml做二次处理的原因类别名可读性太重要了数字索引根本没有自我纠错能力。5.4 显存不足batch降了还是爆显存现象imgsz1280加batch8在24G显存显卡上OOMbatch降到2依然报错。原因输入分辨率提升到1280后中间特征图的显存占用呈平方级增长batch8的需求可能远超显存。解决一种做法是保持batch8但开启梯度累积YOLOv8里配置optimizerSGD、ampTrue并降低batch到4通过accumulate参数补偿梯度更新频率另一种更省显存的做法是退回到imgsz960训练YOLO在960下对小目标的检测能力已经比640好很多。如果你一定要用1280建议模型从yolov8n或yolov8s开始不要直接上yolov8l。5.5 Loss 明显不下降检查学习率和数据增强现象训练到60个epochbox_loss和cls_loss都趋于平缓但验证集mAP波动剧烈。原因学习率设置过高导致模型在最优值附近反复震荡或者是Mosaic增强在训练后期干扰了模型收敛。解决把初始学习率从默认的0.01降到0.001并配合warmup_epochs适当延长同时将close_mosaic设为15让最后15个epoch用真实图片分布精修。我在YOLOv8还多做过一个改动是把mosaic1.0降到0.8给模型更少的拼接假图实验下来小目标漏检率下降明显。6. 验证这2238张的价值用mAP与可视化确认模型真的学到了舰船特征训练结束不代表模型能用。这个数据集真正的价值取决于你能否确认它让你训练的模型具备可靠的舰船检测能力。最后的验证环节我建议按照由粗到细的顺序做三轮检查每轮都有具体操作和通过标准。第一轮看验证集指标。训练完成的best.pt在val集上的mAP50应该不低于0.75、mAP50-95不低于0.5才算这份数据发挥出了应有的价值。如果mAP50-95明显偏低而mAP50正常说明模型能框出大概位置但边界框定位精度差优先调anchor和回归损失权重。第二轮看类别混淆矩阵这是最容易被忽略的。YOLOv8训练完会在runs目录生成混淆矩阵图重点关注Cargo、Container Ship和RoRo这三类之间有没有互相误检。如果三者的混淆严重是因为这三类船型在卫星影像里都是长方形的货船形态只能靠甲板细节区分。这时候我的做法是挑出混淆矩阵里误检最集中的图片单独做一轮针对性的剪裁增强训练把这三类目标在训练集里的占比临时提高。第三轮是把模型导出成ONNX用训练以外的真实场景图跑一次推理。导出命令是yolo export modelruns/ship_detect/weights/best.pt formatonnx opset11 opencv_visualize_model.exe --model best.onnx --input real_ship.png --imgsz 1280导出ONNX不只是为了部署它同时验证了模型权重没有被训练框架特定逻辑绑定。在实际场景图里如果模型能正确检测出密集停泊的军舰编队、单艘游艇和港口中的小型辅助船这个2238张数据集的落地价值就算是真正兑现了。最后一个提醒是这份数据集的17类别里包含了Dock和Landing这类非典型船只目标如果你只需要检测航行中的舰船建议在训练前直接删掉这两个类别重新生成对应的txt和data.yaml删除后类别索引需要重新映射这一步骤我建议做成脚本自动化处理而不是手动修改。从那以后我每次拿到新数据集都强制走一遍统计、可视化、重排索引的流程虽然多花了二十分钟但后面训练翻车概率低了很多。希望帮到你。本文还有配套的精品资源点击获取
返回列表