如何以低成本实现智能家庭:利用摄像头做人体存在感应并接入Home Assistant的完整指南

在构建智能家庭系统时,"人"与"物"之间的互动是最为关键的元素。

设想一下这样的场景:您结束了一天的繁忙工作,正踏上回家的路。与此同时,热水器已经开始预热沐浴水。当您走进家门时,灯光渐渐亮起,空调调至您最喜欢的温度,背景音乐轻快地播放着,瞬间驱散了您一天的疲惫。这一切都是由您的智能家居系统在为您默默准备,您无需操心。

在实现这种自动化生活的过程中,“人”的角色尤为重要。几乎所有的自动化操作都是围绕人的活动展开的,例如在检测到有人回家时采取相应措施,或在人进入某个房间时自动开启灯光等。

因此,如何稳定并准确地监测人的活动,一直以来都是智能家居领域的热门话题。自早期的热释电人体感应器到如今层出不穷的毫米波雷达,监测人的活动始终是技术发展的核心。

图片大多数家庭通常会安装摄像头,是否可以利用现有的摄像头作为人体传感器,充分发挥其监测功能呢?

深入了解摄像头制造商后会发现,大部分厂家支持移动侦测功能,即在摄像头画面发生变化时可以触发通知。

然而,画面的变化可能包括人、宠物、窗帘等多个元素,因此大多数厂商并未提供免费的识别服务,并且无法实现与已有智能家居设备的联动。

那么,摄像头能否作为传感器来实现与智能设备的联动呢?今天我们将讨论的解决方案正是 Frigate。

图片通过 Frigate,我们不仅可以实现对摄像头画面中物体的移动与区分,还能够对识别到的对象(如猫、狗、人)进行视频录制,更为重要的是,它能够与 Home Assistant 进行有效的通信。

Frigate简介

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

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

大家应该对 Home Assistant 非常熟悉,简而言之,只要能够接入 Home Assistant,就能实现智能设备的联动。Frigate 同时提供了插件,使我们能够在 Home Assistant 中接收来自 Frigate 的事件。

图片项目地址:Frigate GitHub

文档地址:Frigate Documentation

实施前提

官方文档中对于硬件的要求有非常详细的说明,主要分为摄像头、服务器和探测器三个部分,以下是简单说明:

  • 摄像头:任何支持获取 RTSP 流的摄像头均可,推荐品牌如海康威视、大华等。
  • 服务器:搭建 Frigate 的主机,家庭的 NAS 通常能够满足需求。
  • 探测器用于运行推理以检测物体的设备,包括 Google Coral TPU、OpenVINO、TensorRT,若没有以上设备则会调用 CPU 进行推理。

Google Coral TPU

Google Coral TPU 是一款独立硬件,一般需要海外购买,推荐使用 Google Coral 作为探测器,因为其在物体识别和推理方面的响应速度最快。

备注:推理延迟过高,会导致识别对象的时间变长,从而在自动化场景中失去意义(例如,人在走过后才开灯?)。

🔻 Google Coral TPU 图片

OpenVINO

OpenVINO 类型的探测器可以直接在以下平台运行,而无需额外设备,但推理速度较慢:

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

图片

TensorRT - Nvidia GPU

TensorRT 探测器是需要 Nvidia 显卡的,通常用于在台式机上调用显卡进行测试。

图片

系统搭建

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

获取RTSP流

首先,需要启用 ONVIF,才能获取 RTSP 流。对于海康威视设备,可以参考之前的相关文章。

ONVIF

他们都叫我老宁,公众号:他们都叫我老宁是否需要一个摄像头?摄像头与群晖优雅的结合

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 检测器较为高效。  
    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  
          # 将被跟踪对象的分数的最小百分比视为真实正值(默认如下)  
          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 设置监测的对象。
  • 完整配置可参考官方文档:Frigate 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  # 可选:1GB 内存,减少 SSD/SD 卡磨损  
        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 及更详细的使用方法将会在后续文章中进行深入探讨,敬请期待。