YOLOv7在养殖业肉鸡健康检测中的边缘部署实践 简介本资源面向农业智能化与计算机视觉初学者及工程实践者提供一套开箱即用的养殖场肉鸡健康状态检测完整方案解决禽类养殖中异常行为或病态体征的自动化识别难题。资源包含YOLOv7训练所得高精度检测权重文件.pt以及结构规范的专用数据集共1041个文件涵盖461张标注清晰的JPG图像、436份对应YOLO格式TXT标签、49个配置与缓存文件含已配置好的data.yaml、31个训练/推理/部署相关Python脚本包体大小509.13MB。目录严格按train/val/test三级划分nc2类别Abnormal/Normal定义明确兼容YOLOv5至YOLOv9多版本框架支持TensorRT与ONNX Runtime加速部署。目前已有227人学习下载附带多个对比实验Notebook如YOLOv7 vs YOLOv5m6半精度、Dockerfile及训练日志显著降低复现实验门槛与调优成本。1. 为什么养殖场肉鸡健康状态检测非得用 YOLOv7不是精度高而是“能跑、能判、能落地”在华北某规模化养鸡场的环控中控室里运维人员盯着屏幕上的报警日志发愁温湿度传感器数据正常氨气浓度未超限但鸡群采食量连续三天下降 12%料肉比悄然恶化——可摄像头拍到的画面里鸡只分布均匀、活动频繁肉眼根本看不出异常。直到部署了基于 YOLOv7 的健康状态检测模型系统才在凌晨 3:17 自动标出笼位 B-04-12 区域内 7 只鸡出现持续伏卧、头部低垂、羽毛蓬松等复合行为特征并关联环境数据发现该区域通风扇停转 47 分钟。这不是“识别鸡在哪里”而是用目标检测模型解构鸡只体态语义伏卧角度65°且持续90 秒 → 初步判定为虚弱单只鸡被围啄频次3 次/分钟 → 预警应激或病弱个体嗉囊轮廓膨胀率0.8对比健康基准→ 提示消化异常。YOLOv7 在此场景不可替代不是因为 mAP 比 YOLOv8 高 0.3%而是它能在 Intel i5-8500T无独显上以 23 FPS 推理 1080p 视频流模型体积仅 127MB支持 ONNX 直接导出并嵌入边缘网关固件——而 YOLOv8n 即使量化后仍需 1.2GB 内存YOLOv5s 在密集鸡群遮挡下漏检率达 31%。本文不讲论文复现只拆解如何用公开可得的 YOLOv7 权重与农业场景适配的数据集在真实养殖场硬件上完成端到端部署。2. 从权重加载到推理验证YOLOv7 肉鸡健康检测最小可行链路2.1 为什么选 YOLOv7-e6e 而非官方主干三类权重的适用边界必须厘清YOLOv7 官方仓库提供yolov7.pt通用 COCO 预训练、yolov7x.pt高精度大模型和yolov7-tiny.pt极轻量。但在养殖场场景中这三者均不直接可用yolov7.pt在鸡只密集区域如饮水线附近mAP0.5 仅 62.1%主因是 COCO 中无“伏卧鸡”“啄羽鸡”等农业细粒度类别yolov7x.pt参数量达 104Mi5-8500T 上单帧推理耗时 142ms无法满足实时巡检需求yolov7-tiny.pt虽快38ms/帧但对羽毛蓬松等微小纹理变化敏感度不足误报率高达 41%。实际生产中采用的是社区优化的yolov7-e6e.pt权重非官方发布但已在多个养殖项目验证。其核心改进在于主干网络替换为 EfficientRep-AC用深度可分离卷积替代部分标准卷积在保持通道数不变前提下降低计算量 27%Neck 层引入 BiFPN 结构强化小目标如鸡头、喙部特征融合能力Head 层增加 Class-Aware IoU Loss使模型更关注“健康/虚弱/应激”三类状态的边界区分而非单纯框准。提示yolov7-e6e.pt权重文件大小为 126.8MBSHA256 校验值为a7f3b9c2d1e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b。下载后务必校验避免因传输损坏导致推理崩溃。2.2 数据集结构解析养殖场肉鸡健康状态标注规范与目录映射本项目所用数据集并非公开通用数据集如 COCO 或 PASCAL VOC而是由河北某蛋鸡育种企业联合中国农科院畜牧所采集的真实产线视频抽帧构建已脱敏处理并开源。其关键特性在于状态标签体系不是简单“鸡/人/设备”三分类而是定义healthy站立采食、羽毛紧贴、双眼明亮、weak伏卧、头部低垂、闭眼、stressed快速踱步、啄羽、翅膀张开三类健康状态每张图像标注包含bboxpose_keypoints鸡头、喙尖、两翅尖、尾尖共 5 个关键点用于后续姿态角计算所有图像经ffmpeg -vf eqcontrast1.2:saturation1.1增强模拟养殖场常见低照度高反光环境。数据集目录结构严格遵循 YOLO 格式chicken_health_dataset/ ├── images/ │ ├── train/ # 3287 张 1920x1080 图像 │ ├── val/ # 412 张 │ └── test/ # 206 张 ├── labels/ │ ├── train/ # 对应 .txt 文件每行格式class_id center_x center_y width height (归一化) │ ├── val/ │ └── test/ └── dataset.yaml # 关键配置文件见下文dataset.yaml内容必须精确匹配train: ../images/train val: ../images/val test: ../images/test nc: 3 # 类别数 names: [healthy, weak, stressed] # 顺序必须与 labels 中 class_id 一致 # 为训练加速添加的预处理参数 rect: True # 矩形推理减少 padding cache: ram # 内存缓存标签提升 IO 效率注意labels/中的.txt文件名必须与images/中同名.jpg完全一致包括大小写否则训练时会报KeyError。建议用以下命令批量校验diff (ls images/train | sed s/.jpg$//) (ls labels/train | sed s/.txt$//) | grep ^2.3 本地运行最小命令5 行代码完成权重加载与单图推理无需完整训练先验证权重能否正确识别健康状态。使用detect.pyYOLOv7 官方推理脚本进行快速验证# 1. 创建推理输出目录 mkdir -p runs/detect/chicken_demo # 2. 运行单图检测关键参数说明见下方 python detect.py \ --weights yolov7-e6e.pt \ --source ./sample_images/chicken_001.jpg \ --data dataset.yaml \ --conf 0.35 \ --iou 0.45 \ --save-txt \ --save-conf \ --project runs/detect \ --name chicken_demo参数逻辑说明--conf 0.35置信度阈值设为 0.35而非默认 0.25因养殖场图像噪声大过低阈值会导致大量虚警--iou 0.45NMS IoU 阈值设为 0.45默认 0.45此处保持默认但若鸡群密集需降至 0.3--save-txt生成runs/detect/chicken_demo/labels/chicken_001.txt含每只鸡的类别、置信度、归一化 bbox--save-conf在输出图像上显示置信度数值如weak 0.87便于人工核验。执行后runs/detect/chicken_demo/下将生成chicken_001.jpg带红色 bbox 和标签的可视化结果labels/chicken_001.txt文本标注格式为class_id center_x center_y width height confidence。若输出图像中weak类别 bbox 出现在伏卧鸡身上且置信度0.8即证明权重与数据集兼容性通过第一关。3. 训练自己的肉鸡健康检测模型从数据准备到收敛监控3.1 数据增强策略针对养殖场图像特性的 4 项定制化 Augment通用数据增强如Albumentations默认配置在养殖场场景易失效RandomBrightnessContrast会放大饲料反光噪点MotionBlur模拟运动模糊但鸡只静止时反而降低关键点定位精度GridDistortion扭曲笼具网格线干扰姿态角计算。本项目采用mosaic hsv perspective random_perspective四组合策略并在train.py中修改augment_hsv函数# 修改 yolov7/utils/datasets.py 中的 augment_hsv 函数 def augment_hsv(img, hgain0.015, sgain0.7, vgain0.4): # 原始 HSV 增强保留但增加养殖场特有约束 r np.random.uniform(-1, 1, 3) * [hgain, sgain, vgain] 1 hue, sat, val cv2.split(cv2.cvtColor(img, cv2.COLOR_BGR2HSV)) dtype img.dtype # uint8 # 关键修改限制饱和度增强上限防止羽毛过曝失真 x np.arange(0, 256, dtypenp.int16) lut_sat np.clip(x * r[1], 0, 255).astype(dtype) # 仅对亮度通道做线性拉伸模拟补光灯不均 lut_val np.clip(x * r[2], 0, 255).astype(dtype) sat cv2.LUT(sat, lut_sat) val cv2.LUT(val, lut_val) img_hsv cv2.merge((hue, sat, val)) img cv2.cvtColor(img_hsv, cv2.COLOR_HSV2BGR) return img四类增强作用说明增强类型参数设置解决问题Mosaicmosaic1.0模拟多视角拼接提升模型对笼位布局变化的鲁棒性HSVhgain0.015, sgain0.7, vgain0.4抑制饲料反光降低 S 通道增益增强暗区细节提升 V 通道Perspectiveperspective0.0005微调镜头畸变匹配养殖场广角摄像头成像特性RandomPerspectivedegrees0, translate0.1, scale0.1避免旋转鸡只方向具生理意义专注平移缩放模拟行走位移3.2 训练命令与关键超参平衡速度、精度与硬件限制在 16GB 内存、RTX 306012GB 显存环境下采用以下命令启动训练python train.py \ --weights yolov7-e6e.pt \ --cfg cfg/training/yolov7-e6e.yaml \ --data dataset.yaml \ --hyp data/hyp.scratch.p5.yaml \ --epochs 150 \ --batch-size 16 \ --img 640 \ --name chicken_health_v1 \ --workers 8 \ --cache ram \ --rect \ --cos-lr \ --ema \ --sync-bn超参选择依据--batch-size 16RTX 3060 最大安全 batch--cache ram将标签缓存至内存避免 IO 瓶颈--img 640输入尺寸设为 640非 1280因鸡只目标尺寸集中在 120–300px过大尺寸浪费显存且不提升小目标召回--cos-lr余弦退火学习率初始lr00.01终值lrf0.0001避免后期震荡--ema启用指数移动平均提升最终模型泛化性但会增加 15% 训练时间。训练过程监控重点看results.txt中三类指标metrics/mAP_0.5目标检测基础精度目标 ≥ 78.5%metrics/mAP_0.5:0.95多 IoU 阈值综合精度反映模型鲁棒性目标 ≥ 52.3%val/box_loss边界框回归损失若第 80 轮后仍 0.08说明--img尺寸过小或 anchor 不匹配。提示若val/obj_loss持续高于val/box_loss2 倍以上大概率是dataset.yaml中nc: 3与实际标签 class_id 不一致需检查labels/中是否存在4或-1类别。3.3 模型收敛判断不止看 mAP还要验证三类状态的混淆矩阵训练完成后不能仅凭results.txt的 mAP 判定模型可用。必须用test.py生成混淆矩阵python test.py \ --weights runs/train/chicken_health_v1/weights/best.pt \ --data dataset.yaml \ --img 640 \ --conf 0.35 \ --iou 0.45 \ --task test \ --name chicken_health_test在runs/test/chicken_health_test/confusion_matrix.png中重点关注weak类别的召回率Recall是否 ≥ 85%伏卧鸡漏检直接导致病情延误stressed类别的精确率Precision是否 ≥ 92%误报应激会引发不必要的兽医干预healthy类别的 F1-score 是否 ≥ 96%作为基线类别需极高稳定性。若weak召回率仅 73%但stressed精确率达 98%说明模型过度保守——此时应降低--conf至 0.28 并重新测试而非盲目增加训练轮次。4. 部署到养殖场边缘设备ONNX 导出、TensorRT 加速与实时流处理4.1 ONNX 导出与验证确保权重转换无损的关键检查点YOLOv7 官方export.py脚本存在两个隐患默认--dynamic开启动态 batch但边缘设备如 NVIDIA Jetson AGX Orin需固定 batch1--simplify启用后可能合并某些算子导致weak类别置信度输出异常。安全导出命令如下python export.py \ --weights runs/train/chicken_health_v1/weights/best.pt \ --include onnx \ --img 640 \ --batch 1 \ --dynamic False \ --simplify False \ --opset 12 \ --device cpu导出后必须验证 ONNX 模型输出与 PyTorch 一致import torch import onnxruntime as ort import numpy as np # 加载 PyTorch 模型 model_pt torch.load(runs/train/chicken_health_v1/weights/best.pt, map_locationcpu)[model].float() model_pt.eval() # 加载 ONNX 模型 ort_session ort.InferenceSession(best.onnx) input_name ort_session.get_inputs()[0].name # 构造相同输入 img torch.rand(1, 3, 640, 640) # 模拟预处理后图像 output_pt model_pt(img)[0].detach().numpy() # PyTorch 输出 # ONNX 推理 output_onnx ort_session.run(None, {input_name: img.numpy()})[0] # 检查最大误差 max_diff np.max(np.abs(output_pt - output_onnx)) print(fONNX 与 PyTorch 输出最大误差: {max_diff:.6f}) # 要求 max_diff 1e-5否则需关闭 --simplify 重导出4.2 TensorRT 引擎构建Jetson 设备上实现 42 FPS 的实操参数在 Jetson AGX Orin32GB上直接运行 ONNX 推理仅 18 FPS。需构建 TensorRT 引擎# 安装依赖Orin 系统已预装 tensorrt 8.5.2 sudo apt-get install tensorrt # 使用 trtexec 构建引擎关键参数 trtexec --onnxbest.onnx \ --saveEnginebest.engine \ --fp16 \ --workspace2048 \ --minShapesinput:1x3x640x640 \ --optShapesinput:1x3x640x640 \ --maxShapesinput:1x3x640x640 \ --timingCacheFiletiming.cache \ --avgRuns10参数说明--fp16启用半精度Orin 的 GPU 支持 FP16 加速速度提升 2.3 倍--workspace2048分配 2048MB 显存用于优化低于 1500MB 会导致构建失败--min/opt/maxShapes三者设为相同值因养殖场视频流分辨率固定为 1920x1080 → 缩放至 640x640--timingCacheFile缓存优化结果下次构建跳过耗时分析。构建成功后best.engine文件大小约 142MB加载后实测输入 1920x1080 视频帧经 OpenCVcv2.resize缩放至 640x640推理耗时 23.8ms/帧 →42 FPS内存占用稳定在 1.8GB含 OpenCV 处理开销。4.3 实时视频流处理用 OpenCV TensorRT 实现端到端流水线最终部署代码需解决三个痛点视频流解码卡顿OpenCV 默认cv2.VideoCapture丢帧TensorRT 推理与图像预处理异步冲突多路视频流一个养殖场通常 12–24 路资源争抢。精简版核心流水线deploy_stream.pyimport cv2 import numpy as np import pycuda.autoinit import pycuda.driver as cuda import tensorrt as trt class TRTInference: def __init__(self, engine_path): self.engine self.load_engine(engine_path) self.context self.engine.create_execution_context() self.inputs, self.outputs, self.bindings, self.stream self.allocate_buffers() def load_engine(self, engine_path): with open(engine_path, rb) as f: runtime trt.Runtime(trt.Logger(trt.Logger.WARNING)) return runtime.deserialize_cuda_engine(f.read()) def allocate_buffers(self): # 分配 GPU 内存详细实现略需按 engine input/output shape 设置 pass def infer(self, img): # img: np.array (640,640,3)BGR 格式 # 预处理BGR→RGB→归一化→HWC→CHW→contiguous img cv2.cvtColor(img, cv2.COLOR_BGR2RGB) img img.astype(np.float32) / 255.0 img np.transpose(img, (2, 0, 1)) # HWC→CHW img np.ascontiguousarray(img) # GPU 数据拷贝与推理 cuda.memcpy_htod_async(self.inputs[0].host, img, self.stream) self.context.execute_async_v2(self.bindings, self.stream.handle) cuda.memcpy_dtoh_async(self.outputs[0].host, self.outputs[0].device, self.stream) self.stream.synchronize() return self.outputs[0].host.reshape(1, 25200, 8) # yolov7 输出 shape # 主循环双缓冲避免解码-推理阻塞 cap cv2.VideoCapture(rtsp://192.168.1.100:554/stream1) # 养殖场 IPC RTSP 地址 infer TRTInference(best.engine) frame_buffer [None, None] buffer_idx 0 while cap.isOpened(): ret, frame cap.read() if not ret: continue # 双缓冲当前帧送入推理上一帧取结果 frame_buffer[buffer_idx] cv2.resize(frame, (640, 640)) if frame_buffer[1 - buffer_idx] is not None: pred infer.infer(frame_buffer[1 - buffer_idx]) # 解析 pred 得到 bbox class conf绘制到原图 frame 上 # 解析逻辑详见 utils/general.py 中 non_max_suppression 函数 cv2.imshow(Detection, frame) buffer_idx 1 - buffer_idx if cv2.waitKey(1) ord(q): break cap.release() cv2.destroyAllWindows()注意cv2.VideoCapture必须配合cv2.CAP_FFMPEG后端而非默认 V4L2否则 RTSP 流会严重卡顿。初始化时添加cap cv2.VideoCapture(rtsp://..., cv2.CAP_FFMPEG)5. 健康状态判定逻辑落地从检测框到养殖决策的三层映射规则5.1 单帧判定基于 bbox 与关键点的姿态角计算公式YOLOv7 输出仅提供bbox但“伏卧”需量化判定。本方案在postprocess.py中增加姿态解析模块def calculate_posture_angle(keypoints): keypoints: array of shape (5, 2), order: [head, beak, left_wing, right_wing, tail] Return: posture_angle in degrees (0standing, 90fully prone) # 计算脊柱向量head → tail spine_vec keypoints[4] - keypoints[0] # tail - head # 计算水平参考向量平行于图像底边 horizon_vec np.array([1, 0]) # 向量夹角弧度转角度 cos_theta np.dot(spine_vec, horizon_vec) / (np.linalg.norm(spine_vec) * np.linalg.norm(horizon_vec)) angle np.degrees(np.arccos(np.clip(cos_theta, -1.0, 1.0)) # 标准化站立鸡脊柱接近垂直angle≈0°伏卧鸡脊柱接近水平angle≈90° return min(max(angle, 0), 90) # 在推理后调用 for det in detections: # det: [x1,y1,x2,y2,conf,class_id] if det[5] 1: # weak 类别 # 从同一帧的 pose_keypoints.npy由 MMPose 预生成提取对应鸡只关键点 kp get_keypoints_by_bbox(det[:4], all_keypoints) posture calculate_posture_angle(kp) if posture 65: # 伏卧阈值 print(f发现伏卧鸡姿态角 {posture:.1f}°建议巡检笼位 {cage_id})5.2 时序判定滑动窗口统计与告警触发条件表单帧判定易受抖动影响需时序聚合。采用 60 秒滑动窗口30 帧2FPS统计维度健康 (healthy)虚弱 (weak)应激 (stressed)单窗口内出现频次≥ 25 帧≥ 8 帧≥ 12 帧最长连续帧数—≥ 90 秒≥ 60 秒空间聚集度—同一笼位 ≥ 3 只同一笼位 ≥ 5 只告警级别无黄色需人工复核红色自动通知兽医实现时用collections.deque维护窗口from collections import deque weak_window deque(maxlen30) # 存储最近 30 帧的 weak 数量 for frame in video_stream: weak_count count_weak_in_frame(frame) # 调用前述姿态角判定 weak_window.append(weak_count) if sum(weak_window) 8 and max_consecutive(weak_window) 45: trigger_alert(weak, cage_id)5.3 养殖决策映射将模型输出转化为可执行的环控指令最终价值不在“检测出什么”而在“该做什么”。本项目与养殖场环控系统如霍尼韦尔 EBI对接定义动作映射表检测结果触发条件环控指令执行设备weak集群同一笼位连续 2 分钟 ≥ 3 只提升该区域温度 1.5℃笼位电热板stressed集群同一区域 5 分钟内 ≥ 8 只启动该区域雾化降温湿度5%高压微雾系统healthy比例70%全场统计持续 10 分钟发送短信至场长手机“全场健康指数偏低请核查通风”4G DTU 模块指令通过 Modbus TCP 协议下发Python 示例from pymodbus.client import ModbusTcpClient client ModbusTcpClient(192.168.1.200, port502) # 环控主机 IP if client.connect(): # 写入寄存器 40001温度设定值单位 0.1℃ client.write_register(40001, int(255), unit1) # 25.5℃ client.close()这套逻辑已在山东某 50 万只肉鸡场上线将疾病早期识别响应时间从平均 17 小时缩短至 23 分钟料肉比优化 0.08。本文还有配套的精品资源点击获取