Frigate - NVR z funkcją wykrywania obiektów w czasie rzeczywistym dla kamer IP HA

Hej! Zostałem poproszony na facebooku na grupie Home Assistant o przeklejenie mojego posta z doświadczeniami z Frigate’m i detekcją twarzy jak i tablic rejestracyjnych. Wklejam i tu, dla potomnych :slight_smile:

Link do tego posta:


#detekcja_twarzy #tablice_rejestracyjne frigate #doubletake #compreface #aiserver

Detekcja Twarzy, Tablic Rejestracyjnych, Frigate - garść porad.

Hej!

Na grupie jestem krótko, ale zdążyłem zauważyć powtarzające się pytania o detekcję twarzy (i pytania o detekcję tablic rejestracyjnych).

Jako, że od ponad pół roku prawie codziennie dłubię w tych tematach, testuję różne technologie, tweakuje parametry - mam już nieco “wyczucia” co działa (u mnie), a co nie.

Ponadto stanowczo sprzeciwiam się stwierdzeniom “że jak AI to tylko GPU a Coral to zabawka”.

Mam CPU i Corala, moje AI działają wyśmienicie dlatego chętnie podzielę się tipami i odpowiem na pytania zagubionych entuzjastów :slight_smile:

:arrow_right: A) Sprzęt: :printer:

:white_check_mark: 1) NUC

  • Intel NUC NUC13ANKi7 13th Gen Core I7-1360P
  • RAM: 64G
  • Coral Edge TPU - wersja USB-C, nie-rozwojowa
  • HDD: SSD, 2TB, podzielone na system i Proxmox VMki + kontenery

:white_check_mark: 2) Kamery + ustawienia strumienia na którym realizuję detekcję

= W sumie 5 kamer, 7 strumieni + detekcja audio

  • Reolink Doorbell PoE (5MP)
    – 2560 x 1920
    – FPS 15
    – Bitrate: 4096
    – I-frame Interval: 1x

  • Reolink RLC-823A 16x (8MP)
    – 3840 x 2160
    – FPS 15
    – Bitrate: 8192
    – I-frame Interval: 1x

  • 2x Reolink TrackMix PoE
    – 3840 x 2160
    – FPS 15
    – Bitrate: 8192
    – I-frame Interval: 1x

  • Reolink RLC-520
    – 2560 x 1920
    – FPS 15
    – Bitrate: 7168

:arrow_right: B) Technologia :radioactive:

:white_check_mark: Frigate jako NVR, uruchomiony wprost na host’cie NUC
– wyłącznie korzysta z Corala TPU
– mam włączoną również detekcję dźwięku (rozmowa, szczekanie, krzyk)

:white_check_mark: Double-Take
– (frontend) interfejs graficzny do detekcji twarzy i treningu sieci
– Korzystam z bardziej aktualnego forku oryginalnego repozytorium
GitHub - skrashevich/double-take: Unified UI and API for processing and training images for facial recognition.

:white_check_mark: CodeProject.AI
– (backend) model wykrywający twarz
– Moduły:
— License Plate Reader
— Face Processing
CodeProject.AI Server: AI the easy way. - CodeProject

:white_check_mark: Frigate ALPR
– (frontend) detekcja tablic rejestracyjnych
GitHub - kyle4269/frigate_alpr

:white_check_mark: Frigate ALPR Web
– (frontend) Webowy interfejs do powyższego, umożliwia podgląd zdjęć aut, logi
GitHub - kyle4269/frigate_alpr_web

:arrow_right: C) Konfiguracja :gear:

:white_check_mark: 1. Setup serwera

  • Intel NUC to Ubuntu + Proxmox
  • Proxmox uruchamia m.in. VMkę Ubuntu oraz kontener (CT) “frigate-container”
  • na NUCu mam Frigate docker
  • na Frigate-container (CT) mam Double-Take, CompreFace, CodeProject.AI server, Frigate-ALPR + Web
  • w sumie na NUCu mam uruchomionych jakieś 40 dockerów do różnych celów
  • Wszystkim zarządza Portainer.

:white_check_mark: 2. YAMLe

Poniżej link do zanonimizowanych config’ów ww. technologii:

:arrow_right: D) FAQ :grey_question:

:white_check_mark: 1. Ile trwa detekcja twarzy?

  • CodeProject.AI Server: 2-17 sekund.
    – 2 sekundy jeśli pojawia się kilka klatek z twarzą.
    – 17 sekund jeśli łażę wokół domu i Frigate mieli obraz ze wszystkich kamer, a twarz wykrywana jest dziesiątki razy.

– Najczęściej jednak twarz łapie do kilku sekund.

:white_check_mark: 2. Czemu nie GPU?

  • bo GPU żre prąd, a moja serwerownia (Synology NAS + Reolink NVR + NUC + kilka urządzeń) żre już 3.5kWh dziennie.

  • bo GPU to armata do muchy. Nie potrzebuję detekcji twarzy czy obiektu w milisekundy, zadowala mnie kilka sekund :slight_smile:

  • bo NUC i Coral TPU wymiatają i nie potrzebuję GPU - wszystko sprowadza się do dobrej konfiguracji :slight_smile:

  • W rozważaniu CPU vs GPU warto wziąć pod uwagę następującą obserwację:
    – Modele detekcji twarzy głównie konsumują pamięć RAM, na potrzeby przechowywania w pamięci ciężkiego modelu (nawet kilka GB!)
    – Kiedy detektory nie pracują, ich konsumpcja CPU jest bliska zeru.
    – Zanim klatka z kamery pójdzie do detekcji, analizowana jest pod kątem czy w ogóle twarz na niej występuje (filtr OpenCV), czy spełnia kryterium obiektu (czy to w ogóle sylwetka osoby?), czy spełnia inne kryteria (min_area)
    – To oznacza, że w praktyce nieliczne klatki są poddawana detekcji.
    – To oznacza, że wysoka konsumpcja CPU ma charakter chwilowy, nieliniowy.

  • Na załączonych obrazkach wydruk z “s-tui” oraz “ctop”, utylizacja CPU i RAMu przez kontenery oraz całościowo z serwera.

  • Widać, że CPU nie przekracza 33-40%.

  • RAMu całość (przypominam - ponad 40 dockerów, większość lab + praca) ok. 30GB

:white_check_mark: 3. Czemu nie CompreFace?

  • bo CompreFace jest ciężkie jak cholera, żre dużo pamięci, nie nadąża z inferencją przy kaskadzie zdjęć na wejściu.
  • To be fair, AI.Server także żre - ale w jednym pudełku mamy model Twarz + Tablice, a CompreFace daje tylko twarz.
  • CodeProject.AI Server jako jedna aplikacja oferuje moduły różnych zastosowań - jeden system do tablic rejestracyjnych + twarzy
  • bo z dyskusji na Double-Take sam autor forka twierdzi, że AI.Server lepiej sprawuje się na gołym CPU, CompreFace zaś na GPU:
    CompreFace or CodeProject.AI Server? · skrashevich/double-take · Discussion #109 · GitHub

:white_check_mark: 4. A tablice jak wykrywasz?

  • domyślnie Frigate-ALPR zaleca korzystanie z online usługi “Plate Recognizer”
  • darmowa subskrypcja w zupełności wystarcza, do 2500 requestów miesięcznie chyba.
  • natomiast ja chciałem mieć model offline, u siebie w serwerowni. CodeProject.AI Server modułem “License Plate Recognizer” realizuje to.
  • prywatność.

:white_check_mark: 5. Jaki sprzęt muszę mieć by robić detekcję twarzy?

  • ja jestem zwolennikiem rozwiązania Frigate + Coral na detekcję obiektów (osoba, auto) oraz CPU do twarzy.
  • A zatem kup terminal z dobrym CPU - dużo rdzeni, dużo core’ów, daj mu dużo RAMu i kup Corala.

:white_check_mark: 6. Coral jest za drogi. Jak żyć?

  • detekcja obiektów na gołym CPU zarżnie Ci maszynę jak świnię. Nie polecam, testowałem.
  • wtenczas inferencja rozciągnie się nawet do minut jeśli będziesz chciał jeszcze twarz i tablice.
  • albo kupujesz Corala i używasz CPU albo GPU.
  • GPU natomiast pożre Ci tyle prądu że nie wyjdziesz na tym ekonomicznie.

:white_check_mark: 7. A testowałeś w ogóle GPU cwaniaku?

  • Tak, dysponuję Intel NUC 11 Phantom Canyon wyposażonym w RTX 2060.
  • Nie jest to bestia pośród GPU ale świetnie dźwigała Frigate’a, natomiast nie byłem zadowolony z konsumpcji prądu.

:white_check_mark: 8. Po co Ci detekcja twarzy?

  • otwieram furtkę gębą jak wracam z biegania, bez telefonu.
  • jeśli kamera wykryje mnie wokół domu, automatyka wyłacza powiadomienia z kamer, wysyła powiadomienie “Mariusz kręci się przy szopie”, świecę podbitkę jeśli zgaszona, różne

:white_check_mark: 9. Po co Ci detekcja tablic rejestracyjnych?

  • otwieram bramę gdy podjeżdża rodzina i znajomi, czy sam podjeżdżam.
  • Istotnym jest, że tablice wykrywam tylko i wyłącznie kamerą z domofonu.
  • Inne kamery powodowały false positive’y dla samochodów zaparkowanych na podjeździe.

:white_check_mark: 10. Czy testowałeś inne backendy detekcji twarzy?

  • Tak, testowałem DeepStack (słaba detekcja), AWS Rekognition (duże koszta), CompreFace (duża konsumpcja zasobów - RAM + CPU, przeciętna jakość detekcji)
  • Póki co najbardziej jestem zadowolony z CodeProject.AI Server

:white_check_mark: 11. Jak NUC radzi sobie z tymi zadaniami?

  • Utylizacja CPU nie przekracza 40%.
  • Frigate + Coral inferencja na poziomie 6-8ms

:white_check_mark: 12. A Home Assistanta gdzie uruchamiasz?

  • Na osobnym terminalu, HP T630.
  • Jeśli Cię to interesuje, na końcu tego posta znajdziesz nick do opisu mojego setupu HA

:white_check_mark: 13. Przyszedłem się Ciebie czepiać - w innych komentarzach pisałeś że używasz CompreFace, aaa i co teraz kłamco?!!11

  • Testuję od dłuższego czasu CodeProject.AI server i na etapie pisania tych komentarzy nie byłem pewien czy go polecam.
  • Wtenczas polecałem CompreFace’a.
  • Teraz polecam AI Server.
  • Idź hejcić gdzieś indziej. :upside_down_face:

:white_check_mark: 14. Jak Double-Take wykrywa twarze?

  • Double-Take nie wykrywa twarzy, on jedynie łączy Frigate’a z magiczną skrzynką która robi detekcję.
  • DT działa tak:

– 1. Nasłuchuje na MQTT zdarzeń frigate/events
– 2. Jeśli zdarzenie jest typu “person” oraz spełnia wymóg “min_area” oraz “camera” rozpoczyna pracę.
– 3. Odpytuje Frigate’a o dwa zdjęcia: “latest.jpg” oraz “snapshot.jpg” . Wykonuje to X razy, tyle ile skonfigurowaliśmy (u mnie 6 razy jedno i 6 razy drugie) co Y czasu (u mnie co 300ms).
– 4. Każde zdjęcie sprawdzane jest czy w ogóle jest tam twarz (filtr OpenCV)
– 5. Jeśli jest twarz, całe zdjęcie wysyłane jest do backendu detekcji (CompreFace, AI.Server).
– 6. DT odczekuje “timeout” na odpowiedź (np. 25 sek).
– 7. Jeśli odpowiedź przyjdzie, to analizuje czy wykryto znaną twarz. Twarz musi spełnić kryterium minimalnego rozmiaru oraz pewności (confidence) zanim zostanie “zaakceptowane”.
– 8. Jeśli odpowiedź nie przyjdzie w zadanym czasie, DT dalej nie czeka na model. Zamyka połączenie.

:white_check_mark: 15. Czy Intel NUC to jedyne słuszne rozwiązanie? Drogo.

  • Absolutnie nie! Kupiłem NUCa do potrzeb wielorakich (do pracy, do labu, do AI właśnie)
  • Spokojnie możesz poczytać tutaj na grupie i poszukać alternatywnego terminala wyposażonego w rozsądne CPU, dorzucić mu pamięci - i powinien udźwignąć.
  • Koledzy w komentarzach (i w innych postach) piszą o zaletach terminala opartego N100, poszukaj na grupie :slight_smile:

:arrow_right: E) Hints, Tips & Tricks :green_circle:

:white_check_mark: 0. Instalację jakiegokolwiek oprogramowania gorąco polecam poprzez Portainer → Stacks . YAML zgodny ze specyfikacją “docker-compose” ułatwia zmiany ustawień, re-deployment. Nigdy nie wpisuję z palca “docker run --dupa”.
Portainer to oprogramowanie do zarządzania dockerami. Instalujemy ja na naszym host’cie, pozwoli nam ładnie startować, sprawdzać, zmieniać dockery.

:white_check_mark: 1. Detekcję obiektów (Frigate) prowadze na strumieniu o najwyższej rozdzielczości. To istotne, bo nim więcej pikseli tym większa jakość detekcji, pewność.

:white_check_mark: 2. Na kamerach ustawiam niższe FPS (np. 15 zamiast max 30), tak aby FFMPEG mógł nadążyć z obróbką strumienia, inaczej gubił klatki.

:white_check_mark: 3. Zanim Double-Take wyciągnie twarz do detekcji, najpierw nasłuchuje zdarzeń “person” z Frigate’a. Następnie wyciąga 6 zdjęć “latest.jpg” oraz 6 “snapshot.jpg” w odstępach 0.3sek (w sumie 1.8 sek). Ta konfiguracja jest efektem moich prób i błędów. Za dużo prób wyciągania wysyła za dużo klatek do detekcji i zamula CPU. Za duża zwłoka gubi szybko poruszające się osoby. Te parametry będę jeszcze optymalizował, nie są idealne :stuck_out_tongue:

Double-Take.yaml:

  attempts:
    # number of times double take will request a frigate latest.jpg for facial recognition
    latest: 6
    # number of times double take will request a frigate snapshot.jpg for facial recognition
    snapshot: 6
    # process frigate images from frigate/+/person/snapshot topics
    mqtt: true
    # add a delay expressed in seconds between each detection loop
    delay: 0.3

:white_check_mark: 4. Istotnym jest, że zanim Double-Take wyśle twarz do detekcji, wykrywa czy w ogóle twarz znajduje się w klatce wideo przy pomocy filtrów OpenCV. To bardzo oszczędza CPU/GPU i odrzuca wiele klatek.

:white_check_mark: 5. We Frigate’cie bardzo istotnym jest optymalizacja parametrów stref, mask obiektów, min_area, max_area i innych które wykluczają fałszywe detekcje osób - np. mi wielokrotnie tuje wykrywa jako osobę. Niestety Frigate’a trzeba non stop konfigurować wykluczając strefy, modyfikując parametry. Naszym celem jest zmniejszenie ilości zdarzeń “osoba”, sprowadzając sie tylko do prawdziwych detekcji.

:white_check_mark: 6. W kamerach Reolink’a polecam strumienie RTSP. Strumień http-flv działa wyłacznie dla 5MP kamer a i tak jest niestabilny. Jeśli macie nagrywarkę Reolink NVR, warto pociągać strumienie z NVRa zamiast wprost z kamery, odciąży to CPU kamery.

:white_check_mark: 7. FFMPEG presety - próbowałem je wszystkie, włącznie z ręcznym dłubaniem przy parametrach. Celem była redukcja użycia CPU. Efekt? Dla mnie działają te:

Per-kamera:
output_args:
record: preset-record-generic-audio-aac

Ogólne:

ffmpeg:
global_args: -hide_banner -loglevel debug
hwaccel_args: preset-vaapi
input_args: preset-rtsp-restream

:white_check_mark: 8. Aby zmniejszyć użycie CPU, warto ograniczyć ilość zmian rozdzielczości. W tym celu, we Frigate ustawiamy per-camera wartości width x height odpowiadające strumieniowi:

detect:
width: 3840
height: 2160

:white_check_mark: 9. Dla najwyższej stabilności łącza polecam kamery PoE - kabel to kabel.

:white_check_mark: 10. Z moich testów wynika, że detekcja twarzy najczęściej występuje na zdjęciach pochodzących z latest oraz snapshot - mniej więcej po równo (więcej mam detekcji z latest). To oznacza, że zdjęcie pobierane ze zdarzenia MQTT Frigate’a - u mnie - nie prowadzi praktycznie nigdy do detekcji. To oznacza, że bezpiecznie można wyłączyć opcję “mqtt” w Double-Take YAMLu.

Zaoszczędzi to nieco taktów CPU. Ja w przykładzie wklejonym powyżej zostawiam, może u kogoś zadziała.

:white_check_mark: 11. Klipy z Frigate’a zapisuj do katalogu na serwerze który uruchamia Frigate’a (lokalnie). Nie używaj podmontowanego udziału SMB/CIFS/Samba, ani NFS.

Unikniesz problemu “Unable to keep up with…” gdzie Frigate nie nadąża zapisywać klipów z uwagi na ograniczone I/O dysku. Miałem ten problem bo chciałem od razu na NASa wrzucać nagrania. Niestety, trzymam nagrania na NUCu, a później rsync’iem wysyłam na NASa :slight_smile:

:white_check_mark: 12. We Frigate’cie nie rozbijaj strumienia “detect” i “record” na osobne połączenia do kamery. W sekcji Go2Rtc skonfiguruj “jedną” linię połączenia (np. RTSP) i daj jej wszystkie role (detect, record, audio).

Mniejsza ilość połączeń do kamery odciąży CPU kamery. CPU kamery z reguły ledwo wystarcza na jej własne potrzeby.

Spójrz w moim configu jak mam zrealizowaną sekcję go2rtc. Zauważ tylko jedno połączenie z danym IP kamery.

Dokumentacja Frigate’a na ten temat:

:white_check_mark: 13. Aby sprawdzić czy strumień który podajesz w konfiguracji Frigate’a w sekcji “go2rtc” działa poprawnie i jakie są jego parametry, uruchom linię poleceń i zaloguj się do docker Frigate’a:

bash # docker exec -it frigate /bin/bash

A następnie użyj polecenia ffprobe podając jako jego pierwszy argument całą linię wskazującą na strumień kamery, np. u mnie:

frigate # ffprobe "rtsp://username:password@192.168.X.Y:554/h264Preview_01_main"

Wyjście tego polecenia pokaże Ci parametry audio, rozdzielczość strumienia i czy w ogóle to działa :slight_smile:

:white_check_mark: 14. Jak trenować te sieci aby rozpoznały twarz?

  • Korzystamy z interfejsu Double-Take:
    – 1. wchodzimy w kartę train
    – 2. lewy górny róg rozwijane menu - wybieramy “add new”
    – 3. wpisujemy nazwe osoby (tzw. etykieta)
    – 4. wgrywamy zdjęcia danej osoby
    – 5. Każde wgrane zdjęcie “dotrenowuje” sieć.

Jeśli chcemy zmienić backend detekcyjny - klikamy “Sync”, spowoduje to usunięcie twarzy i wytrenowanie od początku.

:white_check_mark: 15. Jakie zdjęcia się nadadzą do treningu?

  • Po pierwsze, na podstawie researchu, czytania porad osób, różnych projektów (typu YOLOv5) nie zawsze więcej = lepiej.

  • Lepiej mieć ograniczoną ilość zdjęć (np. 30-50 zdjęć osoby), ale lepszej jakości niż wgrać 1000 bzdurnych fotek.

  • Zdjęcie powinno przedstawiać twarz w całej okazałości, najlepiej frontalnie, w dobrym oświetleniu.

  • Podczas treningu modele wyciągają “cechy” twarzy, np:
    – rozstaw oczu (dystans)
    – rozmieszczenie kości policzkowych
    – geometria czoła, oczodołów, ust, nosa

  • Te cechy muszą być pobrane ze zdjęć twarzy, a nie sylwetki.

  • Wysyłamy więc zdjęcia typu “Selfie” - a nie zdjęcie na tle drzewa czy Schodów Smoleńskich.

  • Ja mam po 30 zdjęć swoich i żony i to nadal za mało, jak widzicie na screenshot’cie - na kilku zdjęciach wykryło nas jak “Unknown” :frowning:


To chyba na tyle z pierwszych myśli jakie przyszły do głowy, zapraszam do dyskusji :slight_smile:

Zapraszam również CPU-sceptyków i GPU-wyznawców - chętnie zmierzę się z Waszymi przekonaniami.

PS: U mnie działa. :see_no_evil: To że u mnie działa nie znaczy że u Ciebie zadziała.
Cały ten opis aplikuję do mojej platformy.


:star: Spodobał Ci się mój opis?

Sprawdź mój setup Home Assistanta dla inspiracji i dla garści innych porad:

7 polubień