简介:这份牛羊检测数据集面向智慧牧场、智慧农场系统开发及目标检测课程作业、竞赛与科研项目,解决家畜识别与计数场景中高质量标注样本稀缺的问题。数据共3538张图片,标签同步提供VOC(xml)、YOLO(txt)与JSON三种格式,目标类别为“牛”和“羊”两类,可直接接入主流检测算法训练。压缩包约706.2MB,内含3538张jpg原图、3538个xml标注、3539个txt标签文件及1个zip包,文件组织清晰,便于按格式快速取用。数据集分布均匀、标注精准,背景与场景多样性充足,模型拟合效果较好,适合从算法验证到实际部署的多种需求。目前已有473人学习下载,所有数据均来自作者实际项目与实验demo,质量有保障,下载后可直接用于训练与评估。
1. 智慧牧场里的牛羊检测:3538 张三种标签格式的数据集到底怎么用
去年帮一个做智慧牧场系统的团队排查计数误差,现场摄像头装在牛棚和草场交界处,白天逆光、夜里补光,牛和羊还经常贴在一起走。他们模型在测试集上 mAP 看着还行,一到真实场景就漏检、误检,最后定位到问题不在网络结构,而在训练数据的标注格式和分布。这件事让我意识到,做牛羊识别检测这类家畜检测项目,数据集的质量和格式兼容性往往比换 backbone 更决定成败。这次拆的这份智慧牧场牛羊检测数据集,一共 3538 张图片,标签同时给了 VOC 的 xml、YOLO 的 txt 和 json 三种格式,目标就两类:牛和羊。它适合课程作业、设计、比赛,也适合直接塞进实际项目里跑 baseline。下面我按「这是什么、怎么用、坑在哪」的顺序,把这份资源从解压到训练再到验证的完整链路讲清楚,新手能照着复现,熟手能直接看参数和边界。
2. 三种标签格式的取舍:VOC、YOLO、JSON 各自适合什么场景
拿到压缩包先别急着解压训练,得先搞清楚为什么同一批图要配三种标签。这不是为了凑数,而是因为不同框架、不同阶段对标注格式的胃口完全不一样。选错格式轻则写一堆转换脚本,重则坐标对不上、类别错位,训练半天 loss 不降。这一章把三种格式的字段结构、适用框架和转换关系讲透,后面动手才不会翻车。
2.1 VOC xml 的结构与适用场景
VOC 格式是目标检测里最老牌也最通用的标注形式,每张图对应一个同名 xml 文件。它的核心信息在<object>节点里,包含类别名<name>和边界框<bndbox>的 xmin、ymin、xmax、ymax,坐标是绝对像素值,原点在左上角。这份数据集里牛和羊两类,xml 里的 name 字段就是「牛」「羊」对应的英文或中文标签,具体以解压后实际内容为准。
VOC 的好处是可读性强,用文本编辑器打开就能核对标注对不对,适合做数据清洗和人工抽检。它常被 PyTorch 的 torchvision、早期 SSD 实现、以及很多课程作业模板直接读取。缺点是文件数量翻倍,3538 张图就是 3538 个 xml,磁盘上小文件多,批量读取时 IO 压力比单文件格式大。
# 解析 VOC xml,提取类别和框坐标 import xml.etree.ElementTree as ET def parse_voc_xml(xml_path): tree = ET.parse(xml_path) root = tree.getroot() objects = [] for obj in root.findall('object'): name = obj.find('name').text # 类别名:牛 / 羊 bbox = obj.find('bndbox') xmin = int(bbox.find('xmin').text) # 左上角 x,绝对像素 ymin = int(bbox.find('ymin').text) # 左上角 y xmax = int(bbox.find('xmax').text) # 右下角 x ymax = int(bbox.find('ymax').text) # 右下角 y objects.append((name, xmin, ymin, xmax, ymax)) return objects这段代码的关键点是坐标直接取整,VOC 不做归一化。参数上要注意 xmax 和 ymax 是包含边界的右下角坐标,转 YOLO 时宽高要用 xmax-xmin 而不是 xmax-xmin+1,这个 +1 的玄学差异会让框整体偏移一个像素,小目标上尤其明显。
2.2 YOLO txt 的归一化逻辑与训练接入
YOLO 格式每张图对应一个 txt,每行一个目标,格式是class_id x_center y_center width height,后四个值全部是相对图像宽高的归一化浮点数,范围 0 到 1。class_id 从 0 开始,这份数据集两类,通常 0 是牛、1 是羊,但一定要以数据集自带的类别映射文件或实际 txt 内容为准,不能想当然。
YOLO 格式最大的优势是读取快、体积小,Ultralytics 的 YOLOv5/v8/v11 系列直接吃这种格式。训练时只需要一个 data.yaml 指向图片目录和标签目录,再配好 nc 和 names 就能开跑。归一化坐标的好处是图片 resize 后标签不用改,但代价是可读性差,肉眼看不出框在哪,必须可视化验证。
# VOC 绝对坐标转 YOLO 归一化坐标 def voc_to_yolo(xmin, ymin, xmax, ymax, img_w, img_h): x_center = (xmin + xmax) / 2.0 / img_w # 中心点 x 归一化 y_center = (ymin + ymax) / 2.0 / img_h # 中心点 y 归一化 w = (xmax - xmin) / img_w # 宽归一化 h = (ymax - ymin) / img_h # 高归一化 return x_center, y_center, w, h参数说明:img_w 和 img_h 必须用原图真实尺寸,不能用 resize 后的尺寸,否则归一化基准错了,框会整体缩放错位。常见做法是用 PIL 或 OpenCV 读图拿 shape,再逐张转换。转换完建议随机抽 20 张用可视化脚本画框,确认牛和羊的框都贴合目标,没有出现框跑到图外或全挤在左上角的情况。
2.3 JSON 标签的字段与多模态/服务化用途
JSON 格式在这份数据集里更像是给服务化和多模态场景准备的。它把一张图的所有标注组织成一个结构化对象,通常包含图片文件名、宽高、以及一个 objects 数组,数组里每个元素有类别、bbox 坐标,有的还会带置信度或分割点。JSON 的好处是能被后端服务、数据库、以及大模型分析链路直接消费,比如智慧牧场系统里要把检测结果和牛只档案关联,JSON 就是天然的中间格式。
{ "image": "000000054594.jpg", "width": 640, "height": 480, "objects": [ {"category": "牛", "bbox": [120, 80, 300, 260]}, {"category": "羊", "bbox": [340, 150, 420, 240]} ] }字段说明:bbox 这里用的是绝对坐标 [xmin, ymin, xmax, ymax],和 VOC 一致,方便互转。如果要做 COCO 风格训练,需要把 category 映射成数字 id,bbox 转成 [x, y, w, h]。JSON 的坑在于不同来源的字段命名不统一,有的用 label 有的用 category,有的 bbox 是归一化的,读之前一定先打印一条看结构,别直接写死解析逻辑。
2.4 三种格式的转换与一致性校验
三种格式并存时,最怕的是同一张图在 xml 和 txt 里框不一致。转换脚本写完必须做一致性校验:随机抽若干张,把 VOC 转成 YOLO 后和数据集自带的 YOLO txt 逐行比对,坐标误差超过一个像素就要查原因。常见原因是转换时用了 resize 后的尺寸,或者类别 id 映射反了。
| 格式 | 坐标类型 | 每图文件数 | 典型框架 | 主要用途 |
|---|---|---|---|---|
| VOC xml | 绝对像素 | 1 个 xml | torchvision、SSD | 数据清洗、抽检 |
| YOLO txt | 归一化 | 1 个 txt | YOLOv5/v8/v11 | 直接训练 |
| JSON | 绝对像素 | 可合并为 1 个 | 后端服务、多模态 | 服务化、档案关联 |
校验通过后再进入训练,能省掉大量「训练不收敛其实是标签错了」的排查时间。这一步看着笨,但它是后面所有环节的地基。
3. 从解压到跑通 YOLO 训练:目录组织与 data.yaml 配置
格式搞明白之后,真正动手训练。这一章按实际工程顺序走:先规划目录,再写 data.yaml,然后启动训练,最后看日志判断是否正常。很多人卡在路径和类别数上,其实都是配置问题,不是模型问题。
3.1 目录结构与文件命名规范
拿到压缩包解压后,先别改文件名。YOLO 要求图片和标签同名、分目录存放,常见结构是 images 和 labels 两个平行目录,下面再分 train 和 val。如果数据集原始结构不是这样,用脚本批量整理,不要手动拖拽,3538 张手动操作必出错。
# 整理成 YOLO 训练目录结构 dataset/ ├── images/ │ ├── train/ # 训练图片 │ └── val/ # 验证图片 ├── labels/ │ ├── train/ # 对应 txt 标签 │ └── val/ └── data.yaml # 数据集配置整理时注意图片和标签必须同名,比如000000054594.jpg对应000000054594.txt。如果数据集里 txt 文件名和图片对不上,训练时会被当成无标签图跳过,表现为 loss 异常或某些图完全不参与。建议整理完跑一遍配对检查,统计图片数和标签数是否一致。
3.2 data.yaml 的关键字段与类别映射
data.yaml 是 YOLO 训练的入口配置,写错一个字段训练就起不来。核心字段是 path、train、val、nc、names。nc 是类别数,这份数据集是 2;names 的顺序必须和 txt 里的 class_id 严格对应,0 对应第一个名字,1 对应第二个。
# data.yaml path: /home/user/dataset # 数据集根目录 train: images/train # 训练图片相对路径 val: images/val # 验证图片相对路径 nc: 2 # 类别数:牛、羊 names: 0: niu # class_id 0 对应牛 1: yang # class_id 1 对应羊参数说明:path 建议用绝对路径,避免训练时工作目录变化导致找不到文件。names 用英文或拼音更稳,中文在某些版本的可视化里会乱码。如果发现训练日志里类别名显示异常,先查 names 缩进和冒号后的空格,YAML 对格式很敏感,少一个空格就解析失败。
3.3 启动训练与关键超参设置
配置好之后启动训练。以 Ultralytics YOLOv8 为例,命令行和 Python 两种方式都行。第一次跑建议先用小 epoch 验证链路通不通,别一上来就 300 epoch,浪费时间。
# 命令行启动 YOLOv8 训练 yolo detect train \ data=dataset/data.yaml \ model=yolov8n.pt \ epochs=100 \ imgsz=640 \ batch=16 \ device=0参数说明:model 用预训练权重能加快收敛,yolov8n 是最小的,适合先跑通;imgsz 是输入尺寸,640 是通用值,牛羊目标如果普遍偏小可以提到 960,但显存占用会上升;batch 根据显存调,16 是 8G 显存左右的稳妥值;device=0 指定第一块 GPU,没有 GPU 就去掉用 CPU,但会很慢。训练过程中重点看 box_loss 和 mAP50 是否下降和上升,如果 loss 一直震荡不降,先回去查标签格式和类别映射。
3.4 训练日志解读与中断恢复
训练日志里几个关键指标:box_loss 衡量框回归,cls_loss 衡量分类,mAP50 是 IoU 0.5 下的平均精度。正常情况 box_loss 在前几个 epoch 快速下降,mAP50 逐步上升。如果 mAP50 长期在 0 附近,大概率是标签没读到或类别全错。中断恢复用 resume 参数,指向 last.pt 即可接着跑,不用从头来。
# 中断后恢复训练 yolo detect train resume model=runs/detect/train/weights/last.pt注意 resume 会沿用之前的配置,改超参要重新起训练。训练完的权重在 runs/detect/train/weights/ 下,best.pt 是验证集最好的,last.pt 是最后一轮,部署一般用 best.pt。
4. 避坑与排查:牛羊检测数据集落地时最容易翻车的五件事
这一章是我和几个做智慧牧场项目的朋友踩过的坑汇总,每条都按现象、原因、解决写。数据集本身质量不错,但工程落地时的坑往往不在数据,而在使用方式。
4.1 现象:训练 loss 不降,mAP 长期为 0
原因:最常见的是标签路径没配对,YOLO 找不到 txt,把所有图当负样本;其次是 class_id 超出 nc 范围,比如 txt 里写了 2 但 nc=2 只允许 0 和 1。解决:先跑配对检查脚本,确认每张图都有同名 txt;再统计所有 txt 里的 class_id 最大值,必须小于 nc。这两个检查五分钟能做完,能省几小时瞎调参。
4.2 现象:验证集指标很好,实际场景漏检严重
原因:数据集分布和真实场景不匹配。3538 张图里如果牛棚内景多、草场远景少,模型在远景小目标上就弱。另外牛羊贴在一起时 NMS 容易把其中一个框抑制掉。解决:先做场景分层统计,看训练集覆盖了哪些光照和距离;推理时适当调低 conf 阈值并调高 iou 阈值,减少误抑制。必要时补充真实场景图做微调。
4.3 现象:VOC 转 YOLO 后框整体偏移
原因:转换时用了 resize 后的尺寸做归一化,或者 xmax-xmin 时多加了 1。解决:归一化必须用原图宽高;宽高计算用 xmax-xmin,不要 +1。转完抽 20 张可视化,和原 xml 叠在一起看,偏移超过一两个像素就回查代码。
4.4 现象:JSON 解析报 key 错误
原因:不同来源的 JSON 字段命名不一致,有的用 category 有的用 label,有的 bbox 是对象不是数组。解决:解析前先打印一条完整 JSON,按实际字段写解析逻辑,别照搬网上的模板。加 try-except 跳过异常条目并记录,避免一条坏数据中断整个流程。
4.5 现象:训练显存溢出或速度极慢
原因:imgsz 或 batch 设太大,或者数据加载用了太多 worker 导致 CPU 瓶颈。解决:先降 batch 到 8 或 4 跑通,再逐步加;imgsz 从 640 起,小目标多再升。worker 数一般设成 CPU 核数的 1/4 到 1/2,太多反而抢资源。显存不够时还可以开混合精度,YOLOv8 默认就带 AMP,不用额外配。
5. 进阶验证与技巧:用可视化抽检和分层评估把数据集吃透
训练跑通只是开始,真正让这份数据集发挥价值的是验证环节。我一般不会只看一个 mAP 数字就下结论,而是做两件事:可视化抽检和分层评估。可视化抽检是随机抽一批验证图,把预测框和真实框画在一起,肉眼看有没有系统性偏移、漏检、类别混淆。这一步能发现指标掩盖的问题,比如羊被大量识别成牛,mAP 可能还行但业务上完全不可用。
# 可视化真实框与预测框对比 import cv2 def draw_boxes(img_path, gt_boxes, pred_boxes, save_path): img = cv2.imread(img_path) for (x1, y1, x2, y2) in gt_boxes: # 真实框:绿色 cv2.rectangle(img, (x1, y1), (x2, y2), (0, 255, 0), 2) for (x1, y1, x2, y2) in pred_boxes: # 预测框:红色 cv2.rectangle(img, (x1, y1), (x2, y2), (0, 0, 255), 2) cv2.imwrite(save_path, img)参数说明:gt_boxes 从 VOC 或 YOLO 反归一化得到,pred_boxes 从模型输出拿,两边都转成绝对像素再画。绿色真实框和红色预测框重叠度高说明定位准,红色框缺失说明漏检,红绿错位说明回归有问题。抽检数量建议不少于 50 张,覆盖不同光照和距离。
分层评估是把验证集按目标尺寸、目标数量、光照条件分组,分别算 mAP。比如小目标组、密集组、逆光组,哪一组指标明显低,就针对性地补数据或调 anchor。这份数据集背景丰富、多样性充足,正好适合做这种分层分析,能快速定位模型短板。
还有一个实用技巧是标签一致性交叉验证:把 VOC 转成 YOLO 后,和数据集自带的 YOLO txt 做逐行比对,统计不一致的比例。如果超过 1%,说明转换脚本或原始标注有问题,必须先修数据再训练。我吃过这个亏,曾经因为转换时类别 id 映射反了,牛和羊对调,模型训出来指标虚高,上线后计数全错,返工花了两天。从那以后我每次拿到多格式标签的数据集,都强制先跑一遍一致性校验和可视化抽检,确认无误才进训练。希望这份拆解帮到你,少走点弯路。
本文还有配套的精品资源,点击获取