简介:这份资源面向计算机视觉学习者与目标检测开发者,提供一套可直接投入训练的9类岩石检测数据集,覆盖玄武岩、石灰岩、沉积岩等常见岩性,适合入门YOLO训练流程或开展地质图像识别实验。包内共2000个文件,以1999个txt标注文件和1个Python可视化脚本为主,压缩包约637MB,数据按YOLOv5目录结构组织,无需额外转换即可使用。训练集含12501张图片及对应标签,验证集含1104张图片及对应标签,图像为640×640分辨率RGB图,并做了四图融合的马赛克增强,标注框完整,每张图包含多个目标,坐标采用YOLO相对格式。类别class文本文件单独给出,方便直接配置模型。附带的show.py可随机读取一张图片并绘制边界框,运行后自动保存到当前目录,无需修改即可查看标注效果。目前已有719人学习,适合想快速验证检测方案、节省数据清洗时间的中高级开发者。
1. 岩石检测数据集怎么选:9 类标注、12501 张训练图的 YOLO 落地包
手上接了个地质辅助识别的活儿,客户扔过来一堆野外露头照片,问能不能自动把玄武岩、石灰岩、沉积岩这些常见岩性框出来。自己从零标数据?光分类标准就能扯皮半个月。我翻到这个 9 类岩石检测数据集时,第一反应是「终于不用当标注民工了」——它把训练集 12501 张、验证集 1104 张全部按 YOLOv5 的目录结构摆好,图片统一 640×640 RGB,每张都有对应的 txt 标签,还附了类别文件和可视化脚本。说白了,这是一份开箱即用的目标检测数据包,适合做地质图像识别、岩性分类检测的团队直接拿去训练,也适合刚接触 YOLO 数据集的人拿来练手,省掉最耗时的清洗和划分环节。
2. 拆开目录看门道:YOLOv5 结构、9 类 class 与马赛克增强
2.1 目录结构决定了你能不能直接开训
拿到一个数据集,我习惯先tree一下看骨架,而不是急着写训练脚本。这份数据按 YOLOv5 的标准布局组织,核心就是images和labels两个平行目录,各自再分train和val。这种结构的好处是,YOLOv5 的train.py默认就认这个路径,你几乎不用改data.yaml里的目录指向,填个类别数就能跑。
# 查看数据集顶层结构,确认 images/labels 是否平行 tree -L 3 datasets/ # 预期输出类似: # datasets/ # ├── images # │ ├── train (12501 张 jpg) # │ └── val (1104 张 jpg) # └── labels # ├── train (12501 个 txt) # └── val (1104 个 txt)逻辑说明:images/train和labels/train必须一一对应,文件名主干相同、扩展名不同。参数上,图片是 640×640,意味着你训练时的imgsz设 640 最省事,不用做额外缩放。如果目录层级不对,YOLOv5 会直接报找不到标签,这是新手最常见的翻车点。
2.2 9 类岩石的 class 文件与标注格式
类别文件是一份纯文本,每行一个类名,顺序就是标签里 class id 的映射。这份数据覆盖 9 种岩石,从玄武岩、石灰岩到沉积岩等。标注格式是 YOLO 的相对坐标:class x_center y_center width height,数值都在 0 到 1 之间。相对坐标的好处是跟图片尺寸解耦,你换分辨率也不用重标。
# 读取一个标签文件,验证格式与类别映射 class_names = open("classes.txt").read().strip().split("\n") print("类别数:", len(class_names), class_names) with open("labels/train/Sedimentary_Limestone45_jpg.rf.b42b0773fed4e4e490c5f9ee7fa97f98.txt") as f: for line in f: cid, x, y, w, h = line.split() # 断言坐标在 0~1 之间,越界说明标注有问题 assert 0 <= float(x) <= 1 and 0 <= float(w) <= 1, "坐标越界" print(f"类别={class_names[int(cid)]} 中心=({x},{y}) 宽高=({w},{h})")逻辑说明:class_names的索引必须和标签里的cid严格对应,错一位整个训练就废了。参数上,x_center、y_center是框中心相对整图的比例,w、h是框宽高相对整图的比例。我一般会跑一遍断言,把越界或负数坐标的样本挑出来,避免训练时 loss 突然飙高。
2.3 马赛克增强意味着什么
数据说明里提到对图像做了马赛克增强,也就是把四张图拼成一张。这属于 YOLO 训练里的常规操作,能提升小目标和遮挡场景的鲁棒性。但要注意:增强后的图里目标框会变小、变密,如果你再叠加自己的强增强,可能过拟合到拼接边缘。常见做法是训练时保留 YOLOv5 默认的 mosaic 开关,但把mosaic的概率适当调低,或者在前几个 epoch 关掉,让模型先学干净样本。
提示:马赛克增强是训练期行为,数据集里存的仍是原始单图,别误以为每张图都是四合一。
3. 可视化脚本 show.py:随机抽图、画框、存盘一条龙
3.1 脚本怎么跑起来
数据包里的show.py是专门用来肉眼验数据的。它的设计很省心:随机传入一张图片,自动读取同名标签,把边界框画上去,然后保存在当前目录。你不需要改任何路径,只要保证脚本和数据集在同一工作目录下。
# 直接运行,脚本会随机抽一张图并输出带框的可视化结果 python show.py # 输出示例:已保存可视化结果 -> Sedimentary_Limestone45_jpg.rf.b42b0773fed4e4e490c5f9ee7fa97f98_vis.jpg逻辑说明:脚本内部一般会先随机选一个images/train下的文件名,去掉扩展名后去labels/train找同名 txt,逐行解析坐标并反归一化成像素坐标,再用 OpenCV 或 PIL 画矩形和类别文字。参数上,框的颜色和线宽通常写死在脚本里,想改就搜rectangle或putText那几行。
3.2 自己改一版可视化:指定图片和颜色映射
随机抽图适合抽查,但排查特定样本时我想指定文件。下面这段是我在show.py基础上改的,加了固定类别颜色,方便对比不同岩性。
import cv2, os, random class_names = open("classes.txt").read().strip().split("\n") # 给 9 个类别各分配一个固定颜色,避免每次颜色乱跳 colors = [(255,0,0),(0,255,0),(0,0,255),(255,255,0), (255,0,255),(0,255,255),(128,0,0),(0,128,0),(0,0,128)] def visualize(img_path, label_path, save_path="vis_out.jpg"): img = cv2.imread(img_path) h, w = img.shape[:2] with open(label_path) as f: for line in f: cid, x, y, bw, bh = map(float, line.split()) # 反归一化:中心坐标乘宽高,再换算成左上右下 x1 = int((x - bw/2) * w); y1 = int((y - bh/2) * h) x2 = int((x + bw/2) * w); y2 = int((y + bh/2) * h) cv2.rectangle(img, (x1,y1), (x2,y2), colors[int(cid)], 2) cv2.putText(img, class_names[int(cid)], (x1, y1-5), cv2.FONT_HERSHEY_SIMPLEX, 0.6, colors[int(cid)], 2) cv2.imwrite(save_path, img) print("saved:", save_path) # 指定一张图验证 visualize("images/train/Sedimentary_Limestone45_jpg.rf.b42b0773fed4e4e490c5f9ee7fa97f98.jpg", "labels/train/Sedimentary_Limestone45_jpg.rf.b42b0773fed4e4e490c5f9ee7fa97f98.txt")逻辑说明:反归一化那两行是核心,(x - bw/2) * w把中心点转成左上角像素。参数上,colors列表长度必须等于类别数,否则索引越界。线宽 2 和字号 0.6 是我在 640 图上看着舒服的值,图更大就调大。
3.3 用可视化做数据质检
别小看这个脚本,它是我验数据的第一道关。随机跑十几次,重点看三件事:框有没有明显偏移、类别文字和岩石外观是否对得上、有没有漏标的大块岩石。如果发现某类岩石的框总是偏,大概率是标注时中心点算错了,这种样本在训练里就是噪声源。
注意:可视化只验证标注和图片的对应关系,不验证类别语义是否正确。语义层面的错标得靠人工抽检。
4. 从数据包到训练:data.yaml 配置与 YOLOv5/v8 跑通
4.1 写一份能直接用的 data.yaml
YOLOv5 和 YOLOv8 都吃data.yaml,区别只在字段名略有不同。下面这份我按这份数据的实际路径填好,你改一下path就能用。
# data.yaml —— 岩石检测数据集配置 path: ./datasets # 数据集根目录 train: images/train # 相对 path 的训练图目录 val: images/val # 相对 path 的验证图目录 nc: 9 # 类别数,必须和 classes.txt 行数一致 names: # 类别名,顺序即 class id - Basalt - Limestone - Sedimentary - Coal - Marble - Igneous - Metamorphic - Sandstone - Shale逻辑说明:nc和names长度必须一致,且顺序要和classes.txt完全对齐,否则模型学到的类别全是错的。参数上,train和val写相对路径更稳,换机器不用改绝对路径。如果你的目录名不是images/train,这里要同步改。
4.2 YOLOv5 训练命令与关键参数
# YOLOv5 训练,imgsz 设 640 匹配数据分辨率 python train.py \ --data data.yaml \ --weights yolov5s.pt \ --img 640 \ --batch 16 \ --epochs 100 \ --mosaic 0.5 \ --project runs/rock逻辑说明:--weights yolov5s.pt用预训练权重起步,收敛快很多。--img 640和图片原生分辨率一致,避免缩放损失。--batch 16是 16G 显存下的稳妥值,显存小就降到 8。--mosaic 0.5把马赛克概率降到一半,因为数据本身已经增强过,再叠满容易过拟合拼接边缘。--epochs 100是起点,看验证集 mAP 不再涨就可以停。
4.3 YOLOv8 训练命令的差异
# YOLOv8 训练,字段名和 v5 略有不同 yolo detect train \ data=data.yaml \ model=yolov8s.pt \ imgsz=640 \ batch=16 \ epochs=100 \ mosaic=0.5 \ project=runs/rock逻辑说明:v8 用yolo detect train子命令,参数用等号连接。model=yolov8s.pt对应 v5 的--weights。其余语义一致。注意 v8 的mosaic参数同样存在,调法一样。
4.4 训练时盯什么指标
跑起来后别干等,盯三个东西:box_loss是否稳定下降、验证集mAP@0.5是否爬升、cls_loss有没有异常震荡。如果box_loss降但mAP不涨,多半是类别混淆,去看混淆矩阵。如果 loss 直接 NaN,先查标签有没有越界坐标,再查学习率是不是太大。
提示:这份数据验证集有 1104 张,足够给出稳定的 mAP 估计,不用自己再切分。
5. 避坑与排查:坐标越界、类别错位、显存崩溃怎么救
5.1 现象:训练一启动就报标签越界
原因:YOLO 要求所有坐标在 0 到 1 之间,但标注时可能手滑写出 1.02 或负数。解决:跑一段校验脚本,遍历所有标签,把越界行打印出来,要么修正要么剔除该样本。
import glob bad = [] for txt in glob.glob("labels/train/*.txt"): for i, line in enumerate(open(txt)): vals = list(map(float, line.split()[1:])) if any(v < 0 or v > 1 for v in vals): bad.append((txt, i, vals)) print("越界样本数:", len(bad)) for b in bad[:10]: print(b)5.2 现象:训练 loss 正常但预测类别全乱
原因:data.yaml里的names顺序和classes.txt不一致,或者nc写错。解决:把两个文件的类别列表逐行 diff 一遍,确保顺序和数量完全一致。这是最隐蔽的坑,因为训练不会报错,只是学错。
5.3 现象:跑到一半显存爆了
原因:batch太大,或者imgsz被误设成 1280。解决:先把batch减半,再把imgsz确认回 640。如果还爆,检查是不是开了过多 dataloader worker,把workers降到 4。
5.4 现象:验证集 mAP 远低于训练集
原因:过拟合,或者验证集分布和训练集差异大。解决:先加数据增强(旋转、亮度),再降模型规模(从 s 换 n),最后检查验证集里有没有训练集没见过的岩石外观。这份数据训练验证同源,正常情况差距不该太大。
5.5 现象:可视化脚本画不出框
原因:图片路径和标签路径没对上,或者脚本工作目录不对。解决:在脚本里打印实际读取的路径,确认images和labels的文件名主干一致。常见是图片是.jpg而标签是.txt,主干必须完全相同。
6. 进阶技巧:用混淆矩阵反推标注质量与类别合并策略
训练完拿到混淆矩阵,别只看总体准确率。我习惯把矩阵导出来,按行归一化,看每一类的误判去向。比如石灰岩大量被判成沉积岩,可能是这两类在图像上本就接近,标注时边界模糊。这时候有两个选择:一是回去补标难分样本,二是干脆把易混类合并,减少类别数换精度。
import numpy as np, seaborn as sns, matplotlib.pyplot as plt # 假设 cm 是 9x9 混淆矩阵,来自验证集评估 cm = np.array([[...]]) # 实际从评估脚本读取 cm_norm = cm / cm.sum(axis=1, keepdims=True) # 按行归一化 plt.figure(figsize=(10,8)) sns.heatmap(cm_norm, annot=True, fmt=".2f", xticklabels=class_names, yticklabels=class_names, cmap="Blues") plt.xlabel("预测"); plt.ylabel("真实") plt.savefig("confusion_norm.png", dpi=150)逻辑说明:按行归一化后,对角线是召回率,非对角线是误判比例。参数上,annot=True显示数值,fmt=".2f"保留两位。看哪一列特别亮,说明该类被过度预测,可能是样本不均衡。
另一个技巧是拿验证集里置信度 0.3 到 0.6 的预测框单独可视化,这些是模型的「犹豫区」,往往藏着标注错误或难样本。我一般会抽 50 张出来人工过一遍,修正后重新训练,mAP 通常能再涨一两个点。
从那以后我每次拿到新数据集,都强制先跑一遍坐标校验和随机可视化,再动训练脚本。这两步花不了十分钟,但能省掉后面几小时的无效训练。希望帮到你。
本文还有配套的精品资源,点击获取