简介:这份吊车图像标注数据集面向计算机视觉方向的学习者与算法工程师,尤其适合正在开展目标检测项目、需要特定垂类样本进行模型训练与验证的人群。数据集聚焦建筑工地、港口等场景中的吊车目标,可用于训练模型识别并定位吊车位置,帮助解决通用数据集在工程机械类别上样本不足的问题。资源包共6693个文件,包含2231张jpg图像、2231个txt标注文件与2231个xml标注文件,分别对应YOLO与PASCAL VOC两种主流标注格式,压缩包约375.1MB,图像与标注一一对应,便于直接接入训练流程。目前已有1626人学习下载。标注经过严格把控,边界框与类别信息完整,样本量足以支撑模型学习吊车特征并降低过拟合风险,适合用于算法验证、模型微调与工程化落地前的数据准备。
1. 吊车图像标注数据集:2231 张图能撑起一个检测模型吗
工地上要做一个吊车入侵预警,或者给塔吊做安全监控,第一反应往往是“先搞数据”。但真去搜公开数据集,你会发现 COCO、VOC 里根本没有独立的“吊车”类,ImageNet 的标签又只到“crane”这种粗粒度,跟你要框的“汽车吊”“履带吊”“塔吊”完全对不上。这份吊车图像标注数据集_2231,就是冲着这个缺口来的:2231 张实拍图,全部做了目标检测框标注,类别聚焦在吊车本体。它解决的不是“通用检测”问题,而是让你在工地、厂区、港口这类垂直场景里,能直接拿到一批带框的吊车样本,跳过从零标数据这个最耗人的环节。适合谁?做智慧工地、工程机械识别、边缘端安全帽/吊车联动检测的算法同学,以及需要快速验证 YOLO 系列模型能不能在吊车这个类上跑通的人。2231 张不算大,但作为冷启动的第一批训练数据,够用。
2. 先看清标注格式:2231 张图到底怎么组织
2.1 目标检测标注的三种常见格式与选型
拿到一个标注数据集,第一件事不是急着训练,而是确认它是什么格式。目标检测里最常见的三种:Pascal VOC 的 XML、COCO 的 JSON、YOLO 的 TXT。它们描述的是同一件事——框的位置和类别,但组织方式差别很大,直接决定你后面要不要写转换脚本。
VOC 格式每张图对应一个 XML,框用xmin/ymin/xmax/ymax绝对像素坐标,可读性好,但文件数量翻倍,2231 张图就是 2231 个 XML,批量处理时 IO 压力不小。COCO 格式把所有标注塞进一个 JSON,images、annotations、categories三个数组互相用 id 关联,适合大规模数据集和 pycocotools 那套评估流程,但单看某个框要来回跳。YOLO 格式每张图一个 TXT,每行class x_center y_center width height,坐标全部归一化到 0~1,最紧凑,训练时读取最快,也是目前 YOLOv5/v8/v11 默认吃的格式。
这份数据集如果面向的是吊车检测这种单类或少类任务,YOLO TXT 是最省事的。判断方法很简单:解压后看有没有labels文件夹,里面是不是一堆和图片同名的.txt。如果是,恭喜,直接能喂给 YOLO;如果是 XML 或 JSON,就得先转。
2.2 目录结构与类别映射的核对
一个规范的 YOLO 数据集目录通常长这样:
dataset/ ├── images/ │ ├── train/ │ └── val/ ├── labels/ │ ├── train/ │ └── val/ └── data.yamlimages和labels下的文件名必须一一对应,只是扩展名不同。data.yaml里写清楚train、val路径和names类别名。这里有个血泪经验:很多人拿到数据集直接开训,结果模型学出来全是背景,回头查才发现names里的类别顺序和 TXT 里的 class id 对不上。比如 TXT 里吊车标的是0,但 yaml 里names: ['person', 'crane'],那模型就把吊车当人学了。
核对方法:随便抽一张图,用下面这段脚本把框画出来,肉眼确认类别和位置对不对。
import cv2 import os # 读一张图和对应的 YOLO 标签,把框画出来验证 img_path = "dataset/images/train/0001.jpg" label_path = "dataset/labels/train/0001.txt" img = cv2.imread(img_path) h, w = img.shape[:2] with open(label_path) as f: for line in f: cls, xc, yc, bw, bh = map(float, line.split()) # YOLO 是归一化中心点坐标,还原成像素左上右下 x1 = int((xc - bw / 2) * w) y1 = int((yc - bh / 2) * h) x2 = int((xc + bw / 2) * w) y2 = int((yc + bh / 2) * h) cv2.rectangle(img, (x1, y1), (x2, y2), (0, 255, 0), 2) cv2.putText(img, str(int(cls)), (x1, y1 - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 255, 0), 2) cv2.imwrite("check.jpg", img)这段代码的逻辑:逐行读 TXT,每行五个值分别是类别 id、中心点 x、中心点 y、框宽、框高,全部是相对整图宽高的比例。还原时先乘回像素尺寸,再由中心点加减半宽半高得到左上右下角。跑完打开check.jpg,如果框歪了或者类别数字明显不对,说明格式或映射有问题,先别往下走。
提示:如果 TXT 里出现大于 1 的坐标值,说明它不是标准 YOLO 归一化格式,可能是绝对坐标,需要先除以图像宽高再归一化。
2.3 数据划分:别让训练集和验证集串味
2231 张图,常见的划分是 8:2 或 7:3。但这里有个容易翻车的点:如果同一台吊车、同一个工地、甚至同一段连续视频抽帧出来的图,被随机分到了训练集和验证集,那验证指标会虚高。模型在验证集上“见过”几乎一样的图,mAP 看着漂亮,一上真实新场景就崩。
正确做法是按场景或按源视频分组划分,同一组的图要么全在训练集,要么全在验证集。如果数据集本身没提供划分,我一般会先按文件名前缀或拍摄批次聚类,再在组级别上切分。下面这个脚本演示按文件名前缀分组划分:
import os import random from collections import defaultdict img_dir = "dataset/images/all" groups = defaultdict(list) # 假设文件名形如 siteA_001.jpg,用下划线前的前缀当分组依据 for name in os.listdir(img_dir): if name.endswith(".jpg"): group = name.split("_")[0] groups[group].append(name) group_keys = list(groups.keys()) random.seed(42) random.shuffle(group_keys) split = int(len(group_keys) * 0.8) train_groups = set(group_keys[:split]) train_files, val_files = [], [] for g, files in groups.items(): (train_files if g in train_groups else val_files).extend(files) print(f"train: {len(train_files)}, val: {len(val_files)}")逻辑说明:先把所有图按前缀归组,打乱的是“组”而不是“单张图”,这样同一组的图不会被拆散。random.seed(42)保证划分可复现,换台机器跑结果一致。参数上,0.8是训练集组数占比,如果数据场景特别单一,可以调到0.7留更多验证。跑完把文件名列表写进train.txt和val.txt,YOLO 训练时直接引用。
3. 用 YOLOv8 把 2231 张图跑起来:配置与训练
3.1 环境与依赖:版本对齐比装得多更重要
训练吊车检测,我一般用 YOLOv8,原因是它对小数据集友好,命令行和 Python API 都顺手,导出 ONNX 也方便。环境上最容易踩的坑不是缺包,而是版本冲突。ultralytics更新很快,不同版本对torch的要求不一样,装之前先定版本。
# 建一个干净环境,避免和已有 torch 打架 conda create -n crane python=3.10 -y conda activate crane # 先装 torch,按自己 CUDA 版本选,这里以 cu118 为例 pip install torch==2.1.0 torchvision==0.16.0 --index-url https://download.pytorch.org/whl/cu118 # 再装 ultralytics,锁一个稳定版本 pip install ultralytics==8.1.0逻辑说明:先装 torch 再装 ultralytics,是因为 ultralytics 安装时会检查 torch,如果顺序反了它可能拉一个不匹配的 CPU 版 torch 下来。python=3.10是当前兼容性最好的版本,3.12 有些依赖还没跟上。CUDA 版本用nvidia-smi右上角那个数字对齐,别硬套。装完跑yolo checks确认环境和 GPU 识别正常。
3.2 data.yaml 与训练参数:小数据集的防过拟合配置
data.yaml是训练入口,写错路径是最常见的“训练跑起来但学不到东西”的原因。
# data.yaml path: /abs/path/to/dataset # 数据集根目录,建议写绝对路径 train: images/train val: images/val nc: 1 # 类别数,吊车单类就是 1 names: ['crane'] # 类别名,顺序必须和 TXT 里的 class id 一致path用绝对路径,相对路径在不同工作目录下跑容易找不到。nc和names长度必须一致,单类就写 1 和['crane']。
训练命令:
yolo detect train \ data=data.yaml \ model=yolov8n.pt \ epochs=150 \ imgsz=640 \ batch=16 \ lr0=0.01 \ patience=30 \ augment=True \ project=runs/crane \ name=exp1参数逐个说:model=yolov8n.pt用 nano 版,2231 张图这个量级,n 或 s 就够,上大模型反而过拟合。epochs=150配合patience=30,意思是 30 轮验证指标不涨就早停,省时间。imgsz=640是默认输入尺寸,如果吊车在图中占比很小,可以提到 960,但显存和速度要权衡。batch=16按显存调,8G 显存跑 640 大概能到 16。lr0=0.01是初始学习率,小数据集别设太大,否则前期震荡。augment=True开默认增强,对 2231 张这种规模很关键,相当于变相扩样本。
3.3 训练过程看什么:loss 曲线与 mAP 的读法
训练启动后,runs/crane/exp1/下会生成results.csv和一堆曲线图。新手容易只盯mAP50,但更该先看 loss。box_loss和cls_loss如果一直不降,说明学习率或数据有问题;如果训练 loss 降但验证 loss 抬头,就是过拟合,该加增强或减模型。
mAP50是 IoU 阈值 0.5 下的平均精度,吊车这种形状规整的目标,正常能到 0.85 以上。mAP50-95更严格,一般会比mAP50低 0.15~0.25。如果mAP50高但mAP50-95很低,说明框的位置不够准,可能是标注框偏大或偏小。这时候别急着调模型,先回去抽查几张验证图的预测框和真值框差多少。
import pandas as pd # 读训练日志,快速看指标趋势 df = pd.read_csv("runs/crane/exp1/results.csv") df.columns = df.columns.str.strip() # 列名可能带空格 print(df[["epoch", "train/box_loss", "metrics/mAP50", "metrics/mAP50-95"]].tail(10))这段就是读 CSV 看最后 10 轮的指标,确认是否收敛。如果mAP50在最后 20 轮基本平了,说明训练到位;如果还在涨,可以适当加 epoch。
4. 避坑与排查:2231 张图训练时最容易翻车的五件事
4.1 现象:训练 loss 正常但预测全是背景
原因:data.yaml里names顺序和 TXT 的 class id 错位,或者nc写成了比实际类别数大。模型学到的类别索引和你想的不是一回事。
解决:抽一张训练图,用 2.2 的脚本画框确认 class id,再对照names列表。单类任务nc必须是 1,写成 2 会多出一个永远学不到的类,拉低整体指标。
4.2 现象:验证 mAP 很高,换一批新工地图片全漏检
原因:训练集和验证集按单张图随机划分,同一场景的图两边都有,验证指标虚高。这是最隐蔽的坑,因为曲线好看,你不会怀疑数据。
解决:按场景/批次分组划分,参考 2.3 的脚本。划分完再检查一遍训练集和验证集的文件名前缀有没有重叠。
4.3 现象:小目标吊车(远处)几乎检不到
原因:2231 张图里如果远景吊车多,缩到 640 后目标可能只剩十几个像素,特征太弱。默认增强里的 mosaic 还会进一步缩小目标。
解决:把imgsz提到 960 或 1280,同时关掉 mosaic 的最后 10 轮(close_mosaic=10)。如果显存不够,用batch=8换尺寸。另外可以在data.yaml同目录加一个hyp.yaml调scale增强幅度,别让缩放太狠。
4.4 现象:训练报错 “No labels found”
原因:labels目录路径不对,或者 TXT 文件名和图片名不一致(比如图片是.jpg,标签是.JPG.txt)。YOLO 是按同名替换扩展名找标签的。
解决:进labels/train数一下 TXT 数量是否等于images/train的图片数。不一致就写脚本批量重命名,把多余后缀去掉。
4.5 现象:GPU 显存够但训练速度极慢
原因:workers默认是 8,但在某些容器环境里多进程 dataloader 会卡住;或者图片尺寸参差不齐,每批都要 resize 到最大边。
解决:先试workers=4甚至workers=0排除多进程问题。如果数据集图片尺寸差异大,训练前统一 resize 到接近imgsz的尺寸,减少在线缩放开销。用yolo detect train ... cache=True把图缓存到内存,2231 张图内存扛得住,能明显提速。
5. 从能跑到好用:提升吊车检测精度的几个实操技巧
训练跑通只是起点,真正上线前还得把精度往上抠。第一个技巧是难例挖掘。2231 张图里,模型错得最多的往往是遮挡吊车、只露一截吊臂、逆光这几类。把验证集里漏检和误检的图挑出来,单独看它们的共同点,然后针对性补数据或调增强。我一般会写个脚本把预测置信度在 0.1~0.4 之间的框导出来,这批就是“模型拿不准”的难例。
from ultralytics import YOLO import cv2 model = YOLO("runs/crane/exp1/weights/best.pt") results = model.predict("dataset/images/val", conf=0.1, save=True) # 统计低置信度检测,定位难例 for r in results: for box in r.boxes: conf = float(box.conf) if 0.1 < conf < 0.4: print(r.path, conf)逻辑:conf=0.1把阈值放低,让模型把犹豫的框也吐出来,落在 0.1~0.4 区间的就是边界样本。把这些图挑出来人工复核,如果确实是吊车但没标,就补标;如果是误检,就加进负样本。参数上,conf别设到 0.05 以下,噪声太多反而干扰判断。
第二个技巧是冻结 backbone 做微调。如果你后续又标了一批新场景的吊车图,不想从头训,可以加载best.pt,冻结前几层,只训检测头。命令是yolo detect train model=best.pt freeze=10 ...,freeze=10表示冻结前 10 层。这样小批量新数据也能快速适配,不容易把原有能力冲掉。
第三个技巧是导出 ONNX 做部署验证。训练指标好不代表部署好,导出后拿几张图跑一遍,对比 PyTorch 和 ONNX 的输出框是否一致。
yolo export model=runs/crane/exp1/weights/best.pt format=onnx imgsz=640 opset=12opset=12兼容性最好,imgsz必须和训练时一致,否则框会偏。导出后用 onnxruntime 跑一张图,和原模型预测结果比 IoU,差太多就检查预处理有没有对齐(归一化、通道顺序)。
最后一个习惯:每次改完数据或参数,别只看最终 mAP,把results.csv里mAP50和mAP50-95一起拉出来对比。我吃过亏,有一次只盯mAP50涨了 2 个点就上线,结果mAP50-95掉了,实际框的位置变糙了,现场报警频繁误触发。从那以后我每次评估都强制把两个指标并排看,再抽 20 张验证图肉眼过一遍框。希望帮到你。
本文还有配套的精品资源,点击获取