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


✅ 前情提要


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

已完成工作:

猫咪如厕检测与分类识别系统系列【一】 功能需求分析及猫咪分类特征提取

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

计划工作:

✅ 猫咪管理功能:已完成猫咪照片上传与名称登记模块。

✅ 多图上传与分类特征提取:已支持批量上传猫咪图像并自动更新个体特征库。

🔄 目标检测与事件识别集成(YOLOv11):功能开发中,正在实现猫咪行为自动识别。

⏳ 检测区域绘制功能:待开发,计划支持用户自定义如厕检测区域。

⏳ 事件行为记录模块:待完善,将实现如厕进出时间、停留时长等事件记录功能。

⏳ 检测结果推流展示:待更新,计划支持算法结果实时推流。

⏳ 整体运行结果推流整合:待更新,计划集成检测图像与系统状态为统一视频流输出。



本次将继续制作 实时检测模块

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


✅ 功能目标:

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

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

python 复制代码
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_REGION
    cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 255, 255), 2)

    # YOLOv11 推理
    results = model.predict(frame, verbose=False)
    boxes = results[0].boxes
    detected = False
    cat_name = "Unknown"

    for box in boxes:
        cls = int(box.cls[0])
        conf = float(box.conf[0])
        if cls != 0:  # 类别为猫(根据你的模型调整)
            continue
        xmin, 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 = True
            cat_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 = detected

    cv2.imshow("Cat Monitor", frame)
    if cv2.waitKey(1) == 27:  # ESC 退出
        break

cap.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:[email protected]:554/stream1

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


✅ 替换代码中的摄像头源

python 复制代码
# 本地摄像头写法
# cap = cv2.VideoCapture(0)

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

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

python 复制代码
cap.set(cv2.CAP_PROP_BUFFERSIZE, 1)

⚠️ 注意事项:

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

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

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


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

python 复制代码
cap = cv2.VideoCapture("rtsp://192.168.0.102:554/stream1")

模型使用:

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


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

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

✅ 修改你的检测代码:

python 复制代码
results = model.predict(frame, verbose=False)
boxes = results[0].boxes

for box in boxes:
    cls = int(box.cls[0])
    conf = float(box.conf[0])
    if cls != 15:  # COCO 中 cat 是类别15
        continue
    # 保留 cat 类的后续逻辑...

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

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

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

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

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

  2. 自定义 data.yaml:

yaml 复制代码
names: ['cat']
nc: 1
  1. 训练模型:
bash 复制代码
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(强烈推荐及采用)

python 复制代码
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)

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


🧪 调试策略

python 复制代码
import cv2

rtsp_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("❌ 帧读取失败,跳过")
        continue
    cv2.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:

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

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

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

python 复制代码
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 控制窗口样式:

python 复制代码
cv2.namedWindow("Cat Monitor", cv2.WINDOW_NORMAL)
cv2.resizeWindow("Cat Monitor", 640, 480)

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


✅ 已完成模块回顾

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

✅ 运行说明

bash 复制代码
cd cat_monitor/web
python app.py
  1. 浏览器访问:

    http://127.0.0.1:5000/


✅ 已完成模块回顾

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

相关推荐
QuZhengRong12 分钟前
【AI】免费GPU算力平台部署wan2.1
人工智能·腾讯云·视频
coderxiaohan18 分钟前
torch.cat和torch.stack的区别
人工智能·pytorch·深度学习
川泽曦星25 分钟前
【第四十周】文献阅读:用于检索-增强大语言模型的查询与重写
人工智能·语言模型·自然语言处理
向哆哆35 分钟前
BiFPN与RepViT协同机制在YOLOv8目标检测中的应用与优化
人工智能·深度学习·yolo·目标检测·yolov8
意.远38 分钟前
使用PyTorch实现目标检测边界框转换与可视化
人工智能·pytorch·python·深度学习·神经网络·目标检测
我感觉。40 分钟前
【李宏毅深度学习——回归模型的PyTorch架构】Homework 1:COVID-19 Cases Prediction (Regression)
人工智能·深度学习
扉间79842 分钟前
《基于 RNN 的股票预测模型代码优化:从重塑到直接可视化》
人工智能·rnn·深度学习
whoisi22221 小时前
用Trae做一个Roguelike爬塔游戏
人工智能·ai编程·trae
whoisi22221 小时前
用Cursor 做一个ARPG游戏
人工智能·ai编程·cursor
_一条咸鱼_1 小时前
大厂AI大模型面试:ChatGPT 训练原理
人工智能·深度学习·面试