设备:
①一台旧游戏本(I5-7300HQ + 1050Ti + DDR4 16Gb+ 128GbM.2固态)
②3个支持onvif的监控摄像头(2个TP-LINK IPC45AW-PLUS、1个萤石C6c 3K版)
插句题外话,个人觉得TP-LINK的摄像头比萤石的好使。
功能:共三个步骤,按需操作即可(如不需要实现③,则可以跳过)
①使用frigate进行监控录制
②捕捉识别到猫咪的片段
③转发至微信群(虚拟机python实现,我这里由于旧笔记本配置有限,因此这部分功能是在我的NAS虚拟机实现的。如果你的设备配置有富裕,完全可以在同一个设备中进行实现。)
具体步骤:
一、使用frigate进行监控录制
0.安装Docker,这部分教程非常多,我就不赘述了
1.安装NVIDIA Container Toolkit(此处参考了 https://www.cnblogs.com/li508q/p/18444582,感谢原博主)
①首先,添加 NVIDIA Container Toolkit 的仓库密钥和源列表:
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg \
&& curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \
sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | \
sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list
②更新系统包列表,然后安装 NVIDIA Container Toolkit:
sudo apt-get update
sudo apt-get install -y nvidia-container-toolkit
③安装完成后,必须重启 Docker 服务以使更改生效:
sudo systemctl restart docker
④执行以下命令以验证 NVIDIA Container Toolkit 是否正确安装:
nvidia-container-cli --version
⑤还可以通过以下命令确认Docker是否能访问GPU:
如果成功显示 GPU 信息,说明 NVIDIA Container Toolkit 已正确安装。
docker run --rm --gpus all nvidia/cuda:12.0-base nvidia-smi
2.安装frigate
①在指定位置创建一个文件夹用于存放相关文件,例如/home/xxxx/frigate
mkdir -p /home/xxxx/frigate
cd /home/xxxx/frigate
②创建docker-compose.yml文件,并复制以下配置文本
nano docker-compose.yml
version: "3.9"
services:
frigate:
environment:
- YOLO_MODELS=yolov7-320 # 可以使用别的型号,具体见后表。这里推荐yolov7-320,更好的配置可以使用yolov7-640
container_name: frigate # 容器名称,填frigate即可
privileged: true # 超级权限,默认即可
restart: unless-stopped # 重启设置
image: ghcr.io/blakeblackshear/frigate:stable-tensorrt #这里一定要用tensorrt的版本才支持NVIDIA GPU
deploy: # 这部分是设置NVIDIA GPU,必需填写
resources:
reservations:
devices:
- driver: nvidia
device_ids: ['0'] # 如果有多个GPU,这里可以选择用哪一个
capabilities: [gpu]
shm_size: "256mb" # 共享内存大小,可以填大一点
devices:
- /dev/dri/renderD128:/dev/dri/renderD128 # 默认
volumes:
- /etc/localtime:/etc/localtime:ro
- ./config:/config # frigate生成的配置文件存放位置
- ./storage:/media/frigate # frigate生成的录像保存位置,可以自定义
- type: tmpfs
target: /tmp/cache
tmpfs:
size: 1000000000 # 这里存储空间是1G,可以适量调大
ports: # 下列端口若被占用,则自行更改即可
- "8971:8971"
- "5555:5000" # frigate的后台UI界面端口,请把5555修改为你当前未占用的端口即可
- "8554:8554" # RTSP feeds流的端口
- "8555:8555/tcp" # WebRTC over tcp端口
- "8555:8555/udp" # WebRTC over udp端口
可用的yolo模型如下,根据自己的设备算力选择(目前没找到相关的表格来查比如哪些模型支持哪些显卡,先使用yolo7-320先试着):
yolov3-288
yolov3-416
yolov3-608
yolov3-spp-288
yolov3-spp-416
yolov3-spp-608
yolov3-tiny-288
yolov3-tiny-416
yolov4-288
yolov4-416
yolov4-608
yolov4-csp-256
yolov4-csp-512
yolov4-p5-448
yolov4-p5-896
yolov4-tiny-288
yolov4-tiny-416
yolov4x-mish-320
yolov4x-mish-640
yolov7-tiny-288
yolov7-tiny-416
yolov7-640
yolov7-320
yolov7x-640
yolov7x-320
③使刚刚编辑好的docker-compose文件进行安装:
sudo docker compose up -d
注:安装过程会自动下载和编译yolo文件,需要较长时间。如果一直卡着不动,可以kill掉以后重新执行这条命令,直到后台端口xxx.xxx.xxx.xxx:5555能打开。
④打开后台端口:此时frigate已经安装完毕,但需要在端口中修改配置文件config才能实现摄像头的连接和后续功能。
xxx.xxx.xxx.xxx:5555
注:这里的5555端口可以在第②部的docker-compose文件中修改成任意没有被占用的端口即可
⑤在frigate中修改配置文件(也可以在命令行中使用nano/vim修改)
填写下列配置文件(这个版本的配置文件仅使用GPU转码实现录制功能,会流畅很多且减少CPU占用,如要实现目标识别请跳转至下一部分“二、捕捉识别到猫咪的片段”)
detectors:
tensorrt:
type: tensorrt # 使用tensorrt而不是CPU
device: 0 # 使用哪个GPU,默认为0即第一块GPU
mqtt:
enabled: false # 如果使用HA的可以自行打开,我暂无需求所以默认不开
# 录制配置
record:
enabled: true
retain:
days: 0 # 全部录像保留0天,这里自行设置天数
mode: all
# 摄像头配置
cameras:
camera1: # 自定义摄像头名字,我这里以camera1为例
enabled: true # 摄像头是否启用
ffmpeg: # 转码设置
hwaccel_args: preset-nvidia-h265 # 这里推荐h265。你的设备若不支持H264,可改成h264(一般都支持h265)
inputs:
- path: rtsp://admin:12345678@192.168.0.158:554/stream1 # 我这里使用的是TPLINK摄像头,主码流格式为rtsp://username:password@192.168.0.158:554/stream1。别的品牌同理,可自行查阅手册
roles:
- record # 只执行录制
output_args:
record: preset-record-generic-audio-aac # 这里是设置是否录制声音。若不需要录制声音,可以去掉这一项。若报错可以改成preset-record-generic-audio-copy试试
onvif: # 用于摄像头控制,port可以在TPLINK的手机app里看见。别的品牌同理,可自行查阅手册
host: 192.168.0.158
port: 80
user: admin
password: 12345678
camera2:# 这里和camera1同理
version: 0.14
二、捕捉识别到猫咪的片段
①修改config文件
detectors:
tensorrt:
type: tensorrt # 使用tensorrt而不是CPU
device: 0 # 使用哪个GPU,默认为0即第一块GPU
model:
path: /config/model_cache/tensorrt/yolov7-320.trt # 生成的yolo文件路径
input_tensor: nchw # 默认即可
input_pixel_format: rgb # 三通道识别
width: 320 #如果前面使用yolov7-640,这里可以改为640
height: 320 #如果前面使用yolov7-640,这里可以改为640
mqtt:
enabled: false # 如果使用HA的可以自行打开,我暂无需求所以默认不开
# 录制配置
record:
enabled: true
retain:
days: 0 # 全部录像保留0天,这里建议是0天,只保留下面特定事件的录像
mode: all
events:
retain:
default: 10 # 事件录像保留 10 天
mode: active_objects # 指事件是目标活动
objects: # 这里可以给不同目标制定不同的保留期限,比如我这里是猫录像保留10天,狗录像保留8天
cat: 10
# dog: 8
objects:
track:# 目标可以是猫可以是狗
- cat
# - dog
cameras:
bedroom: # 自定义摄像头名字,我这里第一个摄像头在卧室
enabled: true # 摄像头是否启用
ffmpeg:
hwaccel_args: preset-nvidia-h265 # 这里推荐h265。你的设备若不支持H264,可改成h264(一般都支持h265)
inputs: # 摄像头一般有主码流和副码流。主码流高清,用于录制。副码流低清,用于GPU目标识别可以减少计算量和负载
- path: rtsp://admin:12345678@192.168.0.158:554/stream1 #使用TPLINK摄像头的主码流进行录制
roles:
- record # 用于录制
- path: rtsp://admin:12345678@192.168.0.158:554/stream2 #使用TPLINK摄像头的副码流进行目标检测
roles:
- detect # 用于目标检测
output_args:
record: preset-record-generic-audio-aac # 这里是设置是否录制声音。若不需要录制声音,可以去掉这一项。若报错可以改成preset-record-generic-audio-copy试试
detect: # 用于目标检测的输入配置,因为这里是副码流,用720P-5帧就可以,减少GPU负载
width: 1280
height: 720
fps: 5
onvif: # 填写摄像头的ONVIF地址和密码,可以用于摄像头控制
host: 192.168.0.158
port: 80
user: admin
password: 33055youxi
camera2: # 其他摄像头同理
version: 0.14
三、将检测到猫咪的片段转发至微信群
注:虚拟机python实现,我这里由于旧笔记本配置有限,因此这部分功能是在我的NAS虚拟机实现的。如果你的设备配置有富裕,完全可以在同一个设备中进行实现。
1.首先需要在ubuntu中使用Samba把录制的文件夹开启“文件共享”,具体参看我的另一篇
需要共享的文件为:
/home/xxxx/frigate/recordings
2.打开windows虚拟机(可以是同局域网别的设备如nas,也可以是ubuntu本设备)
①安装Miniconda
https://repo.anaconda.com/miniconda/
下载后打开安装即可
②打开Anaconda Powershell Prompt(miniconda3)
③创建一个pyhon虚拟环境并激活(建议使用python3.10),安装python-office包
conda create -n cat2wechat python=3.10
conda activate cat2wechat
pip install python-office -U
④在某个地方创建一个xxx.py文件,用记事本打开,复制并修改我的代码
import os
import shutil
import time
from pathlib import Path
from datetime import datetime
import office
# 找出最新的mp4视频,将所有新视频的地址保存为一个list
def find_new_mp4s(directory, start_check_time,last_check_time):
new_files = []
for root, dirs, files in os.walk(directory):
for file in files:
if file.lower().endswith('.mp4'):
file_path = Path(root) / file
# 如果文件创建时间在上一次检查之后,则认为是新文件
if last_check_time > file_path.stat().st_ctime > start_check_time:
new_files.append(file_path)
return new_files
# 使用微信发送所有list中的视频
def wechat_send(file_list,send_object):
for i in file_list:
office.wechat.send_file(who=send_object,file=i)
def main(source_directory, send_object, interval=60):
# 初始检查
start_check_time=float(time.time()-60) # 检查前1min的视频
last_check_time=time.time()
# 后续检查
while True:
# 记录此时的年月日
timenow = datetime.today().strftime('%Y-%m-%d')
# 检查保存文件夹是否存在
new_source_directory = os.path.join(source_directory,timenow)
new_mp4s = find_new_mp4s(new_source_directory, start_check_time, last_check_time)
if new_mp4s:
print("发现新的MP4文件,准备发送")
wechat_send(new_mp4s,send_object)
else:
print("没有发现新的MP4文件")
start_check_time = last_check_time
last_check_time = time.time()
time.sleep(interval) # 等待一段时间后再次检查
if __name__ == "__main__":
# 指定源文件夹和目标文件夹路径
source_dir = r'\\xxx\shared_folder\recordings' # 录制文件的路径,这里xxx要修改为ubuntu服务器的地址
send_object = "相亲相爱一家人" # 发到哪个群
interval = 60 # 每隔60秒检查一次
# 启动主程序
main(source_dir,send_object,interval)
⑤保存后,打开微信
⑥使用prompt运行python代码,奇迹会出现
cd xxx # 该文件的路径
python xxx.py
完结撒花!