猫咪如厕检测与分类识别系统系列【九】视频检测区域在线绘制+支持摄像头+网络摄像头+整体构建【上】

发布于:2025-04-16 ⋅ 阅读:(34) ⋅ 点赞:(0)

前情提要


家里养了三只猫咪,其中一只布偶猫经常出入厕所。但因为平时忙于学业,没法时刻关注牠的行为。我知道猫咪的如厕频率和时长与健康状况密切相关,频繁如厕可能是泌尿问题,停留过久也可能是便秘或不适。为了更科学地了解牠的如厕习惯,我计划搭建一个基于视频监控和AI识别的系统,自动识别猫咪进出厕所的行为,记录如厕时间和停留时长,并区分不同猫咪。这样即使我不在家,也能掌握猫咪的健康状态,更安心地照顾它们。

已完成工作:

猫咪如厕检测与分类识别系统系列【一】 功能需求分析及猫咪分类特征提取
猫咪如厕检测与分类识别系统系列【二】多图上传及猫咪分类特征提取更新
猫咪如厕检测与分类识别系统系列【三】 融合yolov11目标检测
猫咪如厕检测与分类识别系统系列【四】融合检测日志输出及前端展示界面制作
猫咪如厕检测与分类识别系统系列【五】信息存储数据库改进+添加猫咪页面制作+猫咪躯体匹配算法架构更新
猫咪如厕检测与分类识别系统系列【六】分类模型训练+混合检测分类+未知目标自动更新

猫咪如厕检测与分类识别系统系列【七】 当前阶段总结报告

猫咪如厕检测与分类识别系统系列【八】 检测推理事件整合+视频推流架构分析

计划工作:

✅ 猫咪管理功能:已完成猫咪照片上传与名称登记模块。
✅ 多图上传与分类特征提取:已支持批量上传猫咪图像并自动更新个体特征库。
✅ 目标检测与事件识别集成(YOLOv11): 基本实现
🔄 检测区域绘制功能:进行中,计划支持用户自定义如厕检测区域。
🔄 事件行为记录模块:进行中,将实现如厕进出时间、停留时长等事件记录功能。
⏳ 检测结果推流展示:进行中,计划支持算法结果实时推流。本章将实现页面MJPEG推理
⏳ 整体运行结果推流整合:待更新,计划集成检测图像与系统状态为统一视频流输出。


本小节将添加一个交互式区域标注功能 ,让你在前端网页上手动框选如厕区域,然后保存坐标用于检测。


在这里插入图片描述

✅ 实现方案

🔧 前端功能(HTML + JS)

  • 展示当前摄像头帧(或静态图)

  • 鼠标拖动绘制矩形框

  • 显示框的坐标 (x1, y1, x2, y2)

  • 提交后将坐标发送给 Flask 后端

🔧 后端 Flask

  • 接收坐标并保存为配置文件(如 region.json

  • inference.py 在启动时读取区域配置用于判断


🎯 示例页面流程

GET /set-region     → 展示摄像头图并支持标框
POST /set-region    → 提交区域坐标保存

  • /set-region 页面:可交互设置区域

  • 保存为 config/region.json

  • CatDetector 自动加载该区域

✅ 第一步:自动截图一帧用于标注

添加一个 Flask 路由 /snapshot,它会:

  • 从当前摄像头或 RTSP 获取一帧

  • 保存为 static/snapshot.jpg

  • 用作标注背景图


✅ 第二步:创建 /set-region 前端页面

  • 显示 snapshot.jpg

  • 鼠标框选区域

  • 显示坐标

  • 点击保存后写入 config/region.json


✅ 已完成后端部分:


✅ 说明

路由 功能
/snapshot 从摄像头读取一帧并保存为 static/snapshot.jpg
/set-region 打开前端页面进行手动框选区域
/save-region 接收 POST 坐标并保存为 config/region.json

🔜 下一步

添加对应的前端页面 templates/set_region.html,包含:

  • 显示图像

  • 鼠标框选

  • 提交保存区域坐标

✅ 前端标注页面 set_region.html 功能包括:

  1. 打开浏览器访问:http://localhost:5000/snapshot
  • 自动截取一帧作为标注背景
  1. 然后访问:http://localhost:5000/set-region
  • 鼠标拖动标记区域

  • 点击 “保存区域” 将坐标保存到 config/region.json

  1. 后续在 CatDetector 中读取并使用区域:
with open("config/region.json") as f:
    self.toilet_region = tuple(json.load(f).values())

然后在 CatDetector 中加上自动读取 region.json 的功能?这样可以完全替代硬编码区域 (100, 100, 400, 400)inference.py 自动加载区域配置的集成


📌 区域设置逻辑更新如下:

  • 启动时尝试读取 config/region.json

  • 如果存在 → 使用手动标注区域

  • 如果不存在 → 使用默认区域 (100, 100, 400, 400) 并打印警告


🚀 现在完整使用流程:

  1. 打开摄像头截图:http://localhost:5000/snapshot

  2. 打开手动标注:http://localhost:5000/set-region

  3. 框选区域并保存

  4. 系统将自动加载你框出的区域用于如厕判断


<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <title>设置如厕区域</title>
    <style>
        canvas { border: 2px solid #333; cursor: crosshair; }
        #coords { margin-top: 10px; font-weight: bold; }
    </style>
</head>
<body>
<h2>🐱 设置如厕区域</h2>
<canvas id="canvas"></canvas>
<div id="coords">区域: (x1, y1) → (x2, y2)</div>
<button onclick="saveRegion()">保存区域</button>

<script>
const img = new Image();
img.src = "/static/snapshot.jpg";
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');

let startX, startY, endX, endY, isDrawing = false;

img.onload = () => {
    canvas.width = img.width;
    canvas.height = img.height;
    ctx.drawImage(img, 0, 0);
};

canvas.onmousedown = (e) => {
    isDrawing = true;
    startX = e.offsetX;
    startY = e.offsetY;
};

canvas.onmousemove = (e) => {
    if (!isDrawing) return;
    endX = e.offsetX;
    endY = e.offsetY;
    ctx.drawImage(img, 0, 0);
    ctx.strokeStyle = 'red';
    ctx.lineWidth = 2;
    ctx.strokeRect(startX, startY, endX - startX, endY - startY);
    document.getElementById('coords').innerText = `区域: (${startX}, ${startY}) → (${endX}, ${endY})`;
};

canvas.onmouseup = () => isDrawing = false;

function saveRegion() {
    const region = {
        x1: Math.min(startX, endX),
        y1: Math.min(startY, endY),
        x2: Math.max(startX, endX),
        y2: Math.max(startY, endY)
    };
    fetch('/save-region', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(region)
    }).then(res => res.json()).then(data => {
        alert('✅ 区域保存成功!');
    });
}
</script>
</body>
</html>

可以将该文件保存为 templates/set_region.html。访问 /snapshot 截图后,再访问 /set-region 进行区域标注。
接下来实现在一个页面上 输入地址,然后截图,然后选择坐标,流程如下

✅ 输入 RTSP 地址

✅ 点击「截图」抓取摄像头画面

✅ 鼠标框选如厕区域

✅ 保存区域坐标
全部集成到 一个前端页面 中,交互非常清晰!


✅ 页面结构设计

功能区域 描述
📥 输入框 手动填写 RTSP 地址
🎬 截图按钮 请求后端从该地址截图
🖼️ 图像显示区 显示截图并支持框选区域
💾 保存按钮 提交所框选的坐标(保存为 region.json)

🧪 使用方式:

  1. 访问 /set-region

  2. 输入 RTSP 地址(或摄像头路径)

  3. 点击【📸 截图】,自动生成并显示图片

  4. 用鼠标框选区域,点击【保存区域】

  5. 坐标将保存在 config/region.json


🧠 inference.py 会自动加载 region.json 并使用你选定的区域进行判断。
你现在已经拥有前端交互设置 + 实时应用识别 的完整闭环了!刚刚已经实现了手动标注如厕区域并保存为 config/region.json,现在你只需要确保 CatDetector 自动读取这个配置。


之前的 inference.py 中已经包含了这个逻辑 ✅:

def _load_region(self):
    try:
        with open("config/region.json") as f:
            data = json.load(f)
            return (data['x1'], data['y1'], data['x2'], data['y2'])
    except Exception as e:
        print("⚠️ 无法加载区域配置,使用默认区域 (100, 100, 400, 400)")
        return (100, 100, 400, 400)

只需要在 __init__ 中有这行就可以:

self.toilet_region = self._load_region()

最后,只要保证:

self.toilet_region = self._load_region()

就能让系统自动加载你刚刚前端标注并保存的区域了。



网站公告

今日签到

点亮在社区的每一天
去签到