GIGAZINEの次の紹介記事を見つけ、カメラ映像に映っている物体が何かを機械学習モデルで認識してくれるというオープンソースのNVR「Frigate」を手元で試してみたくなった。どこかの横断歩道のカメラ映像を使っているデモサイトもある。
なお、NVRとは「ネットワークビデオレコーダー」の略だ。サーバにNVRソフトウェアを導入すると、ネットワークカメラの映像を束ねた監視カメラシステムが構築できる。
Frigateを手元でとりあえず素早く試すことを目標に、手元の仮想化プラットフォームProxmox VE (PVE) の上にUbuntuの仮想マシンを構築し、その中でFrigateのdockerコンテナを動かすことにする。
仮想化プラットフォームのCPUは「AMD Ryzen 5 PRO 3400GE」で、別立てのGPUは無し。私は今回初めて存在を知ったハードウェアである、エッジAI用アクセラレータ「Google Coral (TPU)」も持っていないので、必然的に一般的なサーバソフトウェアと同じハードウェア構成となる (PVEにUSBやPCI (GPU) Passthroughも設定しない)。すなわち、物体検出の演算には仮想マシンのCPUを用いる構成だ。
Google Coral USB Accelerator Edge TPU AI アクセラレータ
次のリンク先のFrigate公式ドキュメントを参考に導入を進める。
Dockerを動かす場所を用意する。既存のDocker環境でも良いだろうし、今回の実験では、前述の前提条件のように仮想のUbuntu Server (x86_64) の中に新規構築した。
docker run hello-world
が動かせることを確認するRTSPでのVideoストリーミングが可能な、ネットワークカメラまたはカメラアプリを用意する。今回の実験では2台用意してみたが1台でも構わない。
カメラ | ソース | 備考 |
---|---|---|
No.1 | ネットワークカメラ「ATOM Cam 2」 | アプリ上でこの設定をするとRTSP配信が可能になる: Atomcam2の公式アプリがRTSP対応しました。 | Astrotourism Lab |
No.2 | Androidアプリ「RTSP Security Camera」 | アプリを起動すると画面の真ん中にRTSPのURLが表示される |
アトムテック(ATOM tech) 屋内/屋外兼用の防犯カメラ ATOM Cam 2 (アトムカムツー) 1080PフルHD Alexa対応 見守りカメラ 監視カメラ ネットワークカメラ ペットカメラ/ベビーモニター AC2
アトムテック(ATOM tech)
Docker環境の母艦で作業を行う。
docker-compose.yml
として保存するdocker-compose.yml
の編集を行うshm_size
を https://docs.frigate.video/frigate/installation#calculating-required-shm-size の計算式にしたがって調整する。今回の実験ではざっくり "128mb"
へ増量した (カメラNo.1 (1920x1080) = 26.95MB, カメラNo.2 (640x480) = 4.21MB, ログ = 30MB を全て含められるように)/path/to/your/...
2箇所を自身の環境に合わせて書き換える。今回の実験では /path/to/your/
を /home/hoge/frigate/
へ置換する形とするversion: "3.9"
services:
frigate:
container_name: frigate
privileged: true # this may not be necessary for all setups
restart: unless-stopped
image: ghcr.io/blakeblackshear/frigate:stable
#shm_size: "64mb" # update for your cameras based on calculation above
shm_size: "128mb" # update for your cameras based on calculation above
devices:
- /dev/bus/usb:/dev/bus/usb # passes the USB Coral, needs to be modified for other versions
- /dev/apex_0:/dev/apex_0 # passes a PCIe Coral, follow driver instructions here https://coral.ai/docs/m2/get-started/#2a-on-linux
- /dev/dri/renderD128 # for intel hwaccel, needs to be updated for your hardware
volumes:
- /etc/localtime:/etc/localtime:ro
- /home/hoge/frigate/config.yml:/config/config.yml
- /home/hoge/frigate/storage:/media/frigate
- type: tmpfs # Optional: 1GB of memory, reduces SSD/SD Card wear
target: /tmp/cache
tmpfs:
size: 1000000000
ports:
- "5000:5000"
- "8554:8554" # RTSP feeds
- "8555:8555/tcp" # WebRTC over tcp
- "8555:8555/udp" # WebRTC over udp
environment:
FRIGATE_RTSP_PASSWORD: "password"
/home/hoge/frigate/config.yml
として次の内容を保存する (部分ごとの説明は後述する)mqtt:
host: mqtt.server.com
cameras:
atomcam2:
ffmpeg:
inputs:
- path: rtsp://hoge:fuga@192.168.1.XXX/live
roles:
- detect
detect:
width: 1920
height: 1080
android:
ffmpeg:
inputs:
- path: rtsp://hoge:fuga@192.168.1.YYYY:NNNN
roles:
- detect
detect:
width: 640
height: 480
record:
enabled: True
retain:
days: 3
mode: motion
events:
retain:
default: 7
mode: active_objects
detectors:
cpu1:
type: cpu
num_threads: 3
cpu2:
type: cpu
num_threads: 3
objects:
track:
- person
- bicycle
- car
- motorcycle
- airplane
- bus
- train
- car
- boat
- traffic light
- fire hydrant
- street sign
- stop sign
- parking meter
- bench
- bird
- cat
- dog
- horse
- sheep
- cow
- elephant
- bear
- zebra
- giraffe
- hat
- backpack
- umbrella
- shoe
- eye glasses
- handbag
- tie
- suitcase
- frisbee
- skis
- snowboard
- sports ball
- kite
- baseball bat
- baseball glove
- skateboard
- surfboard
- tennis racket
- bottle
- plate
- wine glass
- cup
- fork
- knife
- spoon
- bowl
- banana
- apple
- sandwich
- orange
- broccoli
- carrot
- hot dog
- pizza
- donut
- cake
- chair
- couch
- potted plant
- bed
- mirror
- dining table
- window
- desk
- toilet
- door
- tv
- laptop
- mouse
- remote
- keyboard
- cell phone
- microwave
- oven
- toaster
- sink
- refrigerator
- blender
- book
- clock
- vase
- scissors
- teddy bear
- hair drier
- toothbrush
- hair brush
ここでは、atomcam2とandroidという2台のカメラを定義している。それぞれの - path: rtsp://...
の行は、各RTSPソースのURLに書き換える。
カメラ映像が、一定期間、検出したオブジェクトごとに保存されるように適宜設定している。
上記リンク先では「not recommended」となっているけれども、カメラの台数に合わせてCPU Detectorを2つ定義している。
認識するオブジェクトを定義している (テストのためにありったけ定義した)。この定義を書かないデフォルト状態の場合、検出されるオブジェクトは「person」のみである。
Docker環境の母艦にて、Frigateが保存領域として使用するディレクトリを作成する。
$ mkdir /home/hoge/frigate/storage/
Docker環境でFrigateコンテナを次のように起動し、コンソール画面に特にエラーが表示されないことを確認する。
$ cd <docker-compose.ymlを置いたpath>
$ docker compose up
Dockerの母艦のIPアドレスの5000/tcp http://192.168.1.ZZZ:5000/ へウェブブラウザでアクセスすると、鳥 (アメリカグンカンドリ?) のアイコンが左上にある「FRIGATE」画面が確認できる。左メニューの「Cameras」を選択すると、接続しているカメラの映像が静止画で一覧できる。全カメラの動画を一覧したい場合は「Birdseye」を選択すれば良いようだ。
左メニューの「Cameras」を選択し、次に右側で任意のカメラ映像を一度クリックする。そしてカメラ映像の右上に薄く現れているメニューを「Live」から「Debug」へ切り替えると、機械学習モデル (この場合はTensowFlow Liteのモデル) がカメラ映像に映った各物体をリアルタイム検出し、分類の確度とともに四角い枠で表示している様子を、毎秒5コマぐらいの動きで見ることができる。ほおお、すごい。
また、左メニューの「Events」を選択すると、物体検出の様子を時系列イベントとして閲覧できる。対象の物体部分がきっちり切り抜かれている画像がサムネイルとして並び、当該時間帯の動画もワンクリックで確認できる (我が家のピンク色のぬいぐるみが「Teddy Bear」と認識されているのはご愛嬌)。
機械学習モデルを使って物体が何かを認識することは昨今当たり前に行われている。Frigateはその機能が予め組み込まれているオープンソースなNVRソフトウェアであり、物体検出関連も含めてセットアップがとても簡単で驚いた。今回の実験では物体検出の演算にCPUのみを利用しており、GPU等を利用する場合はセットアップが実際どうなるか不明だけども。
以前試した下記記事のShinobiも面白かったが、それぞれに特色があり、こちらFrigateもなかなか実用的な予感がする (Home Assistantへの統合方法も案内されている)。機会があれば実戦投入して、NVRで物体検出が利用できると実際どのような利点があるのか、確かめてみたいと思う。