如何以低成本实现智能家庭:利用摄像头做人体存在感应并接入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
实施前提
官方文档中对于硬件的要求有非常详细的说明,主要分为摄像头、服务器和探测器三个部分,以下是简单说明:
- 摄像头:任何支持获取 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 及更详细的使用方法将会在后续文章中进行深入探讨,敬请期待。