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:
commit
c11fe9ab04
189 files changed
+29806
No files matched your search
@@ -0,0 +1,146 @@
|
||||
# Installation
|
||||
|
||||
<sub>[← zurück zum Überblick](../README.md) · [alle Kapitel](README.md)</sub>
|
||||
|
||||
Zwei Wege zum selben Ziel. **Mit Docker** braucht es einen Befehl und keine
|
||||
Python-Umgebung; **ohne Docker** sieht man mehr und kann einzelne Teile
|
||||
austauschen.
|
||||
|
||||
## Welcher Weg ist meiner?
|
||||
|
||||
Vogelalbum besteht aus zwei Teilen, die getrennt laufen können: der **Sammlung**
|
||||
(Django, zeigt Arten, XP und Abzeichen) und der **Erkennung** (schaut in die
|
||||
Kamera und meldet Sichtungen). Daraus ergeben sich drei sinnvolle Aufbauten —
|
||||
und für jeden gibt es genau eine Datei:
|
||||
|
||||
| Dein Fall | Datei | Was läuft |
|
||||
|---|---|---|
|
||||
| **Eine Kamera im Garten, ein Rechner im Keller.** Der Normalfall, und der richtige Anfang. | `docker-compose.heim.yml` | Sammlung **und** Erkennung auf einer Maschine |
|
||||
| **Die Sammlung soll öffentlich erreichbar sein**, die Kamera bleibt zu Hause. | `docker-compose.yml` | nur die Sammlung, mit nginx für die Fotos |
|
||||
| **Der Rechner mit Sicht auf die Kamera** liefert an eine Sammlung woanders. | `docker-compose.detector.yml` | nur die Erkennung |
|
||||
|
||||
Die letzten beiden gehören zusammen: Sie sind dieselbe Anlage, aufgeteilt auf
|
||||
zwei Orte. So läuft auch <https://vogelalbum.gaertner.onl> — Sammlung bei einem
|
||||
Hoster, Erkennung im Heimnetz.
|
||||
|
||||
🔑 **Nach außen muss dafür kein Port offen sein.** Die Verbindung geht nur in
|
||||
eine Richtung: Die Erkennung meldet ausgehend an die Sammlung, die Sammlung
|
||||
erreicht die Kamera nie. Kein Portforwarding, kein Tunnel, kein DynDNS.
|
||||
|
||||
⚠️ **Wo die Erkennung laufen kann:** `ai-edge-litert` gibt es als fertiges
|
||||
Wheel für **x86_64 und arm64**. Ein **Pi Zero trägt sie nicht** — dem fehlt
|
||||
nicht das Wheel, sondern die Rechenleistung; er ist die *Kamera*seite, siehe
|
||||
[pi/README.md](../pi/README.md).
|
||||
|
||||
### Getestet auf
|
||||
|
||||
Zwei Geräte, wie sie in vielen Hausnetzen stehen. Beide mit dem Schnellstart
|
||||
oben eingerichtet, aus einem frischen Klon und mit leerem Build-Zwischenspeicher:
|
||||
|
||||
| | **Intel N100** | **Raspberry Pi 4 Model B** |
|
||||
|---|---|---|
|
||||
| | 16 GB, Debian, x86_64 | 4 GB, Ubuntu 26.04, aarch64 |
|
||||
| Images bauen (einmalig) | 69 s | 467 s (knapp 8 min) |
|
||||
| Sammlung erreichbar nach | 5 s | 49 s |
|
||||
| **Ein Bild bestimmen** | **~30 ms** | **42 ms** (Median aus 18 Messungen, 35–53 ms) |
|
||||
| Arbeitsspeicher im Betrieb | — | 1,1 von 3,7 GB |
|
||||
| Temperatur unter Last | — | 54 °C, keine Drosselung |
|
||||
|
||||
🔑 **Der Pi 4 langweilt sich dabei.** Bei 4 Bildern pro Sekunde und
|
||||
`--classify-every=2` stehen rund **500 ms** je bestimmtem Bild zur Verfügung —
|
||||
er braucht 42. Er könnte also jedes Bild bestimmen statt jedes zweite und wäre
|
||||
immer noch bei einem Sechstel. Dass ARM hier so gut mithält, liegt an den
|
||||
int8-quantisierten Modellen; gerechnet hatten wir mit einem Vielfachen.
|
||||
|
||||
Der Preis auf dem Pi sind die acht Minuten Bauzeit und die knappe Minute bis
|
||||
zur ersten Seite. Beides fällt genau einmal an.
|
||||
|
||||
⚠️ **Ungetestet:** Raspberry Pi 5 (sollte schneller sein), Pi 4 mit nur 2 GB,
|
||||
und 32-Bit-Systeme (dort gibt es kein `ai-edge-litert`-Wheel — Raspberry Pi OS
|
||||
muss die 64-Bit-Ausgabe sein). Rückmeldungen zu anderer Hardware sind
|
||||
willkommen, gern als Issue.
|
||||
|
||||
Wer gar kein Docker will: [ohne Docker](#schnellstart-ohne-docker) weiter
|
||||
unten. Und wer nur schauen will, wie es aussieht, braucht nicht einmal eine
|
||||
Kamera — siehe [Ohne Kamera ausprobieren](#ohne-kamera-ausprobieren).
|
||||
|
||||
## Schnellstart mit Docker
|
||||
|
||||
Der kürzeste Weg — Sammlung und Erkennung auf einer Maschine, ohne venv, ohne
|
||||
Modelle von Hand, ohne systemd:
|
||||
|
||||
```bash
|
||||
git clone https://gitea.gaertner.onl/christian/vogelalbum.git && cd vogelalbum
|
||||
cp .env.beispiel .env # VOGELALBUM_SOURCE und ein Token eintragen
|
||||
docker compose -f docker-compose.heim.yml up -d
|
||||
```
|
||||
|
||||
Der erste Start baut beide Images (rund eine Minute) und legt den Artenkatalog
|
||||
an: **148 Arten mit Steckbriefen und 15 Abzeichen.** Die Sammlung steht danach
|
||||
sofort; die Referenzfotos aus Wikipedia holt der Container im Hintergrund nach
|
||||
und tropfen über die nächsten Minuten ein.
|
||||
|
||||
Danach läuft die Sammlung auf <http://localhost:8000> und der Detector schaut
|
||||
in die Kamera. Zwei Zeilen in der `.env` müssen stimmen:
|
||||
|
||||
| Variable | was rein muss |
|
||||
|---|---|
|
||||
| `VOGELALBUM_SOURCE` | Stream-URL der Kamera, z.B. `http://vogelkamera.local:8080/stream` |
|
||||
| `VOGELALBUM_INGEST_TOKEN` | ein selbst ausgedachtes Geheimnis, `openssl rand -base64 32` |
|
||||
|
||||
Alles andere hat brauchbare Vorgaben; den Django-`SECRET_KEY` erzeugt der
|
||||
Container beim ersten Start selbst und legt ihn aufs Volume.
|
||||
|
||||
Noch keine Kamera? Die Kameraseite steht in **[pi/README.md](../pi/README.md)** —
|
||||
ein Raspberry Pi Zero W mit Kameramodul reicht. Alternativ ein ESP32-S3 mit
|
||||
Kameramodul: **[esp32cam/README.md](../esp32cam/README.md)**, deutlich billiger
|
||||
und mit externer Antenne, was der Bildrate mehr hilft als jede Auflösung.
|
||||
|
||||
```bash
|
||||
docker compose -f docker-compose.heim.yml logs -f detector # was sieht er?
|
||||
docker compose -f docker-compose.heim.yml down # anhalten
|
||||
```
|
||||
|
||||
Sammlung und Rohbilder liegen in Docker-Volumes und überleben ein
|
||||
`up --build`. Wer die Sammlung öffentlich hosten und nur die Erkennung zu
|
||||
Hause laufen lassen will, nimmt die beiden anderen Dateien aus der
|
||||
[Tabelle oben](#welcher-weg-ist-meiner): `docker-compose.yml` beim Hoster,
|
||||
`docker-compose.detector.yml` zu Hause. Das Deployment der Sammlung steht in
|
||||
[Betrieb](betrieb.md).
|
||||
|
||||
## Schnellstart ohne Docker
|
||||
|
||||
Voraussetzungen: Python 3.11+, rund 500 MB Platte, eine Kamera die MJPEG,
|
||||
RTSP oder Einzelbilder liefert.
|
||||
|
||||
```bash
|
||||
git clone https://gitea.gaertner.onl/christian/vogelalbum.git && cd vogelalbum
|
||||
python3 -m venv venv
|
||||
./venv/bin/pip install -r requirements-detector.txt -r requirements-web.txt
|
||||
./scripts/fetch_models.sh # ~10 MB, liegen nicht im Repo
|
||||
./scripts/fetch_testdata.sh # drei Beispielfotos, optional
|
||||
|
||||
cd web
|
||||
../venv/bin/python manage.py migrate
|
||||
../venv/bin/python manage.py seed_dex # 148 Arten, 15 Abzeichen
|
||||
../venv/bin/python manage.py fetch_reference_images # Wikipedia-Fotos, ~5 min
|
||||
../venv/bin/python manage.py runserver 0.0.0.0:8000
|
||||
```
|
||||
|
||||
Dann in einem zweiten Terminal:
|
||||
|
||||
```bash
|
||||
./venv/bin/python -m detector watch --source "http://<kamera>:8080/stream"
|
||||
```
|
||||
|
||||
### Ohne Kamera ausprobieren
|
||||
|
||||
```bash
|
||||
cd web
|
||||
../venv/bin/python manage.py demo_data # 21 Tage Beispieldaten
|
||||
../venv/bin/python manage.py demo_data --clear
|
||||
```
|
||||
|
||||
Die Demo-Sichtungen benutzen die Wikipedia-Referenzfotos, sind also klar als
|
||||
Attrappe erkennbar. **Vor dem Echtbetrieb `--clear` laufen lassen**, sonst
|
||||
mischen sich Demo- und Kameradaten.
|
||||
Reference in new issue
Block a user