利用摄像头实现人体存在感应,并接入Home Assistant (一)

利用摄像头实现人体存在感应,并接入Home Assistant (一)

编码文章call10242025-01-16 10:14:5115A+A-

在构建智能家庭时,最为核心的就是“人”与“物”的联动。

想象这样一个场景:你结束了忙碌一天的工作,在归途中,你的热水器已经开始工作,为你预热沐浴水。当你踏入家门,灯光渐渐亮起,迎接你的归来,空调调至了你最喜爱的温度,而背景音乐播放着轻快的旋律,为你驱散一天的疲惫。这一切都无需你操心,因为你的智能家居系统已经默默为你打理好了。

在打造这种自动化的生活方式时,“人”的角色至关重要。绝大多数自动化操作都是以人的活动为中心,比如检测到有人回家时应该采取的动作,或者人进入某个房间时自动开启灯光等等。

因此,如何稳定并精准地监测人的活动,一直是智能家居领域探讨的热门话题。从早些年的热释电人体感应器到现在层出不穷的毫米波雷达,都离不开对人的监测。

由于大多数家庭都会安装摄像头,那么这个摄像头是否能充当人体传感器,物尽其用实现人体的监测呢?

深入了解摄像头提供商就能发现,大多数的厂家都支持移动侦测,也就是当摄像头画面变化时我们能收到通知。

但是画面的变化包含了所有元素的变化,包括猫、狗、窗帘或人等,厂商并不会提供免费的识别服务给用户,更重要的是无法实现和已有智能设备的联动。

那摄像头到底能否充当传感器实现和智能设备的联动呢?

这就是今天要讨论的方案:Frigate。

通过 Frigate 不仅能帮我们实现摄像头物体的移动和区分,还能对识别到的对象(猫、狗、人)进行视频录制,更重要的是它可以和 Home Assistant 进行通信。

Frigate

Frigate 是一款专为 Home Assistant 设计的完整本地 NVR(网络视频录像机),具有 AI 物体检测功能。

它的原理是使用 OpenCV 和 Tensorflow 对本地 IP 摄像头进行实时物体检测,再通过 MQTT 与其他系统进行通信。

想必大家对 Home Assistant 就非常熟悉了,简单来说只要能接入 Home Assistant 就能实现智能设备联动。Frigate 同时提供了插件便于我们在 Home Assistant 中获取到 Frigate 发送的事件。

项目地址:https://github.com/blakeblackshear/frigate

文档地址:https://docs.frigate.video

前提

官方文档对硬件有非常详细的说明,可以分为摄像头、服务器、探测器三部分,这里只进行简单说明:

  • 摄像头:只要能获取rtsp流的摄像头都可以,推荐海康威视、大华
  • 服务器:搭建 Frigate 的主机,家里的 NAS 能满足需求
  • 探测器:运行推理以检测物体的设备,包括 Google Coral TPU、OpenVINO、TensorRT,如果都没有则会调用 CPU 进行推理。

Google Coral TPU

这是一款独立的硬件,一般需要海淘,Google Coral 也是最推荐的探测器,通过它能在画面物体识别和推理上达到最快响应。

ps:如果推理延时很高,那么识别人或物的时间就会很长,在自动化场景中设备联动就失去了意义(人都走过了才开灯?!)

Google Coral TPU

OpenVINO

OpenVINO 类型的检测器可以使用下面的平台直接运行,不需要额外的设备,推理速度较慢:

  • 第六代及更新的英特尔平台,均配备集成显卡
  • 具有 VPU 硬件的 x86 和 Arm64 主机(例如:Intel NCS2)
  • 大多数现代 AMD 处理器

TensorRT - Nvidia GPU

TensortRT 检测器,也就是需要 Nvidia 显卡。一般用于在台式机调用显卡进行测试。

搭建

Frigate 是一套独立的系统,所以我们使用官方推荐的 Docker 方式进行安装。

演示环境:

  • 摄像头:海康威视
  • 服务器:群晖DS218+
  • 探测器:群晖DS218+ (Celeron J3355,支持核显)

获取RTSP流

首先需要开启ONVIF,才能获取RTSP流,海康威视可以参考老宁以前写的文章。

是否需要一个摄像头?摄像头与群晖优雅的结合

RTSP单播取流格式如下: rtsp://用户名:密码@IP:554/Streaming/Channels/101

主码流的URL: rtsp://admin:123456@192.168.2.64:554/Streaming/Channels/101

子码流的URL: rtsp://admin:123456@192.168.2.64:554/Streaming/Channels/102

在 Frigate 中我们使用流主要用以物体的识别,不需要很高的分辨率,所以在摄像头管理界面中可以把子码流设置为较低的分辨率用以推理,而主码流更清晰可以用来保存视频。

配置文件

如果没有 mqtt 服务器则需自行搭建,搭建完毕后填入 mqtt 服务器的地址、用户、密码。

如果你也是利用核显加速,那么可以直接复制以下配置文件,同时修改 xxx 为自己的内容,再根据自己摄像头按需修改 detect 配置下的width(宽)、height(高)等相关属性。

detectors:
  ov:
    type: openvino  # openVINO检测器。如果你没有GPU或Edge TPU硬件,使用OpenVINO检测器比使用CPU检测器更高效。
    device: AUTO
    model:
      path: /openvino-model/ssdlite_mobilenet_v2.xml

model:  # 使用OpenVINO探测器与默认模型,使用以下模型配置
  width: 300
  height: 300
  input_tensor: nhwc
  input_pixel_format: bgr
  labelmap_path: /openvino-model/coco_91cl_bkgr.txt

ffmpeg:
  hwaccel_args: preset-vaapi  #硬件加速预设
# mqtt,必须
mqtt:
  # mqtt的服务地址
  host: xxx
  # mqtt的用户
  user: xxx
  # mqtt的密码
  password: xxx
  # 如果有多个mqtt实例这里要设置
  # topic_prefix: xxx
  # 如果有多个mqtt实例这里要设置
  # client_id: xxx
# 可选配置,有好处,https://docs.frigate.video/guides/configuring_go2rtc
go2rtc:
  streams:
    outdoor_rtsp_cam:
      - "rtsp://admin:xxx@192.168.xxx.xxx:554/Streaming/Channels/101"
    outdoor_rtsp_cam_sub:
      - "rtsp://admin:xxx@192.168.xxx.xxx:554/Streaming/Channels/102"
    indoor_rtsp_cam:
      - "rtsp://admin:xxx@192.168.xxx.xxx:554/Streaming/Channels/101"
    indoor_rtsp_cam_sub:
      - "rtsp://admin:xxx@192.168.xxx.xxx:554/Streaming/Channels/102"
# 摄像头接入
cameras:
  # 摄像头名称,自定义
  out_door:
    ffmpeg:
      inputs:
        # 摄像头地址
        - path: rtsp://127.0.0.1:8554/outdoor_rtsp_cam
          input_args: preset-rtsp-restream
          # 要开启的功能,record:录像,detect:画面监测,audio:音频监测
          roles:
            # 录像功能
            - record
        - path: rtsp://127.0.0.1:8554/outdoor_rtsp_cam_sub
          input_args: preset-rtsp-restream
          roles:
            # 识别功能
            - detect
    detect:
      # 识别检测
      enabled: True
      # 摄像头画面的分辨率
      width: 640
      height: 480
      fps: 5
      max_disappeared: 25  # 物体消失之前未检测到的帧数
    motion:
      threshold: 15
      mask:
        - 222,23,0,22,0,0,226,0
      mqtt_off_delay: 5
    # 区域,先不设置
    zones:
      out_door_fall:
        coordinates: 384,61,482,245,235,244,239,55
      out_door_arround:
        coordinates: 213,480,640,480,522,198,228,199,185,338
    record:
      # 是否开启
      enabled: True
      events:
        # 拍摄前3秒
        pre_capture: 3
        #拍摄后5秒
        post_capture: 5
        retain:
          # 保留录像天数
          default: 5
          # 特定的物体保留天数
          objects:
            person: 10
    # 快照
    snapshots:
      enabled: True
      # 在快照上打印时间戳 默认False
      timestamp: False
      # 在快照上绘制边界框 默认False
      bounding_box: True
      # 裁剪快照 默认False
      crop: False
      # 将快照大小调整为的高度(默认值:原始大小)
      #height: 175
      retain:
        # 默认保留天数(默认值:如下所示)
        default: 10
        # 每个对象的保留天数
        objects:
          person: 15  # 如果是人就保存15天
    objects:
      # 选择需要识别的物体,https://docs.frigate.video/configuration/objects
      track:
        - person
        - bicycle
        - motorcycle
        - cat
        - dog
      # 定制过滤器减少误报
      filters:
        person:
          # 检测到的对象的边框的最小面积,宽度*高度(默认:0)
          #min_area: 0
          # 检测到的对象的边框的最大面积,宽度*高度 (默认: 24000000)
          #max_area: 100000
          # 启动跟踪的对象的最低分数 (默认: 0.5)
          min_score: 0.3
          # 将被跟踪对象的计算分数的最小十进制百分比视为真实正值 
          threshold: 0.5
  in_door:
    ffmpeg:
      inputs:
        # 摄像头地址
        - path: rtsp://127.0.0.1:8554/indoor_rtsp_cam
          input_args: preset-rtsp-restream
          roles:
            # 录像功能
            - record
        - path: rtsp://127.0.0.1:8554/indoor_rtsp_cam_sub
          input_args: preset-rtsp-restream
          roles:
            # 识别功能
            - detect
    detect:
      # 开启识别
      enabled: True
      # 摄像头画面的分辨率
      width: 1280
      height: 720
      fps: 10
      max_disappeared: 50 # 物体消失之前未检测到的帧数
    motion:
      threshold: 25
      mask:
        - 437,0,435,39,0,31,0,0
      mqtt_off_delay: 5
    zones:
      in_door_arround:
        coordinates: 688,415,888,479,1030,540,1200,366,1022,309,856,203,698,38,463,164,598,313
        objects:
          - person
      stairs:
        coordinates: 154,667,321,638,413,615,514,590,572,574,651,558,715,510,811,485,994,565,1027,597,863,720,0,720,0,685
        objects:
          - person
    record:
      # 是否开启
      enabled: True
      events:
        # 拍摄前3秒
        pre_capture: 3
        #拍摄后5秒
        post_capture: 5
        retain:
          # 保留录像天数
          default: 5
          # 特定的物体保留天数
          objects:
            person: 10
    # 快照
    snapshots:
      enabled: True
      # 在快照上打印时间戳 默认False
      timestamp: False
      # 在快照上绘制边界框 默认False
      bounding_box: True
      # 裁剪快照 默认False
      crop: False
      # 将快照大小调整为的高度(默认值:原始大小)
      #height: 175
      retain:
        # 默认保留天数(默认值:如下所示)
        default: 10
        # 每个对象的保留天数
        objects:
          person: 15
    objects:
      # 选择需要识别的物体
      track:
        - person
        - bicycle
        - motorcycle
      # 定制过滤器减少误报
      filters:
        person:
          # 检测到的对象的边框的最小面积,宽度*高度(默认:0)
          #min_area: 0
          # 检测到的对象的边框的最大面积,宽度*高度 (默认: 24000000)
          #max_area: 100000
          # 启动跟踪的对象的最低分数 (默认: 0.5)
          min_score: 0.6
          # 将被跟踪对象的计算分数的最小十进制百分比视为真实正值 (默认: shown below)
          threshold: 0.7

配置文件的简单说明:

  • 该文件配置了两个摄像头:out_door、in_door
  • 码流分别为:outdoor_rtsp_cam、outdoor_rtsp_cam_sub、indoor_rtsp_cam、indoor_rtsp_cam_sub
  • ffmpeg 主码流用来存储视频,子码流用来检测物体
  • detect 代表识别(推理),需要指定摄像头分辨率
  • motion 下为移动监听的配置
  • record 录像相关配置
  • snapshots 快照相关配置
  • zones 制定一个或多个特定的区域
  • objects 设置监测的对象
  • 完整配置可参考官方文档 https://docs.frigate.video/configuration/reference

最后把修改后的配置另存为 config.yml 文件。

群晖演示

下面通过群晖演示具体的搭建步骤。

打开群晖 File Station 套件,在 test 文件夹中创建 frigate 文件夹,再在 frigate 文件夹创建 config、storage文件夹。并把前面修改完成的 config.yml 配置文件上传到 config 文件夹下。

在 Container Manager 套件中新建一个项目,复制下面的配置粘贴到来源输入框中。注意 /volume1/test/frigate/config 、/volume1/test/frigate/storage 路径要修改为你所创建的文件夹路径。

version: "3.9"
services:
  frigate:
    container_name: frigate
    privileged: true # 允许容器拥有几乎与宿主机相同的权限
    restart: unless-stopped
    image: ghcr.io/blakeblackshear/frigate:stable
    shm_size: "64mb" # 共享内存的大小,两个摄像头720p,64M够用,可以查看文档进行计算
    devices:
      - /dev/dri/renderD128:/dev/dri/renderD128 # 加载驱动调用核显,这里可以根据你的探测器进行修改
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - /volume1/test/frigate/config:/config  # 路径要修改
      - /volume1/test/frigate/storage:/media/frigate  # 路径要修改
      - type: tmpfs # Optional: 1GB of memory, reduces SSD/SD Card wear
        target: /tmp/cache
        tmpfs:
          size: 1000000000
    ports:
      - "8000:5000"  # 5000端口被占用,这里设置为8000
      - "8554:8554" # RTSP feeds
      - "8555:8555/tcp" # WebRTC over tcp
      - "8555:8555/udp" # WebRTC over udp
    environment:
      FRIGATE_RTSP_PASSWORD: "password"

设置项目名称,并选择 frigate 文件夹为保存 docker-compose.yml 的文件夹。

可以右键点击属性查看文件夹路径。

确认配置无误后,点击右下角下一步,等待 frigate 项目启动完毕。

通过群晖IP:8000能访问 frigate 主界面则表示配置成功。

界面

可以在 Events 中查看识别的物体。

打开 system 选项,发现核显并没有加载成功,那么则会使用 CPU 进行推理。

可以在 Config 菜单中直接修改配置文件,便于调试。

后记

由于 Frigate 本身非常复杂,所以这篇文章只介绍了初步配置和搭建过程,至于接入 Home Assistant 及更详细的使用会在后面的文章中给大家详细介绍,敬请期待。

我是老宁

一个热爱技术的程序员和极客,群晖NAS深度玩家!

专注NAS相关技术分享,原创!干货!

觉得老宁的文章对你有帮助,记得点赞、收藏、加关注

点击这里复制本文地址 以上内容由文彬编程网整理呈现,请务必在转载分享时注明本文地址!如对内容有疑问,请联系我们,谢谢!
qrcode

文彬编程网 © All Rights Reserved.  蜀ICP备2024111239号-4