Vogelalbum 1.0.0

Eine Kamera am Vogelhaus, ein Rechner der erkennt wer da war — und eine
Sammlung, die sich von allein fuellt.

Zwei neuronale Netze: eines findet den Vogel im Bild, eines bestimmt die
Art. 148 heimische Arten, auf Deutschland eingeschraenkt und neu normiert —
ohne diese Einschraenkung wird aus einer Kohlmeise eine nordamerikanische
Schwesterart. Daraus entsteht ein Sammelalbum: nummerierte Seiten,
gefundene Arten in Farbe, fehlende als Schatten, dazu Erstfang, Punkte,
Stufen und 15 Abzeichen.

Laeuft vollstaendig auf eigener Hardware. Kein Cloud-Dienst, kein Konto,
keine Telemetrie; die Bilder verlassen das eigene Netz nicht.

Zwei getrennt deploybare Teile: die Sammlung als Django-Anwendung, die
Erkennung als eigener Dienst. Der Erkennungs-Dienst fragt selbst an und
braucht deshalb weder eine erreichbare Adresse noch einen offenen Port —
er laeuft hinter einem gewoehnlichen Router.

Dabei: Firmware fuer Raspberry Pi und ESP32-S3, Anbindung an Home
Assistant ueber MQTT, Oberflaeche auf Deutsch und Englisch, Einstellungen
je Kamera aus dem Browser, und ein Weg fuer Fotos von unterwegs.

AGPL-3.0.
This commit is contained in:
christian committed 2026-10-14 18:55:23 +00:00
commit cc9e0786c2
189 files changed
+29792

No files matched your search

+89
View File
@@ -0,0 +1,89 @@
# Einstellungen
<sub>[← zurück zum Überblick](../README.md) · [alle Kapitel](README.md)</sub>
Alles, was Detector und Web-App über Umgebungsvariablen annehmen — und was
man stattdessen im Admin einstellen kann, ohne einen Prozess anzufassen.
### Detector
| Schalter | Standard | Zweck |
|---|---|---|
| `--source` | — | Stream-URL, RTSP-URL oder Ordner |
| `--api` / `--token` | — | Wohin gemeldet wird |
| `--save-to` | — | Ordner für Rohbilder je Sichtung |
| `--gate` | `motion` | `detector` ignoriert Bewegung — nötig bei unruhigem Hintergrund |
| `--habitats` | `garten` | Lebensräume, die in Frage kommen |
| `--min-bird-score` | `0.05` | Darunter gilt die Art als unbestimmt |
| `--detect-threshold` | `0.4` | Ab wann etwas als Vogel gilt |
| `--classify-every` | `3` | Nur jedes n-te Bild durchs Modell |
| `--cooldown` | `4.0` | Sekunden Ruhe, bis ein Besuch endet |
| `--min-bird-frames` | `2` | Weniger Treffer → verworfen |
| `--min-confidence` | `0.45` | Darunter „unbestimmt" statt geraten |
| `--nachtsicht` | aus | Nie bei Dunkelheit pausieren |
| `--dunkel-unter` / `--hell-ueber` | `15` / `30` | Helligkeitsschwellen 0–255 |
| `--motion-ratio` | `0.012` | Anteil bewegter Pixel für einen Besuch |
Alles auch als Umgebungsvariable mit Präfix `VOGELALBUM_`, etwa
`VOGELALBUM_SOURCE`, `VOGELALBUM_TOKEN`, `VOGELALBUM_HABITATS`.
### Web-App
| Variable | Zweck |
|----------|-------|
| `DJANGO_SECRET_KEY` | **Pflicht**, sobald `DJANGO_DEBUG=0`. Ohne startet die App nicht. |
| `DJANGO_DEBUG` | `0` im Betrieb |
| `DJANGO_ALLOWED_HOSTS` | kommagetrennt |
| `DJANGO_CSRF_TRUSTED_ORIGINS` | kommagetrennt, mit Schema |
| `VOGELALBUM_INGEST_TOKEN` | Sammel-Token; leer lassen, wenn jede Kamera einen eigenen hat |
| `SQLITE_DIR` | Datenbank auf ein Volume legen |
| `MEDIA_ROOT` | Fotos auf ein Volume legen |
## Einstellungen im Admin statt auf der Kommandozeile
Bis vor kurzem stand die Konfiguration des Detectors nur auf seiner
Kommandozeile: Stream-Adresse, Schwellen, Lebensräume. Wer eine Kamera
umstellen wollte, brauchte eine Shell auf dem Rechner, auf dem der Detector
läuft. Jetzt fragt der Detector die Web-App:
```bash
python -m detector watch --api http://vogelalbum:8000 --token <Kamera-Token>
```
Damit holt er sich bei `/api/config/` alle 300 Sekunden, was für *seine*
Kamera gilt — und übernimmt Änderungen **ohne Neustart**. Einstellbar im
Django-Admin unter der Kamera:
| Feld | Wirkung |
|---|---|
| Stream-Adresse | Woher die Bilder kommen. `--source` hat Vorrang. |
| Lebensräume | Welche Arten der Klassifikator erwägt (`garten`, `wald`, `offenland`, `wasser`, `gebirge`) |
| Schwelle Vogelerkennung | Ab welcher Sicherheit etwas als Vogel gilt |
| Mindestanteil heimischer Arten | Darunter gilt die Sichtung als unbestimmt |
Die **Artenliste kommt mit** — sie ist eine inhaltliche Entscheidung und
gehört in den Admin, nicht in eine Python-Datei. Der wissenschaftliche Name
ist dabei der Schlüssel ins Label-File des Modells; ein zweites Mapping
braucht es nicht.
Zwei Eigenschaften sind wichtiger als die Funktion selbst:
- **Die Kommandozeile bleibt gültig.** Ohne `--token` ändert sich nichts, und
ein ausdrücklich gesetztes `--source` gewinnt immer.
- **Ein Ausfall ändert nichts.** Antwortet die Web-App nicht, läuft die
Erkennung mit dem letzten bekannten Stand weiter. Wer zwei Wochen auf den
ersten Vogel wartet, will ihn nicht verpassen, weil ein Webserver neu
gestartet wurde.
`--konfig-alle 0` schaltet das Nachfragen ab.
### Regionen
Das iNat-Modell kennt 965 Arten und ist **auf Nordamerika trainiert** — ohne
Einschränkung wird aus einer Kohlmeise eine Carolina Chickadee. Welche Arten
gelten, entscheidet deshalb `VOGELALBUM_REGION` (Standard `de`) gegen das Feld
`regions` der Art.
Eine weitere Region ist damit kein Umbau mehr, sondern ein Katalog: Arten mit
dem passenden Kürzel anlegen und die Variable umstellen. Für Nordamerika
arbeitet das Modell sogar in seiner Trainingsverteilung, also besser als hier.