人工智能AI基于DeepSeek和YOLOv8_YOLOV12智能动物健康监测识别系统在这里插入图片描述
1
在这里插入图片描述
人工智能AI基于DeepSeek和Yolov8_12的智能动物健康监测系统
在这里插入图片描述

一、技术栈
前端:Vue3+TypeScript+Element Plus+ECharts+Vite
后端:SpringBoot3+MyBatis-Plus+MySQL8+JWT
算法端:Flask+PyTorch+Yolo+OpenCV
在这里插入图片描述

1. 数据集概况表

数据集类型 行为类别 (中文/英文) 类别数量 训练集 (Train) 验证集 (Val) 测试集 (Test) 总计样例数
猪行为识别 1. 饮水 (drinking)2. 进食 (eating)3. 躺卧 (lying)4. 坐立 (sitting)5. 嗅探 (sniffing)6. 站立 (standing) 6 866 248 123 1,237
牛行为识别 1. 发情 (Estrus)2. 吃草 (grazing)3. 躺卧 (lying)4. 站立 (standing) 4 2,226 419 295 2,940

2. 模型训练精度表 (mAP50)

:以下精度基于项目提供的特定数据集场景训练得出。对于场景一致的数据识别效果优秀,但在其他不同场景下泛化性可能较弱。

🐷 猪行为识别模型精度
行为类别 (英文) 行为类别 (中文) mAP50 精度 性能评价
drinking 饮水 0.955 ⭐⭐⭐⭐⭐ 极佳
lying 躺卧 0.955 ⭐⭐⭐⭐⭐ 极佳
eating 进食 0.949 ⭐⭐⭐⭐⭐ 极佳
standing 站立 0.825 ⭐⭐⭐⭐ 良好
sitting 坐立 0.804 ⭐⭐⭐⭐ 良好
sniffing 嗅探 0.678 ⭐⭐⭐ 一般 (需优化)
平均精度 - ~0.861 -
🐮 牛行为识别模型精度
行为类别 (英文) 行为类别 (中文) mAP50 精度 性能评价
lying 躺卧 0.972 ⭐⭐⭐⭐⭐ 极佳
standing 站立 0.935 ⭐⭐⭐⭐⭐ 极佳
grazing 吃草 0.836 ⭐⭐⭐⭐ 良好
Estrus 发情 0.834 ⭐⭐⭐⭐ 良好
平均精度 - ~0.894 -

📊 数据分析总结

  1. 高置信度行为:模型对**“躺卧” (lying)“站立” (standing)**这类静态或大动作行为的识别非常精准(mAP50 > 0.93),无论是猪还是牛。
  2. 难点行为
    • 猪的**“嗅探” (sniffing)**动作幅度小且特征不明显,精度相对较低 (0.678),是后续优化的重点。
    • 猪的**“坐立” (sitting)**介于躺和站之间,也存在一定识别难度。
  3. 数据量影响:牛的行为数据集总量(约2940张)远大于猪(约1237张),整体来看,牛模型的平均精度 (~0.894) 略高于猪模型 (~0.861),说明数据量的增加对模型稳定性有正向帮助。

智慧畜牧监测系统。结合了**计算机视觉(YOLO + BoTSORT)进行实时行为检测与跟踪,并利用大语言模型(LLM)**生成专业的健康分析报告。

代码分为三个核心部分:

  1. AI 算法服务 (Python/Flask):负责视频流处理、YOLO 行为识别、BoTSORT 目标跟踪以及调用 LLM 生成报告。
  2. 后端业务服务 (Java/SpringBoot):负责用户权限、设备管理、数据存储和 API 接口。
  3. 前端可视化界面 (Vue3):实现多路监控宫格、数据大屏和行为分析报表。

第一部分:AI 算法微服务 (Python + Flask)

这是系统的“大脑”,负责处理视频流并输出结构化数据。

1. 环境依赖 (requirements.txt)
flask
flask-cors
ultralytics>=8.0.0
opencv-python
numpy
supervision
requests
pandas
2. 核心推理与跟踪代码 (ai_engine.py)

集成了 YOLO 检测和 BoTSORT 跟踪逻辑。

# file: ai_engine.py
import cv2
from ultralytics import YOLO
from supervision import Detections, ByteTrack # 或者使用 BoTSORT
import numpy as np

class AnimalBehaviorEngine:
    def __init__(self, model_path='weights/pig_behavior.pt'):
        # 加载 YOLO 模型
        self.model = YOLO(model_path)
        # 定义行为类别映射 (以猪为例)
        self.class_map = {
            0: 'drinking', 1: 'eating', 2: 'lying', 
            3: 'sitting', 4: 'sniffing', 5: 'standing'
        }
        # 初始化跟踪器 (BoTSORT 或 ByteTrack)
        self.tracker = ByteTrack() 

    def process_frame(self, frame):
        """
        处理单帧图像:检测 -> 跟踪 -> 行为统计
        """
        # 1. YOLO 推理
        results = self.model(frame, verbose=False)[0]
        
        # 2. 转换为 Supervision Detections 格式
        detections = Detections.from_ultralytics(results)
        
        # 3. 更新跟踪器 (获取稳定的 ID)
        detections = self.tracker.update_with_detections(detections)
        
        # 4. 标注画面
        annotated_frame = frame.copy()
        behavior_counts = {}
        
        for i, tracker_id in enumerate(detections.tracker_id):
            if tracker_id is None: continue
            
            class_id = detections.class_id[i]
            conf = detections.confidence[i]
            bbox = detections.xyxy[i]
            
            label = self.class_map.get(class_id, "unknown")
            
            # 统计行为数量
            behavior_counts[label] = behavior_counts.get(label, 0) + 1
            
            # 绘制框和 ID
            cv2.rectangle(annotated_frame, (int(bbox[0]), int(bbox[1])), 
                          (int(bbox[2]), int(bbox[3])), (0, 255, 0), 2)
            cv2.putText(annotated_frame, f"ID:{tracker_id} {label}", 
                        (int(bbox[0]), int(bbox[1]-10)), 
                        cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)
        
        return annotated_frame, behavior_counts, detections
3. Flask API 服务 (app.py)

提供视频流推流接口和 LLM 分析接口。

# file: app.py
from flask import Flask, Response, request, jsonify
from flask_cors import CORS
from ai_engine import AnimalBehaviorEngine
import cv2
import requests
import json

app = Flask(__name__)
CORS(app)

# 初始化引擎
engine = AnimalBehaviorEngine('weights/pig_behavior.pt')

# 模拟视频源 (实际项目中应连接 RTSP)
# 注意:说明中提到不支持真实摄像头,这里用本地视频文件模拟
VIDEO_SOURCE = 'videos/demo_pig.mp4' 

@app.route('/video_feed/<camera_id>')
def video_feed(camera_id):
    """生成 MJPEG 视频流"""
    cap = cv2.VideoCapture(VIDEO_SOURCE)
    
    def generate():
        while cap.isOpened():
            ret, frame = cap.read()
            if not ret: break
            
            # AI 处理
            annotated_frame, counts, _ = engine.process_frame(frame)
            
            # 编码为 JPEG
            ret, buffer = cv2.imencode('.jpg', annotated_frame)
            frame_bytes = buffer.tobytes()
            
            yield (b'--frame\r\n'
                   b'Content-Type: image/jpeg\r\n\r\n' + frame_bytes + b'\r\n')
            
            # 将统计数据发送到前端 (可通过 WebSocket 或 SSE,这里简化为打印日志)
            # print(f"Camera {camera_id} Stats: {counts}")
            
    return Response(generate(), mimetype='multipart/x-mixed-replace; boundary=frame')

@app.route('/analyze/health', methods=['POST'])
def analyze_health():
    """调用大模型生成健康报告"""
    data = request.json
    behavior_stats = data.get('stats', {}) # 例如 {'lying': 50, 'eating': 20...}
    
    prompt = f"""
    你是一位资深畜牧专家。根据以下动物行为统计数据,生成一份健康分析报告:
    数据:{json.dumps(behavior_stats)}
    要求:
    1. 评估整体健康状态(良好/一般/危险)。
    2. 指出异常行为(如躺卧时间过长可能生病)。
    3. 给出具体的饲养建议。
    4. 输出格式为 JSON,包含 status, summary, suggestions 字段。
    """
    
    # 调用阿里百炼/Qwen API (伪代码)
    # response = call_qwen_api(prompt)
    # return jsonify(response)
    
    # 模拟返回
    return jsonify({
        "status": "良好",
        "summary": "群体活跃度正常,进食量达标。",
        "suggestions": ["建议检查饮水区卫生", "夜间注意保温"]
    })

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000, debug=True)

第二部分:后端业务服务 (Java SpringBoot 3)

负责管理摄像头信息、存储历史记录和权限控制。

1. 实体类 (Camera.java)
// file: src/main/java/com/example/smartfarm/entity/Camera.java
@Data
@TableName("sys_camera")
public class Camera {
    @TableId(type = IdType.AUTO)
    private Long id;
    private String name; // 摄像头名称,如 "保育区监控01"
    private String rtspUrl; // 虽然本项目用模拟视频,但字段保留
    private String location; // 位置
    private Integer status; // 0-离线 1-在线
}
2. 行为记录控制器 (BehaviorController.java)

提供前端图表所需的数据接口。

// file: src/main/java/com/example/smartfarm/controller/BehaviorController.java
@RestController
@RequestMapping("/api/behavior")
@CrossOrigin
public class BehaviorController {

    @Autowired
    private BehaviorRecordService recordService;

    /**
     * 获取行为分布统计 (用于饼图)
     */
    @GetMapping("/distribution")
    public Result<Map<String, Object>> getDistribution(
            @RequestParam String cameraId, 
            @RequestParam String startDate, 
            @RequestParam String endDate) {
        
        List<BehaviorRecord> records = recordService.lambdaQuery()
            .eq(BehaviorRecord::getCameraId, cameraId)
            .between(BehaviorRecord::getCreateTime, startDate, endDate)
            .list();
        
        // 统计各类别数量
        Map<String, Long> stats = records.stream()
            .collect(Collectors.groupingBy(BehaviorRecord::getBehaviorType, Collectors.counting()));
        
        return Result.success(stats);
    }

    /**
     * 获取健康分析摘要
     */
    @GetMapping("/summary/{id}")
    public Result<HealthReport> getSummary(@PathVariable Long id) {
        // 从数据库获取之前由 Python 服务生成并保存的报告
        HealthReport report = reportService.getById(id);
        return Result.success(report);
    }
}

第三部分:前端可视化界面 (Vue3 + TS)

多路监控、宫格切换和数据大屏。

1. 视频监控组件 (VideoMonitor.vue)
<!-- file: src/views/monitor/VideoMonitor.vue -->
<template>
  <div class="monitor-container">
    <!-- 顶部工具栏 -->
    <div class="toolbar">
      <el-select v-model="currentCamera" placeholder="选择摄像头">
        <el-option v-for="cam in cameras" :key="cam.id" :label="cam.name" :value="cam.id" />
      </el-select>
      
      <el-radio-group v-model="gridLayout">
        <el-radio-button label="1">1 宫格</el-radio-button>
        <el-radio-button label="4">4 宫格</el-radio-button>
        <el-radio-button label="9">9 宫格</el-radio-button>
      </el-radio-group>
      
      <el-button type="primary" @click="startAnalysis">AI 智能分析</el-button>
    </div>

    <!-- 视频宫格区域 -->
    <div class="video-grid" :class="'grid-' + gridLayout">
      <div v-for="i in gridCount" :key="i" class="video-card">
        <div class="video-header">
          <span>{{ getCameraName(i) }}</span>
          <el-tag size="small" type="success">直播中</el-tag>
        </div>
        <img 
          :src="`http://localhost:5000/video_feed/${getCameraId(i)}`" 
          class="video-stream" 
          alt="Stream"
        />
        <!-- 悬浮显示实时统计 -->
        <div class="overlay-stats">
          <span v-if="liveStats[i]">站立: {{ liveStats[i].standing || 0 }}</span>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed } from 'vue';
import { ElMessage } from 'element-plus';

const gridLayout = ref('1');
const currentCamera = ref('');
const liveStats = ref<Record<number, any>>({});

// 模拟摄像头列表
const cameras = [
  { id: 'cam01', name: '保育区监控01' },
  { id: 'cam02', name: '喂食区监控01' },
  { id: 'cam03', name: '运动场监控01' }
];

const gridCount = computed(() => parseInt(gridLayout.value));

const getCameraId = (index: number) => {
  // 简单轮询分配摄像头 ID
  return cameras[(index - 1) % cameras.length].id;
};

const getCameraName = (index: number) => {
  return cameras[(index - 1) % cameras.length].name;
};

const startAnalysis = () => {
  ElMessage.info("正在调用大模型生成健康报告...");
  // 调用后端 API 生成报告并跳转
};
</script>

<style scoped>
.monitor-container { padding: 20px; height: 100%; display: flex; flex-direction: column; }
.toolbar { margin-bottom: 20px; display: flex; gap: 15px; align-items: center; }
.video-grid { display: grid; gap: 15px; flex: 1; }
.grid-1 { grid-template-columns: 1fr; }
.grid-4 { grid-template-columns: repeat(2, 1fr); }
.grid-9 { grid-template-columns: repeat(3, 1fr); }

.video-card { 
  background: #000; 
  border-radius: 8px; 
  overflow: hidden; 
  position: relative; 
  aspect-ratio: 16/9;
}
.video-stream { width: 100%; height: 100%; object-fit: cover; }
.video-header { 
  position: absolute; top: 0; left: 0; right: 0; 
  background: rgba(0,0,0,0.6); color: white; 
  padding: 5px 10px; display: flex; justify-content: space-between; 
}
.overlay-stats {
  position: absolute; bottom: 10px; right: 10px;
  background: rgba(0, 0, 0, 0.7); color: #00ff00;
  padding: 5px; border-radius: 4px; font-size: 12px;
}
</style>
2. 行为分析大屏 (BehaviorAnalysis.vue)
<!-- file: src/views/analysis/BehaviorAnalysis.vue -->
<template>
  <div class="analysis-dashboard">
    <!-- 顶部筛选 -->
    <div class="filters">
      <el-date-picker v-model="dateRange" type="daterange" range-separator="" start-placeholder="开始日期" end-placeholder="结束日期"/>
      <el-button type="primary" @click="fetchData">查询</el-button>
    </div>

    <!-- 统计卡片 -->
    <el-row :gutter="20">
      <el-col :span="6">
        <el-card shadow="hover">
          <template #header>总记录数</template>
          <div class="stat-value">{{ totalRecords }}</div>
        </el-card>
      </el-col>
      <el-col :span="6">
        <el-card shadow="hover">
          <template #header>平均持续时间</template>
          <div class="stat-value">{{ avgDuration }}秒</div>
        </el-card>
      </el-col>
    </el-row>

    <!-- 图表区域 -->
    <el-row :gutter="20" style="margin-top: 20px;">
      <el-col :span="12">
        <el-card>
          <template #header>行为类型分布</template>
          <div ref="pieChartRef" style="height: 300px;"></div>
        </el-card>
      </el-col>
      <el-col :span="12">
        <el-card>
          <template #header>摄像头分布</template>
          <div ref="barChartRef" style="height: 300px;"></div>
        </el-card>
      </el-col>
    </el-row>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted } from 'vue';
import * as echarts from 'echarts';
import axios from 'axios';

const pieChartRef = ref<HTMLElement>();
const barChartRef = ref<HTMLElement>();
const totalRecords = ref(0);
const avgDuration = ref(0);

onMounted(() => {
  fetchData();
});

const fetchData = async () => {
  // 1. 获取统计数据
  const res = await axios.get('http://localhost:8080/api/behavior/distribution?cameraId=all&startDate=2023-01-01&endDate=2023-12-31');
  const data = res.data.data;
  
  // 2. 渲染饼图
  const chart = echarts.init(pieChartRef.value!);
  chart.setOption({
    tooltip: { trigger: 'item' },
    series: [{
      type: 'pie',
      radius: ['40%', '70%'],
      data: Object.keys(data).map(key => ({ value: data[key], name: key }))
    }]
  });
  
  totalRecords.value = Object.values(data).reduce((a, b) => a + b, 0);
  avgDuration.value = 38; // 模拟数据
};
</script>

第四部分:项目启动与运行指南

1. 目录结构建议
SmartAnimalSystem/
├── ai_service/          # Python Flask 服务
│   ├── weights/         # 存放 best.pt
│   ├── videos/          # 存放演示视频
│   └── app.py
├── backend/             # Java SpringBoot 服务
│   ├── src/
│   └── pom.xml
├── frontend/            # Vue3 前端
│   ├── src/
│   └── package.json
└── docs/                # 文档和教程
2. 启动步骤
  1. 启动 AI 服务
    cd ai_service
    pip install -r requirements.txt
    python app.py
    # 访问 http://localhost:5000/video_feed/cam01 查看视频流
    
  2. 启动后端
    • 配置 application.yml 连接 MySQL。
    • 运行 SpringBoot 主类。
  3. 启动前端
    cd frontend
    npm install
    npm run dev
    
3. 关于 ID 识别的特别说明

正如项目描述所言,本系统使用的是 BoTSORT/ByteTrack 生成的临时追踪 ID

  • 特点:ID 仅在单次视频会话中有效。如果动物离开画面再回来,ID 会改变。
  • 适用场景:短期行为统计、实时计数。
  • 不适用场景:长期个体档案建立(这需要 ReID 重识别技术)。

**

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐