猫咪如厕检测与分类识别系统系列【三】融合yolov11目标检测


✅ 前情提要


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

已完成工作:

✅猫咪如厕检测与分类识别系统系列【一】 功能需求分析及猫咪分类特征提取
✅猫咪如厕检测与分类识别系统系列【二】多图上传及猫咪分类特征提取更新

计划工作:

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

————————————————


本次将继续制作 实时检测模块
使用 YOLOv11 检测摄像头画面中的猫、判断是否进入指定区域,并调用分类模块识别是哪只猫 🐱📹


✅ 功能目标:

  1. 打开摄像头实时读取画面
  2. 用 YOLOv11 检测猫目标(设定类名为 'cat'
  3. 判断猫是否进入你定义的“如厕区域”(矩形区域)
  4. 如果猫在区域内 → 裁剪猫图 → 提特征 → 分类
  5. 在画面中显示识别结果,并记录状态变化(进入/离开)

🧱 YOLOv11 + 分类实时检测代码(main.py 简版)

import cv2
import time
import numpy as np
from recognizer.embedder import CatEmbedder
from recognizer.database import CatDatabase
from recognizer.matcher import CatMatcher
from ultralytics import YOLO  # 假设你用的是YOLOv8/11格式# 初始化
model = YOLO("yolov11_cat.pt")  # 替换为你的模型路径
embedder = CatEmbedder()
db = CatDatabase()
matcher = CatMatcher(db)# 区域设定(可以做成画图交互)
TOILET_REGION = (100, 100, 400, 400)  # (x1, y1, x2, y2)# 状态跟踪
cat_present = False
entry_time = None# 启动摄像头
cap = cv2.VideoCapture(0)while True:ret, frame = cap.read()if not ret:break# 画如厕区域x1, y1, x2, y2 = TOILET_REGIONcv2.rectangle(frame, (x1, y1), (x2, y2), (0, 255, 255), 2)# YOLOv11 推理results = model.predict(frame, verbose=False)boxes = results[0].boxesdetected = Falsecat_name = "Unknown"for box in boxes:cls = int(box.cls[0])conf = float(box.conf[0])if cls != 0:  # 类别为猫(根据你的模型调整)continuexmin, ymin, xmax, ymax = map(int, box.xyxy[0])cx, cy = (xmin + xmax) // 2, (ymin + ymax) // 2# 判断猫是否在如厕区域if x1 < cx < x2 and y1 < cy < y2:detected = Truecat_crop = frame[ymin:ymax, xmin:xmax]# 保存临时图片 + 识别猫tmp_path = "tmp.jpg"cv2.imwrite(tmp_path, cat_crop)vec = embedder.extract(tmp_path)cat_name = matcher.match(vec)# 显示识别名cv2.putText(frame, f"{cat_name}", (xmin, ymin - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 200, 0), 2)cv2.rectangle(frame, (xmin, ymin), (xmax, ymax), (0, 255, 0), 2)# 状态变化记录if detected and not cat_present:entry_time = time.time()print(f"🐱 {cat_name} 进入区域")cv2.imwrite(f"records/{cat_name}_enter_{int(entry_time)}.jpg", frame)if not detected and cat_present:exit_time = time.time()duration = round(exit_time - entry_time, 2)print(f"🚪 {cat_name} 离开区域,用时 {duration} 秒")cv2.imwrite(f"records/{cat_name}_leave_{int(exit_time)}.jpg", frame)cat_present = detectedcv2.imshow("Cat Monitor", frame)if cv2.waitKey(1) == 27:  # ESC 退出breakcap.release()
cv2.destroyAllWindows()

📦 依赖库列表:

  • ultralytics (YOLOv8/11)

  • torch, opencv-python, Pillow

  • scikit-learn(用于相似度计算)



✅ 下一步工作:

  1. 用 Flask 做个记录页面,展示:

    • 每次进入/离开的猫咪、时间、如厕时长

    • 保存的截图

  2. 加入状态日志系统(写入 SQLite)


✅ 读取视频流:
可以通过 OpenCV 直接读取 RTSP 流的视频画面,替换掉 cv2.VideoCapture(0) 这一行。


✅ RTSP 摄像头接入方式

假设你的摄像头地址是:

rtsp://192.168.0.102:554/stream1

常见格式有以下几种(具体看你的摄像头厂商手册):

格式类型示例 URL
无用户名密码rtsp://192.168.0.102:554/stream1
有用户名密码rtsp://admin:password@192.168.0.102:554/stream1

如果你不确定 RTSP 路径,可以用 VLC 打开地址测试能否连接。


✅ 替换代码中的摄像头源

# 本地摄像头写法
# cap = cv2.VideoCapture(0)# 替换为 RTSP 摄像头:
cap = cv2.VideoCapture("rtsp://192.168.0.102:554/stream1")

也可以设置超时时间(推荐):

cap.set(cv2.CAP_PROP_BUFFERSIZE, 1)

⚠️ 注意事项:

  1. 防火墙:确保你的电脑和摄像头在同一局域网,且摄像头开放了 RTSP 服务。

  2. 稳定性:RTSP 会有卡顿或断流情况,建议加重连逻辑(稍后我们可以加)。

  3. 帧率延迟:默认 RTSP 有延迟,可尝试减少缓冲提高实时性。


✅ 示例(完整替换一行即可)

cap = cv2.VideoCapture("rtsp://192.168.0.102:554/stream1")

模型使用:

现在没有收集足够多的猫咪图片,就先使用 YOLOv11 COCO 官方权重(基于 YOLOv8 推理架构),但是只想检测 cat 类别(class id = 15)。我们有两个解决方案:


✅ 方案一:在推理结果中筛选 cat 类别

这是最简单的方法,无需重新训练模型,只在代码里过滤掉非猫类目标。

✅ 修改你的检测代码:

results = model.predict(frame, verbose=False)
boxes = results[0].boxesfor box in boxes:cls = int(box.cls[0])conf = float(box.conf[0])if cls != 15:  # COCO 中 cat 是类别15continue# 保留 cat 类的后续逻辑...

你也可以打印类别名验证一下:

from ultralytics.utils import ops
print(ops.ANCHOR_ORDER)  # 也可以用 model.names[cls] 打印类别名

✅ 方案二:导出只含猫的 YOLOv11 模型(可选,后续更新)

如果你未来希望模型体积更小、推理更快:

  1. 用 COCO 数据集中只包含 cat 的部分训练模型(或 fine-tune)。

  2. 自定义 data.yaml:

names: ['cat']
nc: 1
  1. 训练模型:
yolo detect train data=cat.yaml model=yolov11.pt epochs=50 imgsz=640

然后就能得到一个“只识别猫”的轻量化模型了。


网络摄像头检测推理错误

[h264 @ 00000218ddca2b00] error while decoding MB 94 41, bytestream -5

表示 OpenCV(底层用 ffmpeg)在解析 RTSP 摄像头的视频流时,遇到了 H.264 视频帧解码错误。这种问题在使用 RTSP 摄像头时很常见,通常是由以下原因引起的:


❗ 常见原因分析:

1. 网络不稳定 / 丢帧

  • RTSP 是实时流协议,稍有波动就可能导致数据不完整。

  • 解码器(H.264)收到了不完整的数据,无法正确解码宏块(Macroblock)。

2. 摄像头编码质量太低 / 不兼容

  • 某些低端摄像头输出的 RTSP H.264 数据流存在兼容问题。

3. 缓冲区设置不当(OpenCV 默认大延迟)

  • OpenCV 默认有较大的缓冲,容易产生过时帧或卡顿,进而出错。

✅ 解决方案


✅ 方法 1:设置 OpenCV 缓冲区为 1(强烈推荐及采用)

cap = cv2.VideoCapture("rtsp://192.168.0.102:554/stream1")
cap.set(cv2.CAP_PROP_BUFFERSIZE, 1)

✅ 方法 2:改用 ffmpeg 直接拉流更稳定(通过 subprocessimageio

如果 OpenCV 解码不稳定,可以尝试用 ffmpeg 拉流 + pipe 给 Python 处理。


✅ 方法 3:尝试切换 RTSP 子码流(sub stream)

大多数摄像头有主码流(1080p)和子码流(D1 / CIF):

  • 主码流可能过大、丢帧严重

  • 可尝试地址类似:

    rtsp://192.168.0.102:554/sub
    rtsp://192.168.0.102:554/live/ch0_1  ← 子码流
    

✅ 方法 4:尝试加参数或禁用 HW 加速(ffmpeg flags)

可通过设置更强容错的方式读取(但这需要更底层控制)。


🧪 调试策略

import cv2rtsp_url = "rtsp://192.168.0.102:554/stream1"
cap = cv2.VideoCapture(rtsp_url)
cap.set(cv2.CAP_PROP_BUFFERSIZE, 1)if not cap.isOpened():print("❌ 无法连接摄像头")exit()while True:ret, frame = cap.read()if not ret:print("❌ 帧读取失败,跳过")continuecv2.imshow("RTSP", frame)if cv2.waitKey(1) == 27:break

✅ 总结建议:

方式说明
set(CAP_PROP_BUFFERSIZE, 1)✅ 首选,缓解延迟和丢帧问题
检查 RTSP 子码流地址可大幅提升兼容性
尝试更稳定解码方式(如 GStreamer)高级稳定需求下可选

cap.set(cv2.CAP_PROP_BUFFERSIZE, 1)
可以先加上上述代码试试是否缓解问题。如果问题仍然频繁,我们可以换 ffmpegGStreamer 拉流方式,我也可以帮你整合好。

窗口尺寸调整:

好的,如果用 OpenCVcv2.imshow() 来显示摄像头窗口,可以通过 缩放帧的尺寸 来控制窗口大小。


✅ 方法:缩放图像再显示

在你显示前加一行缩放代码,比如缩放为 640x480:

# 假设 frame 是读取的图像
resized_frame = cv2.resize(frame, (640, 480))  # 你也可以用 (960, 720) 或其他分辨率
cv2.imshow("Cat Monitor", resized_frame)

✅ 推荐方式(根据原图比例缩小)

如果你想“等比例缩放”,比如缩小为原来的 0.5 倍:

scale = 0.5
h, w = frame.shape[:2]
resized_frame = cv2.resize(frame, (int(w * scale), int(h * scale)))
cv2.imshow("Cat Monitor", resized_frame)

✅ 如果你想让窗口是“可拉伸的”

还可以配合 cv2.namedWindow 控制窗口样式:

cv2.namedWindow("Cat Monitor", cv2.WINDOW_NORMAL)
cv2.resizeWindow("Cat Monitor", 640, 480)

这允许你手动调整窗口大小。


✅ 已完成模块回顾

模块状态说明
猫咪录入支持多张猫脸图批量上传、特征提取和保存
猫咪识别最近邻相似度匹配分类
YOLOv11 + 摄像头实时检测猫是否进入区域并识别是哪只猫
区域判断判断猫是否进入指定如厕区域
RTSP 支持已支持 RTSP 摄像头接入(192.168.0.102)
窗口缩放图像缩放显示已支持

✅ 运行说明

cd cat_monitor/web
python app.py
  1. 浏览器访问:
http://127.0.0.1:5000/

✅ 已完成模块回顾

模块状态说明
猫咪录入支持多张猫脸图批量上传、特征提取和保存
猫咪识别最近邻相似度匹配分类
YOLOv11 + 摄像头实时检测猫是否进入区域并识别是哪只猫
区域判断判断猫是否进入指定如厕区域
RTSP 支持已支持 RTSP 摄像头接入(192.168.0.102)
窗口缩放图像缩放显示已支持

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/76894.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2025年燃气证书:传承与发展的行业纽带

回溯历史长河&#xff0c;能源的利用与人类文明的发展息息相关。从远古时期的钻木取火&#xff0c;到如今广泛应用的燃气能源&#xff0c;每一次能源的变革都推动着社会的巨大进步。而在现代燃气行业蓬勃发展的背后&#xff0c;燃气从业人员资格证书正扮演着传承与发展的重要纽…

在Ubuntu下进行单片机开发是否需要关闭Secure Boot

1. Secure Boot的作用 功能&#xff1a;Secure Boot是UEFI的安全功能&#xff0c;旨在阻止未经验证的驱动或操作系统启动&#xff0c;防止恶意软件篡改引导过程。 影响范围&#xff1a;它主要限制的是操作系统启动阶段加载的内核级驱动&#xff08;如显卡驱动、虚拟化模块&…

国达陶瓷重磅推出陶瓷罗马柱外墙整装尖端新产品“冠岩臻石”

近日&#xff0c;记者在佛山国达建材有限公司&#xff08;以下简称国达陶瓷&#xff09;董事长杨建平处了解到&#xff0c;该公司重磅推出的“冠岩臻石”新产品&#xff0c;是属于陶瓷罗马柱外墙整装产品中的尖端产品。新产品自面市之后&#xff0c;深受高端用户的青睐与认可。…

【分享】Ftrans文件摆渡系统:既保障传输安全,又提供强集成支持

【分享】Ftrans文件摆渡系统&#xff1a;既保障传输安全&#xff0c;又提供强集成支持&#xff01; 在数字化浪潮中&#xff0c;企业对数据安全愈发重视&#xff0c;网络隔离成为保护核心数据的关键防线&#xff0c;比如隔离成研发网-办公网、生产网-测试网、内网-外网等。网络…

实验一 字符串匹配实验

一、实验目的 1&#xff0e;熟悉汇编语言编程环境和DEBUG调试程序的使用。 2&#xff0e;掌握键盘输入字符串的方法和分支程序的设计。 二、实验内容 编程实现&#xff1a;从键盘分别输入两个字符串&#xff0c;然后进行比较&#xff0c;若两个字符串的长度…

添加登录和注册功能

先写前端再写后端 前提&#xff1a;ideavue3mybatisspringBoot3前后端分离实现对一张表的增删改查&#xff08;完整代码版&#xff09;-CSDN博客 项目地址 1.添加一个Login.vue视图 <template><div class"login_container"><div class"login…

【Windows】系统安全移除移动存储设备指南:告别「设备被占用」弹窗

Windows系统安全移除移动存储设备指南&#xff1a;告别「设备被占用」弹窗 解决移动硬盘和U盘正在被占用无法弹出 一、问题背景 使用Windows系统时&#xff0c;经常遇到移动硬盘/U盘弹出失败提示「设备正在使用中」&#xff0c;即使已关闭所有可见程序。本文将系统梳理已验证…

Springboot下载文件, 文件名中文是乱码, 空格变加号

默认把文件名放上去, 中文会乱码, 文件名种有空格, 就会被截断 public void download(HttpServletResponse response){// 文件名先进行url编码, 避免乱码问题// 把用%20进行替换fileName URLEncoder.encode(fileName, "UTF-8").replace("", "%20&qu…

MySQL 超详细安装教程与常见问题解决方案

一、MySQL 安装教程 1. Windows 系统安装&#xff08;以 MySQL 8.0 为例&#xff09; 步骤 1&#xff1a;下载 MySQL Installer 访问 MySQL 官网下载页面。 选择 Windows (x86, 64-bit), MSI Installer&#xff08;推荐使用完整版 mysql-installer-web-community-8.0.xx.xx.…

【cuda学习日记】5.2.1 共享内存额外篇

共享内存(Shared Memory) 1.是一种低延迟、高带宽的片上内存 2.由同一个Block内的所有线程共享 3.生命周期与Block相同 4.访问速度比全局内存快约100倍 Block(线程块) 1.GPU执行的基本单位&#xff0c;包含一组线程 2.多个Block组成Grid(网格) 3.Block内的线程可以通过共享内存…

[250411] Meta 发布 Llama 4 系列 AI 模型 | Rust 1.86 引入重大语言特性

目录 Llama 4 家族登场&#xff1a;开启原生多模态 AI 创新新纪元Rust 1.86.0 版本发布亮点主要新特性与改进其他重要信息 Llama 4 家族登场&#xff1a;开启原生多模态 AI 创新新纪元 Meta AI 近日发布了其最新、最先进的 Llama 4 系列人工智能模型&#xff0c;标志着 AI 技术…

ArrayList 和 数组 的区别

定义与本质 数组&#xff1a;是 Java 语言内置的数据结构&#xff0c;是存储相同类型元素的连续内存空间。它是一个基本的语言特性&#xff0c;在内存中是一块连续的区域。ArrayList&#xff1a;是 Java 集合框架中的一个类&#xff0c;属于动态数组。它是基于数组实现的&#…

​‌FireCrawl‌爬虫工具​, Craw4ai

‌FireCrawl‌是一款开源的AI爬虫工具&#xff0c;专门用于Web数据提取&#xff0c;并将其转换为Markdown格式或其他结构化数据。FireCrawl特别适合处理使用JavaScript动态生成的网站&#xff0c;能够自动抓取网站及其所有可访问的子页面内容&#xff0c;并将其转换为适合大语言…

通信原理-非线性调制

今天给大家带来的是关于通信原理中非线性调制的内容,一起来看看吧&#xff01;&#xff01;&#xff01; 1.角度调制 2.FM与PM的区别 3.单音调制FM 4.窄带调频 5.宽带调频 5.1FM信号的频谱 5.2FM信号的带宽 5.3FM信号的功率分配 6.FM信号的产生与解调 6.1FM信号的产生 6.2FM…

文心一言开发指南03——千帆大模型平台产品优势

版权声明 本文原创作者&#xff1a;谷哥的小弟作者博客地址&#xff1a;http://blog.csdn.net/lfdfhl 千帆大模型平台作为百度智能云推出的企业级大模型一站式平台&#xff0c;具有显著的产品优势。千帆大模型平台以其基础强大、流程完善、运行稳定和安全可靠的产品优势成为企…

mysql DQL

一.基本查询 1.查询多个字段 2.查看所有字段 3.设置别名 4.去除重复记录 二.条件查询 1.大于小于等于 2.查询 身份证为空的 没有所以没有记录 3.在15到20这个区间范围内 4.or/in 或者 4.like 匹配 &#xff08;_匹配单个字符 %匹配多个字符&#xff09; 查询员工信…

关于 软件开发模型 的分类、核心特点及详细对比分析,涵盖传统模型、迭代模型、敏捷模型等主流类型

以下是关于 软件开发模型 的分类、核心特点及详细对比分析&#xff0c;涵盖传统模型、迭代模型、敏捷模型等主流类型&#xff1a; 一、软件开发模型分类及核心特点 1. 瀑布模型&#xff08;Waterfall Model&#xff09; 核心特点&#xff1a; 线性阶段划分&#xff1a;需求分…

2025年第十六届蓝桥杯省赛C++ A组真题

2025年第十六届蓝桥杯省赛C A组真题 1.说明2.题目A&#xff1a;寻找质数&#xff08;5分&#xff09;3.题目B&#xff1a;黑白棋&#xff08;5分&#xff09;4. 题目C&#xff1a;抽奖&#xff08;10分&#xff09;5. 题目D&#xff1a;红黑树&#xff08;10分&#xff09;6. 题…

JVM初探——走进类加载机制|三大特性 | 打破双亲委派SPI机制详解

目录 JVM是什么&#xff1f; 类加载机制 Class装载到JVM的过程 装载&#xff08;load&#xff09;——查找和导入class文件 链接&#xff08;link&#xff09;——验证、准备、解析 验证&#xff08;verify&#xff09;——保证加载类的正确性 准备&#xff08;Prepare&…