Frigate NVR mit Gesichtserkennung auf Intel N100 – Komplettes Tutorial
Diejenigen, die meinem Kanal folgen, wissen, dass ich bereits Frigate NVR auf Proxmox laufen hatte bis mein Mini PC gecrasht ist. 5 Reolink-Kameras hatte ich, aber keine Aufnahmen, keine Objekterkennung mehr. Nach einem Einbruch in der Nachbarschaft war ein ordentliches Kamera-Monitoring umso dringender und ich habe neu investiert.
100% Lokal – Keine Cloud nötig
Das Besondere an diesem Setup: Alles läuft lokal. Keine Abos, keine Cloud-Abhängigkeiten, keine Daten verlassen das Netzwerk.
| Komponente | Läuft auf | Cloud? | Zweck |
|---|---|---|---|
| Proxmox VE | N100 Mini PC | Nein | Hypervisor / Host OS |
| Frigate NVR | N100 (Docker) | Nein | Objekterkennung + Aufnahmen |
| Coral TPU | N100 (USB) | Nein | Hardware-beschleunigte Detection (10ms/Frame) |
| Gesichtserkennung | N100 (Docker) | Nein | InsightFace identifiziert Familienmitglieder |
| Lärmpegel-Monitor | N100 (Docker) | Nein | Audio-Analyse aus Kamera-RTSP-Feeds |
| Ollama + Gemma 3 | N100 (nativ) | Nein | Lokales LLM für Sprachsteuerung |
| MQTT Broker | Home Assistant | Nein | Event-Kommunikation |
| Home Assistant | Separater Server | Nein | Automation + Dashboard |
| Aufnahmen-Speicher | 5,5TB Externe HDD | Nein | 14-30 Tage Retention |
Der einzige externe API-Call ist der optionale GPT-4o Vision Check für die Mülltonnenerkennung – und selbst der könnte durch ein lokales Modell ersetzt werden.
Warum ist das wichtig? – Kamera-Feeds verlassen nie dein Netzwerk – Gesichtserkennungs-Daten bleiben auf deiner Hardware – Keine monatlichen Abos (Ring, Nest & Co.) – Funktioniert auch bei Internet-Ausfall – Deine Daten gehören dir, für immer
Hardware
| Komponente | Preis | Zweck |
|---|---|---|
| Intel N100 Mini PC (16GB RAM, 512GB SSD) | ~250€ | Frigate NVR Host |
| Google Coral USB TPU | bereits vorhanden | Beschleunigung der Objekterkennung |
| WD Elements 5,5TB Externe HDD | ~155€ | Aufnahmenspeicher |
Gesamt: ~405€ (Start möglich mit nur Mini PC + Coral für ~280€)
Schritt 1: Proxmox VE installieren
Proxmox als Basis-OS gibt Flexibilität für zusätzliche Services (z.B. Ollama für lokale KI).
- Proxmox VE 9.1 ISO von proxmox.com herunterladen
- Auf USB-Stick flashen (Balena Etcher oder
dd) - Vom USB booten, auf interne SSD installieren
- Enterprise-Repos deaktivieren:
# Per SSH auf Proxmox
sed -i 's/^deb/#deb/' /etc/apt/sources.list.d/pve-enterprise.sources
echo "deb http://download.proxmox.com/debian/pve trixie pve-no-subscription" > /etc/apt/sources.list.d/pve-no-subscription.list
apt update && apt full-upgrade -y
Schritt 2: Netzwerk
Meine Kameras sind in einem separaten VLAN (NoT – Network of Things, 192.168.3.x). Der N100 braucht direkten Zugang für RTSP-Streams.
Wichtig: Ich hatte den N100 zuerst im Default-VLAN mit Firewall-Regeln zum Kamera-VLAN – das hat NICHT zuverlässig funktioniert. Die Lösung: N100 direkt ins Kamera-VLAN über einen dedizierten Switch-Port.
Zusätzlich nötig: – Internet-Zugang für den N100 (Docker-Pulls, Updates) – Zugang zu Home Assistant für MQTT
Schritt 3: Docker + Frigate installieren
Docker direkt auf dem Proxmox-Host (einfacher für USB-Passthrough als LXC):
apt install -y docker.io docker-compose
systemctl enable docker
/opt/frigate/docker-compose.yml erstellen:
services:
frigate:
container_name: frigate
image: ghcr.io/blakeblackshear/frigate:stable
restart: unless-stopped
privileged: true
shm_size: "256mb"
volumes:
- /opt/frigate/config:/config
- /mnt/recordings:/media/frigate
- /dev/bus/usb:/dev/bus/usb
- type: tmpfs
target: /tmp/cache
tmpfs:
size: 1000000000
ports:
- "5000:5000"
- "8971:8971"
- "1984:1984"
- "8554:8554"
- "8555:8555/tcp"
- "8555:8555/udp"
Schritt 4: Frigate konfigurieren
/opt/frigate/config/config.yml:
mqtt:
enabled: true
host: 192.168.1.70 # Eure HA-IP
user: mqtt
password: euer_mqtt_passwort
port: 1883
detectors:
coral:
type: edgetpu
device: usb
ffmpeg:
hwaccel_args: preset-vaapi
output_args:
record: -f segment -segment_time 10 -segment_format mp4 -reset_timestamps 1 -strftime 1 -c:v copy -an
record:
enabled: true
alerts:
retain:
days: 30
mode: motion
detections:
retain:
days: 14
mode: motion
objects:
track:
- person
- car
- dog
- cat
detect:
enabled: true
snapshots:
enabled: true
retain:
default: 14
cameras:
haustuer:
ffmpeg:
inputs:
- path: rtsp://user:pass@192.168.3.79/Preview_01_main
roles: [record]
- path: rtsp://user:pass@192.168.3.79/Preview_01_sub
roles: [detect]
detect:
fps: 5
# Weitere Kameras nach gleichem Muster
Tipp: Sub-Stream für Detection (niedrigere Auflösung = schnellere Verarbeitung), Main-Stream für Aufnahmen (volle Qualität).
Schritt 5: Gesichtserkennung mit InsightFace
Hier wird es richtig spannend. Frigate erkennt WAS im Bild ist (Person, Auto, Hund). Aber es erkennt nicht WER. Dafür habe ich einen eigenen Service gebaut.
Warum nicht dlib/face_recognition?
Mein erster Versuch war die beliebte Python face_recognition Library (basiert auf dlib). Das hat leider gar nicht geklappt. Bei 640×480 Security-Kamera-Auflösung wurde kein einziges Gesicht gefunden. Selbst mit 3x Upscaling und CNN-Modell – null Treffer.
InsightFace mit dem buffalo_sc Modell löst das Problem.
Die Architektur
Frigate erkennt "person" → MQTT Event
↓
Face Recognition Service (Docker Container)
↓ holt das VOLLE Kamerabild (nicht den Event-Crop!)
↓ InsightFace: Gesicht erkennen + Embedding berechnen
↓ Vergleich mit known_faces Ordner
↓
Match → Frigate Sub-Label setzen + MQTT an HA
Kein Match → Periodischer Scanner alle 30s auf allen Kameras
Den Service bauen
Dockerfile (/opt/face-recognition/Dockerfile):
FROM python:3.11-slim-bookworm
RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential cmake libgl1 libglib2.0-0 && \
rm -rf /var/lib/apt/lists/*
RUN pip install --no-cache-dir insightface onnxruntime numpy pillow \
requests paho-mqtt opencv-python-headless
COPY app.py /app/app.py
WORKDIR /app
CMD ["python", "app.py"]
Der Kern von app.py:
from insightface.app import FaceAnalysis
import cv2, numpy as np
app = FaceAnalysis(name='buffalo_sc', providers=['CPUExecutionProvider'])
app.prepare(ctx_id=0, det_size=(640, 640))
def identify_all_faces(image_bytes, known_embeddings):
img = cv2.imdecode(
np.frombuffer(image_bytes, np.uint8), cv2.IMREAD_COLOR)
# Hochskalieren - kritisch für Security-Kameras!
h, w = img.shape[:2]
if w < 1000:
img = cv2.resize(img, (w * 2, h * 2))
faces = app.get(img)
if not faces:
return "no_face", 0
embedding = faces[0].embedding
best_match, best_sim = "unknown", -1
for person, known_embs in known_embeddings.items():
for known_emb in known_embs:
sim = np.dot(embedding, known_emb) / (
np.linalg.norm(embedding) * np.linalg.norm(known_emb))
if sim > best_sim:
best_sim, best_match = sim, person
if best_sim >= 0.3:
return best_match, round(float(best_sim) * 100, 1)
return "unknown", round(float(best_sim) * 100, 1)
Background Scanner (Key Feature)
Der Event-Snapshot zeigt die Person oft von hinten. Ein Background-Thread holt alle 15s ein frisches Bild:
def scan_active_persons():
while True:
time.sleep(15)
for camera, info in active_persons.items():
if info["identified"]:
continue
resp = requests.get(
f"{FRIGATE_URL}/api/{camera}/latest.jpg")
name, conf = identify_face(resp.content)
if name not in ("no_face", "unknown"):
requests.post(
f"{FRIGATE_URL}/api/events/{info['event_id']}/sub_label",
json={"subLabel": name})
Training: Kamera-Perspektive entscheidend
| Trainingsbilder | Score |
|---|---|
| Nur Selfies | 33% (Fail) |
| + Kamera-Snapshot | 55% (Match!) |
| Mehrere Winkel | 60%+ |
Kamera-Trainingsfotos: Vor die Kamera stellen, curl http://frigate-ip:5000/api/KameraName/latest.jpg > foto.jpg, nach /opt/face-recognition/known_faces/name/ kopieren, Container neustarten. 5-10 Fotos pro Person.
In docker-compose.yml
face-recognition:
container_name: face-recognition
image: face-recognition:local
build: /opt/face-recognition
restart: unless-stopped
volumes:
- /opt/face-recognition/known_faces:/known_faces
MQTT Discovery für HA
Automatisch registrierte Sensoren: – sensor.face_recognition_wohnzimmer → zuletzt erkannte Person – sensor.face_recognition_personen_zuhause → Anzahl Familienmitglieder
Schritt 6: Home Assistant Integration
- Frigate Integration über HACS installieren
- Integration hinzufügen: URL =
http://n100-ip:5000 - Alle Kameras erscheinen als
camera.frigate_*Entities
Ich nutze ein „Frigate-First“ Setup: Dashboard und Automationen verwenden Frigate-Entities als primäre Quelle, mit Fallback auf direkte Reolink-Entities.
Gesichtserkennungs-Entities
Der Service erstellt MQTT-Discovery-Sensoren in HA: – sensor.face_recognition_wohnzimmer = „dad“ – sensor.face_recognition_personen_zuhause = „3“
Smarte Automationen
- Familie an Kamera → Stilles Raum-Tracking Update
- Unbekannte Person an Garten/Garage → Alarm mit Snapshot
Schritt 7: Bonus – KI-Mülltonnenerkennung
Meine Garagenkamera sieht die Mülltonnen. Am Vorabend des Abholtags: 1. GPT-4o Vision analysiert den Garage-Snapshot 2. Prüft welche der 4 Tonnen fehlt 3. Falls die richtige noch drinsteht → Push-Erinnerung
Performance auf dem N100
| Metrik | Wert |
|---|---|
| CPU-Auslastung (5 Kameras) | ~30-40% |
| RAM-Verbrauch | ~6GB von 16GB |
| Coral TPU Detection | ~10ms pro Frame |
| Gesichtserkennung (InsightFace) | ~3-5s pro Gesicht |
| Speicherverbrauch Aufnahmen | ~50-100GB pro Tag |
| Ollama Gemma 3 4B | 2 tok/s (nur CPU) |
Ausblick
- Gesichtserkennung verbessern mit mehr Kamera-Trainingsfotos
- Ollama mit Gemma 3 für lokale Sprachsteuerung (bereits installiert, 2 tok/s)
- Eventuell Upgrade auf Apple Silicon Mac Mini für schnellere lokale KI
Schreibe einen Kommentar