简介:面向开发者、科研人员及畜牧养殖领域的智能动物健康监测系统源码,基于Yolo与DeepSeek构建,通过Python完成数据处理与模型训练,Html搭建可视化界面,可对动物目标进行实时检测与健康特征分析,适用于动物保护、养殖管理和科学实验等场景。压缩包共325个文件,约11.06MB,其中包含174个Python源码、93个yaml模型配置、24张检测结果图片、15个txt数据文件及6个Html页面,覆盖从模型配置、训练检测到前端展示的完整链路。目前已有265人学习使用。通过该源码,读者能掌握Yolo目标检测与DeepSeek特征分析的工程化落地思路,获取可直接运行的项目框架、模型参数与交互界面,便于后续针对特定动物或健康指标进行定制改进。源码目录结构清晰,适合作为计算机视觉与AIoT健康监测项目的参考基座。 做养殖的朋友应该都有过这种经历:白天看着一栏猪都好好的,第二天早上却突然发现有一头精神萎靡甚至不动了,等兽医到场往往已经错过最佳处理期。我家里的宠物猫有一次也是连续两天躲在角落不爱动,要不是我刚好注意到,可能就拖成泌尿问题了。动物不会说话,判断它们健不健康基本全靠人眼盯,但人不能24小时守在旁边。所以去年我花了不少业余时间,做了这套基于Yolo+DeepSeek+Python开发的智能动物健康监测系统,核心思路很简单:用Yolo识别画面里的动物和目标行为,用DeepSeek把持续一段时间的“行为序列”翻译成通俗的健康评估,最后推送告警到手机。整套源码我已经整理好,这篇博客就把设计思路、训练细节、API接入和踩坑记录完整写一遍,给想做类似项目的朋友一个能直接上手的参考。
1. 系统整体设计思路
1.1 核心需求拆解
一个真正可用的动物健康监测系统,不能只做到“检测出动物”。我刚接触这个项目时,第一版想法特别简单:拿Yolo识别出动物,再判断它是不是躺着的,躺得久了就告警。实际一跑就发现问题了——动物不是每时每刻都静止,猪一天要睡十几个小时,牛也会长时间卧着反刍,光靠“躺卧时长”根本分不清正常休息还是异常。
所以我把需求拆成了三层。第一层是感知层,用Yolo做目标检测,输出画面中动物和关键行为的类别与位置,比如站立、行走、躺卧、进食、跛行。第二层是分析层,把单个帧的检测结果按时间轴聚合成“行为序列”,统计一段时间内的行为占比、切换频率、活动量等特征。第三层是语义层,把行为序列交给DeepSeek,让它结合动物物种、环境温度、既往状态等上下文信息,给出健康评估和干预建议。前两层解决“看到了什么”,第三层解决“这说明什么”。
1.2 为什么选Yolo而不是其他模型
检测层的选型我对比过不少方案。传统图像分类模型只能回答“画面里有没有猪”,没法给出位置,健康监测很多场景恰恰需要知道“哪一只”出了问题。Faster R-CNN这一类两阶段检测器精度不错,但推理速度在边缘设备上往往只有个位数FPS,放养殖场监控场景明显不够用。Yolo系列是典型的单阶段检测器,速度和精度的平衡做得最好,一个普通GPU跑Yolo v8n可以达到几十甚至上百FPS,足够应对多路视频流。
具体版本上,我最后选了Yolo v8作为主力。Yolo v11虽然更新,但v8的社区生态更成熟,Ultralytics框架开箱即用,导出ONNX、TensorRT都比较方便。如果你要训练的类别特别多,或者目标特别小,再考虑v11或者加装注意力机制。这里记住一个原则:先用最稳的模型把流程跑通,再用更大模型做精度提升。
1.3 DeepSeek在系统里承担的角色
最初也有人问我,行为统计本身就能出告警,为什么还要加一个大语言模型?这个问题的答案,取决于你对“告警”的要求。如果只是简单规则,比如“躺卧超过3小时就报警”,那确实不需要LLM。但实际养殖环境里,规则稍微复杂一点就会非常难写:猪在夏天午后会集体躺卧喘气休息,冬天却会更多扎堆活动;牛在产前会有烦躁、频繁起卧的表现。这些情况用固定阈值去套,误报率会高到没人愿意看告警。
DeepSeek的角色,就是把这些模糊的、依赖经验的判断交给一个知识面更广的模型。Yolo把行为量化成特征序列,DeepSeek根据特征序列做语义推理,输出类似“该牛最近2小时活动量显著下降,结合当前气温38℃,疑似中暑风险较高,建议检查饮水与降温设备”这样的可读结论。它不替代检测,而是把检测结果加工成决策信息,这是整个系统降低误报率的关键。
2. 动物行为识别的模型选型与训练
2.1 数据集准备与标注规范
这一步是整个项目里最耗时,也最决定上限的环节。我刚开始偷懒,直接拿公开的COCO数据集预训练权重去识别,发现猪牛羊类的检测效果还行,但“跛行”“进食”“异常抖动”这类细粒度行为完全没有覆盖,只能自己标注。
标注时我用的是LabelImg和Labelme混合方案。目标检测框(bounding box)用LabelImg效率更高,如果是实例分割需求,再换Labelme。类别定义不要太碎,我一开始分了十几个行为类别,结果标注样本严重不足,模型反而学乱了。后来收敛成6个核心类别:standing(站立)、walking(行走)、lying(躺卧)、eating(进食)、drinking(饮水)、limping(跛行)。每个类别我保证至少3000个标注框,并且覆盖不同光线、不同栏舍角度、不同距离的画面。这个量级在几十个小时的标注工时内可以完成。
2.2 训练参数与数据增强
我用的是Ultralytics Yolo v8n作为基线,一张RTX 4060显卡上就能训练。数据集按8:1:1划分成训练集、验证集和测试集。关键参数我贴一段实测比较稳的配置:
# data.yaml path: ./animals_dataset train: images/train val: images/val test: images/test names: 0: standing 1: walking 2: lying 3: eating 4: drinking 5: limping训练命令:
yolo detect train \ data=data.yaml \ model=yolov8n.pt \ imgsz=640 \ epochs=100 \ batch=16 \ lr0=0.01 \ augment=True \ patience=20这几个参数得解释一下。imgsz=640是精度和速度的折中;batch=16在显存允许的情况下尽量开大,训练更稳;lr0=0.01是Ultralytics默认初始学习率,我试过0.005,收敛慢但最终精度略升,如果你的数据量在几千张这个量级,建议从0.01开始,让模型快速进入收敛区。patience=20用于早停,避免后期无效训练。
数据增强方面,mosaic和hsv_augment对动物的毛色差异、遮挡情况帮助很大,但训练后期可以适当降低mosaic比例,防止模型对遮挡目标过度拟合,反而在正常目标上精度下降。实测下来,mosaic=0.8、hsv_v=0.4效果比较稳。
2.3 推理后处理与重叠框处理
很多新手在部署时会遇到一个典型问题:同一只动物被检测出多个互相重叠的框,或者一个行为类别被重复识别。Yolo模型本身输出大量候选框,默认的NMS(非极大值抑制)能解决一部分,但还是需要自己调一下参数。我的经验是把conf降到0.25,NMS的iou阈值设为0.45,可以让重叠框率下降30%左右。
另外,视频流如果直接逐帧检测,帧与帧之间的结果会抖动得很厉害,具体表现为同一只动物这一帧被识别成standing,下一帧又变成lying。处理办法是加一个滑动窗口平滑:取最近10帧的检测结果做多数投票,滤掉瞬时噪点。这个逻辑后面章节会配上代码。
3. DeepSeek接入与健康分析逻辑
3.1 API调用方式与鉴权配置
DeepSeek的接口兼容OpenAI的格式,这让我们接入成本低了很多。直接用Python的openai库改一下base_url和api_key就行。需要注意的点是,最新版本的openai库对base_url的支持没有问题,但有些老版本传参方式不对,会一直报连接错误。我这边锁定的版本是openai>=1.30.0。
先看一段最基础的接入代码:
from openai import OpenAI client = OpenAI( api_key="sk-你的key", base_url="https://api.deepseek.com" ) resp = client.chat.completions.create( model="deepseek-chat", messages=[ {"role": "system", "content": "你是一个动物健康专家。"}, {"role": "user", "content": "最近30分钟,目标牛行为序列:站立20次,行走8次,躺卧2次,当前气温38℃。"} ], temperature=0.2 ) print(resp.choices[0].message.content)这段代码跑通之后,整个系统就具备了“自然语言分析”能力。细节上,temperature我建议设低一点,0.1到0.3之间。健康评估这种事需要的是准确稳定,不是创意发散,温度越高越可能输出模棱两可的废话。
3.2 Prompt工程:把行为序列翻译成健康评估
DeepSeek输出质量的高低,七成取决于prompt怎么设计。我试过两种风格,一种是把所有检测数据塞进去,什么都不解释,结果返回的内容常常飘忽不定。另一种是把系统提示词写得像一份“工作说明书”,明确告诉模型输入格式、判断维度、输出结构。
我最终使用的系统提示词大概长这样:
你是养殖场健康监测助手。你会收到5分钟窗口内的动物行为统计数据,包括 各行为频次、持续时间、行为切换次数,以及当前环境温度。请根据这些数据 判断动物是否存在健康风险。 输出格式要求: 1. 风险等级:低/中/高 2. 风险原因:用一到两句话描述 3. 建议动作:给出一到三条可执行的建议 4. 如果数据不足,只输出“数据不足,无法判断”,不要编造关键就在最后一条:允许模型承认不足。如果不加这句,它会强行编一个结论,这在健康场景里很危险。
另一个很实用的技巧是给模型提供“正常基线”。比如这个物种在对应温度下的正常行为范围是多少,可以让模型判断时有一个对照表,输出质量会显著提升。我遇到过的情况是,不加基线时,模型把猪的长时间躺卧一律判成低风险;加入“高温天气下躺卧时间超60%属于正常散热”这条基线后,误判率明显下降。
3.3 如何把Yolo输出变成LLM能看懂的结构
Yolo的原始输出是若干组[x1, y1, x2, y2, class_id, confidence],这些数字直接丢给DeepSeek没有意义。我的做法是先做一个行为聚合器,把5分钟窗口内每一帧的检测结果聚合为统计特征,再拼成文本。
行为序列的特征我选了几项:每种行为的累计帧数占比、行为切换次数、目标中心点的像素位移速度(估算活动量)、置信度加权后的大类结果。把这些填进自己定义的模板里,效果最稳定,比如:
时间窗口: 14:00-14:05 动物ID: A-003 站立占比: 12% 行走占比: 5% 躺卧占比: 80% 进食占比: 2% 饮水占比: 1% 行为切换次数: 15 活动速度均值: 0.2 m/s 环境温度: 35℃这样的文本结构,DeepSeek一眼就能看懂,输出也会更稳定。不要用自由格式的JSON硬凑,模型虽然能读JSON,但实际测试下来,用这种类表格的自然语言模板,按行解析的成功率最高。
4. 核心代码实现:从视频流到健康报告
4.1 视频流读取与目标检测循环
系统入口是一个多线程的检测循环,我用OpenCV读取视频流,每帧送入Yolo模型推理,同时控制帧率,避免CPU/GPU跑满。下面是核心检测循环的简化代码:
import cv2 import torch from ultralytics import YOLO model = YOLO("best.pt") cap = cv2.VideoCapture("rtsp://192.168.1.100:554/stream1") window_frames = [] skip_count = 0 while True: ret, frame = cap.read() if not ret: continue # 每3帧检测一次,降低负载 skip_count += 1 if skip_count % 3 != 0: continue results = model(frame, conf=0.25, iou=0.45, classes=[0,1,2,3,4,5]) boxes = results[0].boxes for box in boxes: x1, y1, x2, y2 = box.xyxy[0].tolist() cls = int(box.cls[0]) score = float(box.conf[0]) print(f"class={cls} score={score:.2f} bbox=({x1:.0f},{y1:.0f},{x2:.0f},{y2:.0f})") # 把检测结果结构化后进入行为聚合 window_frames.append(parse_yolo_results(results)) if len(window_frames) > 150: # 假设5分钟,每帧间隔2秒 analyze_window(window_frames) window_frames.clear()这里的核心技巧是抽帧检测。养殖场摄像头24小时录像,完全不抽帧会白白增加GPU负载,其实分析健康状态根本不需要每帧都检测。我实测5分钟窗口采集150帧就足够,也就是约2秒一帧。当然如果你对跛行这类瞬间动作特别关注,可以把抽帧间隔缩短到0.5秒。
4.2 滑动窗口平滑与行为统计
检测器的单帧输出抖动比较严重,所以我在进入统计前会做一次平滑。最简单有效的方法是给每个行为类别维护一个历史计数器,取最近N帧出现频率最高的类别作为当前状态。代码示意:
from collections import deque, Counter class BehaviorSmoother: def __init__(self, window_size=10): self.history = deque(maxlen=window_size) def update(self, detection_list): # detection_list 中含当前帧所有目标的行为类别 behaviors = [d["cls"] for d in detection_list] self.history.append(behaviors) if not behaviors: return None # 多数投票 flat = [c for h in self.history for c in h] if not flat: return None return Counter(flat).most_common(1)[0][0]这个方法的性价比非常高,我用了之后,单目标行为识别准确率从80%左右提升到了90%以上,代价只是几十行代码和一个队列的内存。
4.3 调用DeepSeek并推送告警
行为聚合完成后,触发DeepSeek分析的条件需要斟酌。我一开始是每个窗口都调用一次,结果一天下来API调用量巨大,费用控制不住。后来改成两级策略:先由本地规则判断是否有“可疑波动”,比如行为切换次数超过历史均值1.5倍、躺卧占比在某类动物中异常升高,满足条件时才调用DeepSeek做深度分析。这样既保留了大模型的分析能力,又控制了成本。
def analyze_window(features): if not need_deepseek(features): return prompt = build_prompt(features) conclusion = call_deepseek(prompt) if "风险等级: 高" in conclusion or "风险等级: 中" in conclusion: push_alert(features, conclusion)告警推送我接入了钉钉机器人,用Webhook发送文本消息。你也可以换Server酱、企业微信机器人,逻辑都一样:组装一个JSON POST请求就行。我实测从检测到异常到手机收到告警,延迟控制在10秒以内,完全够用。
5. 常见问题与踩坑记录
5.1 问题速查表
我把整个开发过程里遇到的高频问题整理成了表格,方便你对照排查。
| 问题现象 | 可能原因 | 解决办法 |
|---|---|---|
| 同一动物多个重叠框 | NMS阈值过高或置信度过低 | conf设为0.25,iou设为0.45 |
| 行为类别帧间抖动严重 | 没有做时序平滑 | 加BehaviorSmoother,10帧多数投票 |
| DeepSeek返回内容不稳定 | temperature过高或prompt不明确 | 温度降到0.2,补全输出格式要求 |
| API调用报连接类错误 | openai库版本过旧,或base_url配置错误 | 升级openai>=1.30.0,检查base_url |
| 视频流RTSP断流 | 网络抖动或摄像头缓冲溢出 | 加断线重连,设置超时重试 |
| 模型在夜间画面误检多 | 训练数据缺少夜间样本 | 补充红外/低光样本,或者先做亮度增强 |
| 高频调用API费用飙升 | 没有本地规则前置过滤 | 先规则后LLM,控制分析频率 |
5.2 独家避坑心得
有几个坑,官方文档和一般教程都不会写,但实际开发时只要踩到就非常折腾。
第一个坑是路径和数据顺序。Ultralytics在训练时会自动读取data.yaml里的路径,但很多人的训练集和验证集目录名不一致,导致训练时loss正常,验证时却一直报class不存在。我的建议是所有子集目录结构保持一致,文件名前缀规范,减少不必要的排查时间。
第二个坑是动物ID跟踪。健康监测不能只看猪群整体,往往需要跟踪个体。Yolo只负责检测,不做跨帧身份保持。如果摄像头固定角度,可以用目标中心点在相邻帧之间的最近邻匹配来维护简单的ID。但如果养殖栏里动物密集还会互相遮挡,建议直接引入ByteTrack或DeepSORT,否则“A-003号动物状态异常”这种报告永远做不出来。
第三个坑是环境温度数据。DeepSeek做分析时,温度等上下文数据非常关键,但很多养殖场的摄像头并不带温湿度传感器。我的解决方法是外接一个十几块的温湿度模块,走MQTT协议把数据同步到服务器,再和视频检测结果一起写入数据库。这个投入很小,但对分析质量提升非常明显。
第四个坑是部署环境的区分。开发阶段直接在Windows上装Ultralytics跑很方便,但真正接入现场监控需要部署到Linux服务器,而且最好用Docker打包,避免Python版本、CUDA版本不一致导致的环境问题。如果你只有一台普通PC,也可以先用CPU做推理,Yolo v8n在CPU上单帧推理大约100到200毫秒,5分钟窗口采样150帧完全来得及。
整个系统从立项到跑通,我最深的体会是:看似花哨的“AI健康监测”,实际上没有哪一环是独门绝技,真正考验工程能力的是把检测、统计、语义分析这三段用稳定的数据流串起来。Yolo负责看得见,DeepSeek负责看得懂,Python负责把它们咬合在一起。如果你手头也有摄像头、有动物观察场景,完全可以照着这套流程快速起一个原型。
最后再分享一个小技巧:先别急着追求模型精度,第一版用最简逻辑把所有链路打通,再慢慢优化行为分类和提示词。我把整套源码整理好之后,测试阶段每天出一份自动健康统计日报,效果比预期好得多。后续我还打算把语音播报、多摄像头联动加进去,有进展再发出来聊。
本文还有配套的精品资源,点击获取