尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
YOLOv8奶牛个体识别实战:从数据集制作到部署全指南
简介一套基于YOLOv8的奶牛个体身份识别应用面向计算机视觉与深度学习方向的毕业设计、课程设计或项目初期演示功能完整且操作门槛较低尤其适合需要快速产出可演示成果的在校学生。压缩包共8个文件、约15.91MB体积适中包含3个Python脚本可视化界面、视频检测、训练模式入口、3个模型权重文件含预训练权重与最优模型以及2个txt说明文档轻量易部署。项目代码已通过测试配套完整数据集可生成混淆矩阵、F1分数曲线、精确率-召回率曲线、验证集预测结果和标签分布图等评估结果便于答辩或汇报时直观展示模型性能。可视化界面支持加载模型进行视频识别并能实时查看推理情况适合想快速上手目标检测应用的学习者也能在原有基础上修改数据与训练脚本扩展至其他个体识别任务。目前已有60人学习/下载可复用为目标检测项目的基础模板或二次开发起点。1. 为什么奶牛个体识别要用YOLOv8而不是刷脸牧场管理里耳标脱落、RFID 丢失是常事视觉个体识别因此成了一个刚需方向。但奶牛的面部特征个体差异远不如人类明显直接套用人脸识别思路效果很差真正稳定的是背部花纹、腹部斑块和整体体型而这些特征只有在检测框稳定的前提下才能被持续提取。如果先做目标检测、再做分类流程被拆成两段后检测框的偏移会直接污染分类输入误差被叠加放大。把“这是哪一头牛”直接当成目标检测的类别标签用一个 YOLOv8 模型同时输出位置和身份这个思路在几十头牛规模的封闭牛舍里完全够用。资源里把 yolov8n.pt、best.pt、可视化页面、完整数据集和部署教程都打包好了解压后按照 README 跑通训练和推理演示效果比单纯跑开源 demo 更有说服力尤其适合正在做毕设或课程设计的人。2. YOLOv8选型与奶牛数据集的YOLO格式准备2.1 为什么是YOLOv8n精度与速度的平衡YOLOv8 是目前自动化程度较高的检测框架训练和评估 pipeline 集成在 ultralytics 包里不需要自己写 anchor 匹配或 NMS。它提供的 n/s/m/l/x 几个型号里yolov8n 是体积最小的一个参数量大约 3.2MGTX 1660 Ti 这类入门级显卡上跑视频推理能到 30 FPS 左右对奶牛个体识别这种大目标场景已经够用。奶牛的个体识别不是精细分类任务类别数就是牛舍里的牛头数比如 10 头牛就是 10 个类别。每个类别有稳定的纹理特征后n 模型的容量足以拟合强行用 l 模型反而容易在训练集中过拟合推理速度还掉一半。项目里同时带了 yolo11n.pt这个属于新一代轻量模型backbone 结构做了优化在相同测试集下通常比 yolov8n 高 1 到 2 个点 mAP但解码速度会稍微慢一点。保留两个权重的意义就是方便做消融对比这也是答辩时评委一定会问的点。2.2 数据集的目录结构与标签编码这份资源里的数据集已经按 YOLO 的目录规范整理好了解压后需要先确认images和labels是否一一对应dataset/ ├── images/ │ ├── train/ │ ├── val/ │ └── test/ ├── labels/ │ ├── train/ │ ├── val/ │ └── test/如果images/train里有一张cow_023.jpg那么labels/train下必须存在同名cow_023.txt文件后缀不同没关系主名必须完全一致。标签文件的每一行对应一个目标class_id x_center y_center width height坐标使用 0 到 1 之间的归一化浮点数而不是像素值。class_id 必须从 0 开始连续编号假设有 10 头牛类别就是 0 到 9。很多同学自己标数据时习惯从 1 开始ultralytics 会直接把最大类别数加 1 当成总的类别数量训练完发现 mAP 异常低原因就是类别号断档。我在拿到这份数据后习惯先跑一遍标签校验脚本import os def check_labels(label_dir): for f in os.listdir(label_dir): if not f.endswith(.txt): continue with open(os.path.join(label_dir, f)) as fp: lines fp.readlines() for line in lines: parts line.strip().split() if len(parts) ! 5: print(f{f} 格式错误: {line.strip()}) continue x, y, w, h map(float, parts[1:]) if not (0 x 1 and 0 y 1 and 0 w 1 and 0 h 1): print(f{f} 坐标越界: {line.strip()}) print(检查完成) check_labels(dataset/labels/train)上面脚本用目录遍历加字符串拆分完成基础校验。x_center和y_center是边界框中心的归一化坐标width和height是归一化宽高。如果某个坐标出现负值或大于 1训练时 loss 会跳 NaN。校验通过后最好再统计一下每个 class_id 的框数量如果某头牛只出现了 20 次模型很大概率学不到它的特征需要补充样本而不是继续调参。2.3 按时间戳划分训练集和验证集这份数据集来源于视频抽帧存在严重的时间相关性。如果随机打乱划分训练集里某一秒的相近帧可能同时出现在验证集评估指标虚高换到真实视频后效果立刻崩。常见做法是按时间戳切分把前 80% 的视频帧归入训练集后 20% 归入验证集。下面的脚本演示了按序号每隔 5 帧取一帧进验证集的逻辑import shutil from pathlib import Path src_img Path(raw_images) train_img Path(dataset/images/train) val_img Path(dataset/images/val) train_lbl Path(dataset/labels/train) val_lbl Path(dataset/labels/val) for i, img_path in enumerate(src_img.glob(*.jpg)): lbl_path img_path.with_suffix(.txt) if i % 5 0: shutil.move(str(img_path), str(val_img / img_path.name)) shutil.move(str(lbl_path), str(val_lbl / lbl_path.name)) else: shutil.move(str(img_path), str(train_img / img_path.name)) shutil.move(str(lbl_path), str(train_lbl / lbl_path.name))img_path.with_suffix(.txt)把.jpg替换成.txt这样图片和标签能同步移动不会出现图片在 train 但是标签在 raw 目录的情况。i % 5 0约等于 20% 的验证集比例。需要补充的是如果数据是从多个机位采集的按文件名取余很危险因为同一个机位的帧会平均落到 train 和 val 里导致验证集失去“跨视角”的评估意义。更稳妥的方法是在采集时按时间段命名先按时间分组再切分。3. 训练管线与参数调优从yolov8n到best.pt3.1 train_mode.py 的训练流程拆解train_mode.py 不是简单的一行命令它把环境检查、预训练权重加载、数据集 yaml 配置、训练启动和结果输出整合到了一起。核心训练代码等价于下面的片段from ultralytics import YOLO model YOLO(yolov8n.pt) results model.train( datacow_dataset.yaml, epochs100, batch16, imgsz640, lr00.01, lrf0.01, optimizerSGD, patience10, device0, projectruns/train, namecow_yolov8n, pretrainedTrue, )data参数指向 YAML 文件里面写清楚了 train/val 路径和类别名称。imgsz640表示训练时将输入图缩放至 640x640奶牛大目标较多512 会掉精度768 会显著吃显存。batch16在 8GB 显存上接近上限如果你的显卡只有 6GB需要降到 8同时把 imgsz 降到 640 以下。lr00.01配合 SGD 是 ultralytics 默认配置换成 AdamW 后可以把学习率调成 0.001通常收敛更快但最终精度的上限低一点。patience10是早停参数连续 10 个 epoch 验证损失不下降就终止训练防止浪费时间。训练开始后ultralytics 会在runs/train/cow_yolov8n/目录下持续输出results.png这张图汇总了train/loss、val/loss、mAP50 和 mAP50-95 的变化曲线。这里要区分train/loss下降但val/loss早停不降说明模型在过拟合两个 loss 都下降且 mAP 还在上升说明训练还没收敛。这份奶牛数据集规模不大一般 60 epoch 左右就能看到 mAP50 稳定在 0.9 以上。除了 results.png目录下还会生成confusion_matrix.png、F1_curve.png、PR_curve.png和val_batch*.jpg这些就是摘要描述里的核心指标曲线图答辩 PPT 直接引用即可。3.2 关键超参数与收敛判断训练时不需要追求一次到位的超参组合我通常先跑一组基准配置再根据显存和损失曲线调整。下面的表格是我在这份数据集上常用的参数和经验调整规则参数初始值调整策略epochs100val/box_loss 连续 20 轮不降则提前结束batch16显存占用超过 80% 时降到 8imgsz640目标过小或 mAP 不达标时升到 768optimizerSGD换 AdamW 时 lr0 改为 0.001lr00.01训练震荡时降到 0.005patience10数据量大时可增加到 15判断模型好坏不能只看训练集上的 loss核心指标曲线里最重要的是PR_curve.png它是不同置信度下精确率和召回率的权衡曲线曲线越接近右上角说明模型越稳健。奶牛的个体识别通常更关注“不要认错”也就是精确率优先所以把置信度阈值设高一点比如 0.45让每个框的类别都具备高可信度。如果最终 mAP50 只有 0.85建议检查标签分布图看每个类别的框数量差异是否超过 5 倍。类别不平衡时可以给样本量少的类别复制增强图像比直接修改 YOLOv8 的 loss 参数更容易控制。3.3 用 yolo11n.pt 做对比实验的价值项目里保留 yolo11n.pt 不是为了凑文件体积而是给毕设增加一个有对比价值的实验组。把YOLO(yolov8n.pt)改成YOLO(yolo11n.pt)其他参数完全不动再训练一次然后对比两个 run 的最好结果。我一般用 pandas 直接读 CSV 做比较import pandas as pd a pd.read_csv(runs/train/cow_yolov8n/results.csv) b pd.read_csv(runs/train/cow_yolo11n/results.csv) col metrics/mAP50(B) print(yolov8n mAP50:, a[col].max()) print(yolo11n mAP50:, b[col].max())这条命令用pandas.read_csv读取训练日志并取出 mAP50 这一列的最大值。注意不同版本的 ultralytics 输出列名可能有差异第一次读入后建议先print(a.columns)确认列名。除了精度对比还可以在相同测试集上比较推理速度yolo detect predict modelruns/train/cow_yolov8n/weights/best.pt sourcedataset/images/test device0通过两次 predict 的耗时和预测结果对比能得出“yolov8n 速度更快、yolo11n 精度略高”的结论。这种对照实验是答辩的高频加分项因为很多同学只交一个 best.pt 和几张曲线图很少能解释清楚为什么选这个模型而你手里有两组真实数据。4. 可视化界面与视频检测从 Detection_video.py 到 Visual_interface.py4.1 用 best.pt 做视频检测的 Pipeline模型训练完成后最直接的应用就是视频检测。Detection_video.py 的思路并不复杂用 OpenCV 逐帧读取视频把帧送给 YOLO 模型推理再把检测结果绘制到原图上实时显示。核心代码可以简化为下面的版本import cv2 from ultralytics import YOLO model YOLO(runs/train/cow_yolov8n/weights/best.pt) cap cv2.VideoCapture(test_cow.mp4) conf 0.35 while True: ret, frame cap.read() if not ret: break results model(frame, confconf, verboseFalse) annotated results[0].plot() cv2.imshow(cow recognition, annotated) if cv2.waitKey(1) 0xFF ord(q): break cap.release() cv2.destroyAllWindows()conf0.35是置信度阈值低于这个值的预测框会被过滤。奶牛在背对镜头或遮挡时置信度会下降阈值太低会出现误检太高会漏检。选值技巧是观察 F1 曲线里置信度轴取曲线最高点附近的置信度作为阈值的初始值然后手工微调。results[0].plot()返回的是画好边界框和标签的 BGR 图像OpenCV 直接显示不会出现颜色异常。如果需要把结果保存为 mp4要额外创建VideoWriterout cv2.VideoWriter( output.mp4, cv2.VideoWriter_fourcc(*mp4v), fps30, size(frame.shape[1], frame.shape[0]), )fps必须和源视频一致否则保存出来的视频要么倍速要么慢放。我踩过的一个坑是处理完视频后忘记调用out.release()导致最后的视频文件无法播放所以建议在cap.release()前显式释放 writer。4.2 视频检测的帧率优化技巧如果拿 yolov8n 在 CPU 上跑视频推理速度通常只有 5 FPS 左右肉眼看起来一卡一卡。有 NVIDIA 显卡时ultralytics 会自动选择 GPU但还需要做两步优化半精度推理和输入降分辨率。半精度推理代码如下model YOLO(best.pt) model.model.half()half()把模型权重转为 FP16显存占用减半推理速度提升到接近两倍。降分辨率更直接1080p 的视频可以先cv2.resize(frame, (720, 540))再送入 model奶牛的边界框占画面比例较大720p 足够完成识别而推理耗时几乎与像素数量成线性关系。这两个技巧叠加后GTX 1660 Ti 上运行 yolov8n 能稳定在 25 FPS 左右。另外ultralytics 提供streamTrue模式可以直接传入视频文件路径内部会保持批处理比逐帧调用更快for result in model.predict(sourcetest_cow.mp4, streamTrue, conf0.35, verboseFalse): annotated result.plot()4.3 可视化界面的功能设计Visual_interface.py 实现了 To C 的交互体验界面大体分为模型选择区、图像显示区、识别结果列表区和导出区。第一次点“打开视频”后发现窗口卡死原因几乎都是把推理放到了主线程里。常见做法是单独开一个QThread来跑模型主线程只负责刷新画面。核心代码结构如下from PySide6.QtCore import QThread, Signal class InferenceThread(QThread): change_pixmap Signal(QImage) def run(self): while self.running: ret, frame cap.read() if not ret: break results model(frame, confself.conf, verboseFalse) annotated results[0].plot() rgb cv2.cvtColor(annotated, cv2.COLOR_BGR2RGB) h, w, ch rgb.shape self.change_pixmap.emit( QImage(rgb.data, w, h, ch * w, QImage.Format_RGB888) )这里必须把 OpenCV 的 BGR 转成 RGB 再构造 QImage否则界面里牛的颜色会偏蓝。QImage构造函数的第三个参数ch * w表示每行字节数如果传入 0 或错误的步长图像会错位或出现锯齿。在QThread里不要直接操作QLabel控件通过信号change_pixmap把图片发回主线程由主线程的槽函数更新界面。导出识别记录时用csv.DictWriter固定列顺序import csv with open(records.csv, w, newline) as f: writer csv.DictWriter(f, fieldnames[frame, cow_id, confidence, x, y]) writer.writeheader() writer.writerows(records)fieldnames固定了 CSV 的列名顺序后续做数据分析时可以直接pandas.read_csv读取而不会出现列错位。界面里置信度滑块的范围建议设在 0.2 到 0.6 之间因为这个区间是 F1 曲线变化最敏感的区域给演示提供了很大的调整空间。5. 答辩前如何快速重生成指标曲线与现场部署排错训练完的runs/train/cow_yolov8n里已经包含混淆矩阵、F1 曲线、PR 曲线和标签分布图但现场演示前如果换电脑或者误删了这些图片不需要重新训练直接对验证集重新做一次验证即可yolo detect val modelruns/train/cow_yolov8n/weights/best.pt datacow_dataset.yaml这个命令会在runs/detect/val目录下重新生成confusion_matrix.png、F1_curve.png、PR_curve.png和验证集预测图。关键前提是cow_dataset.yaml必须和训练时使用的一致否则类别映射会错混淆矩阵的图像全部乱掉。如果提示 YAML 里的路径不存在需要把path字段改成当前机器上数据集的实际绝对路径这是跨机器部署最常见的错误。现场演示最容易翻车的场景不是模型精度不够而是环境配置问题。启动Visual_interface.py时如果报python: cant open file先检查当前工作目录是否在项目根目录如果报ModuleNotFoundError: No module named ultralytics需要执行下面的命令pip install ultralytics版本不需要追求最新建议安装 8.2.0 以上即可。如果你用的是 PySide6 版本的界面还需要单独安装pip install PySide6例如在离线环境里提前用pip download下载好依赖包再拷到目标机器离线安装。实际演示推荐用预录好的视频文件和提前生成好的指标图片不要依赖现场摄像头因为场地灯光和视角不可控很容易踩到置信度阈值不合适的坑。可以准备三段不同光照环境下的视频分别测试当前置信度阈值下的漏检率然后选出演示当天最稳定的阈值写入配置。如果要让项目运行效率再上一个台阶可以把 best.pt 转换为 ONNX 格式并用 ONNX Runtime 推理yolo export modelbest.pt formatonnx dynamicFalse device0转换完成后用onnxruntime-gpu加载模型并结合 TensorRT 的精度校准在视频高帧率要求下会比原始 PyTorch 推理更稳定这也是答辩时可以用来回答“能否部署到边缘设备”这个问题的最佳实践。本文还有配套的精品资源点击获取
RELATED

相关推荐

CIC-IDS-2018数据集预处理实战:从原始CSV到机器学习可用训练集

CIC-IDS-2018数据集预处理实战:从原始CSV到机器学习可用训练集

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📅 2026/9/15 2:39:03
VOC转YOLO格式与猪只检测:数据集清洗及YOLOv8训练实战

VOC转YOLO格式与猪只检测:数据集清洗及YOLOv8训练实战

简介:面向计算机视觉目标检测实践场景的猪只图像标注数据集,包含约634张真实场景猪图片,标注类别为pig,已同时提供VOC与YOLO两种格式的标注文件,可直接用于目标检测模型的训练、验证与算法入门实验,也可用于…

📅 2026/9/15 2:39:03
Matlab双层优化实现分布式光伏储能选址定容与配电网优化

Matlab双层优化实现分布式光伏储能选址定容与配电网优化

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📅 2026/9/15 2:39:03
MORE NEWS

更多资讯

📰

ESP32蓝牙Beacon测距实战:RSSI标定与环境建模

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

OpenPose姿态估计实战:PAF关键点匹配与跌倒预警系统实现

简介:基于OpenPose卷积神经网络的人体姿态识别及预警系统资源包,面向深度学习、计算机视觉方向的在校生与开发者,覆盖从模型训练、姿态关键点识别到异常预警的完整技术链路,可直接用于毕业设计、课程设计或项目前期验证。压缩包共…

📰

ResNet50特征提取+逻辑回归:轻量级猫狗分类实战

简介:本资源是一份面向深度学习初学者与计算机视觉实践者的Python源码案例,聚焦于使用预训练ResNet50模型提取猫狗图像特征,并结合逻辑回归完成二分类任务,解决经典图像识别入门问题。资源共43个文件,包含25个核心Pyth…

📰

基于1000张标注图像的钓鱼人员检测:YOLOv8训练全流程解析

简介:面向钓鱼场景的目标检测标注数据集,适用于计算机视觉入门及进阶开发者,可用于训练和评估能够识别岸边钓鱼人员的检测模型。压缩包仅41.55MB,却包含1000张jpg图像与1000个xml标注文件,合计2000个文件;图…

📰

AI Coding实战:从需求拆解到部署上线的全流程打法

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

新型非易失性存储器如何破解GX Works2存储瓶颈

1. 为什么“新型非易失性存储器”正在悄悄改写硬件底层逻辑你有没有遇到过这样的场景:一台工业PLC设备在连续运行72小时后,突然报出“GX Works2 存储器空间或桌面堆栈不足,因此无法启动”?不是软件崩溃,不是电源异常&a…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬