Files
vogelalbum/README.md
T
christian c11fe9ab04 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.
2026-10-15 14:30:02 +00:00

162 lines
7.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<div align="center">
# Vogelalbum
**Eine Kamera am Vogelhaus, ein Rechner der erkennt wer da war — und eine
Sammlung, die sich von allein füllt.**
[![Lizenz: AGPL 3.0](https://img.shields.io/badge/Lizenz-AGPL--3.0-2d5a3d.svg)](LICENSE)
[![Python 3.11+](https://img.shields.io/badge/Python-3.11%2B-2d5a3d.svg)](docs/installation.md)
[![Ohne Cloud](https://img.shields.io/badge/Cloud-nicht%20n%C3%B6tig-2d5a3d.svg)](#was-es-macht)
[![Artenkatalog: 148](https://img.shields.io/badge/Artenkatalog-148%20Arten-2d5a3d.svg)](docs/erkennung.md)
**[→ Live ansehen: vogelalbum.gaertner.onl](https://vogelalbum.gaertner.onl)**
![Die Sammlung](docs/sammlung.png)
</div>
> **In English:** Vogelalbum identifies garden birds from a camera stream and turns
> the sightings into a collectible album that fills itself. It runs entirely on
> your own hardware — no cloud, no third-party services. The interface speaks
> German and English; the source code and its comments are German.
---
## Was es macht
Eine Kamera schaut aufs Futterhaus. Alles andere passiert von selbst:
- 🔍 **Erkennt die Art** — zwei neuronale Netze, eines findet den Vogel im Bild,
eines bestimmt ihn. Gemessen: 43 von 44 Arten richtig, keine falsch bestimmt.
- 🎴 **Sammelt** — jede neue Art ist ein Erstfang. 148 Arten, 15 Abzeichen, XP
und Level. Das ist der Teil, für den Kinder wiederkommen.
- 🏠 **Bleibt zu Hause** — kein Cloud-Dienst, keine Telemetrie, kein Konto. Die
Erkennung läuft auf deiner Hardware, die Bilder verlassen dein Netz nicht.
- 🔌 **Nimmt jede Kamera** — MJPEG, RTSP, Einzelbilder oder ein Ordner. Ein
Raspberry Pi Zero genügt, ein ESP32-S3 für 17 € auch.
- 🥔 **Läuft auf kleiner Hardware** — gemessen auf einem Raspberry Pi 4:
42 ms je bestimmtem Vogel, 1,1 GB Arbeitsspeicher. Zahlen für beide
getesteten Geräte in [docs/installation.md](docs/installation.md#getestet-auf).
- 📱 **Auch ohne Kamera** — Handyfotos lassen sich hochladen und werden genauso
bestimmt.
- 🏡 **Spricht mit Home Assistant** — über MQTT, mit Autodiscovery.
<div align="center">
<img src="docs/startseite.png" width="49%" alt="Die Startseite">
<img src="docs/abzeichen.png" width="49%" alt="Die Abzeichen">
</div>
## Schnellstart
Sammlung und Erkennung auf einer Maschine, ohne venv und ohne Modelle von Hand:
```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
```
Die Sammlung läuft danach auf <http://localhost:8000>. 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` |
**Noch keine Kamera?** Es geht auch ohne — `manage.py demo_data` füllt die
Sammlung mit 21 Tagen Beispieldaten. Der Aufbau einer Kameraseite steht in
[pi/README.md](pi/README.md) (Raspberry Pi) oder
[esp32cam/README.md](esp32cam/README.md) (ESP32-S3, billiger).
Ohne Docker, Schritt für Schritt: **[docs/installation.md](docs/installation.md)**.
## Wie es aufgebaut ist
Zwei Teile, die unabhängig voneinander laufen und getrennt deploybar sind:
```
Heimnetz │ Internet
│
Kamera 1 ──MJPEG──▶ ┌──────────┐ │
Kamera 2 ──MJPEG──▶ │ detector │ ──POST────────▶ Django ──▶ Browser
Kamera n ──MJPEG──▶ │ │ Bearer │
└────┬─────┘ │
└──▶ Rohbilder │
(Training) │
```
**Die Verbindung geht nur in eine Richtung.** Der Detector meldet ausgehend an
`/api/sightings/`; die Web-App muss weder Kamera noch Erkennungs-Host jemals
erreichen. Damit muss im Heimnetz kein einziger Port nach außen offen sein —
kein Portforwarding, kein Tunnel, keine dynamische DNS. Genau deshalb kann die
Sammlung öffentlich stehen, während die Kameras es nicht sind.
Warum überhaupt getrennt? Ein Raspberry Pi Zero kann streamen, aber nicht
rechnen. Umgekehrt kennt die Web-App weder numpy noch LiteRT, was ihren
Container klein hält.
## Dokumentation
| Kapitel | worum es geht |
|---|---|
| **[Installation](docs/installation.md)** | mit und ohne Docker, Schritt für Schritt |
| **[Die Kamera anschließen](docs/kamera.md)** | Stream-Formate, Schwellwerte — und wie groß ein Vogel im Bild sein muss |
| **[Wie die Erkennung funktioniert](docs/erkennung.md)** | drei Stufen, der Artenfilter, was das Modell nicht kann |
| **[Wie gut ist das wirklich](docs/genauigkeit.md)** | gemessene Zahlen, und was im Feld tatsächlich passiert ist |
| **[Einstellungen](docs/einstellungen.md)** | alle Variablen, und was stattdessen im Admin geht |
| **[Betrieb](docs/betrieb.md)** | mehrere Kameras, Live-Bild, Deployment |
| **[Entwicklung](docs/entwicklung.md)** | Tests, Übersetzungen, Artenkatalog erweitern |
| **[Datenquellen und Lizenzen](docs/datenquellen.md)** | woher Modelle und Fotos kommen |
Die Kameraseiten haben eigene Anleitungen: **[pi/](pi/README.md)** und
**[esp32cam/](esp32cam/README.md)**.
## Was es (noch) nicht kann
Ehrlicher als eine Merkmalsliste:
- ⚠️ **Der Katalog ist mitteleuropäisch.** 148 in Deutschland vorkommende Arten;
der Klassifikator rechnet seine Wahrscheinlichkeiten auf genau diese Liste
um. Das Modell selbst kennt rund 965 Arten weltweit — die Begrenzung ist der
Katalog, nicht die Erkennung. Die Region ist umschaltbar
(`VOGELALBUM_REGION`), es fehlen nur die Artenlisten anderer Regionen. Das ist
reine Datenarbeit und ein guter erster Beitrag.
- **Acht heimische Arten kennt das Modell nicht** und ordnet sie Verwandten zu
(Sumpf-, Weiden-, Haubenmeise, Gartenbaumläufer, Kleinspecht, Bluthänfling,
Kernbeißer, Waldkauz). Details in [docs/erkennung.md](docs/erkennung.md).
- **Der Aufbau entscheidet mehr als die Software.** Ein Vogel braucht 5–8 % der
Bildfläche, sonst findet ihn niemand. `python -m detector karte` misst das
vorher, statt es hinterher zu lernen — siehe [docs/kamera.md](docs/kamera.md).
## Mitmachen
Fehler, Ideen und Code sind willkommen. Die Spielregeln — und die
Rechteeinräumung, die für die Doppellizenzierung nötig ist — stehen in
**[CONTRIBUTING.md](CONTRIBUTING.md)**. Eine Sicherheitslücke bitte nicht als
Issue, sondern nach **[SECURITY.md](SECURITY.md)**.
Was sich wann geändert hat: **[CHANGELOG.md](CHANGELOG.md)**.
## Lizenz
**GNU Affero General Public License 3.0** ([LICENSE](LICENSE)). Benutzen,
verändern und weitergeben ist erlaubt; wer eine veränderte Fassung als Dienst
über ein Netz anbietet, muss deren Quelltext zugänglich machen. Für den Betrieb
im eigenen Garten ändert das nichts. Kommerzielle Nutzung ohne Offenlegung ist
über eine gesonderte Lizenz möglich: <webmaster@gaertner.onl>.
Modelle (Apache 2.0) und Referenzfotos aus Wikimedia Commons (meist CC BY-SA)
behalten ihre eigenen Lizenzen — Einzelheiten in
[docs/datenquellen.md](docs/datenquellen.md).
---
<div align="center">
<sub>Kein Bild dieses Projekts verlässt das eigene Netz, außer man deployt die
Web-App selbst irgendwohin. Es gibt keine Telemetrie und keine Aufrufe an
Dritte außer den ausdrücklich angestoßenen Downloads von Modellen und
Referenzfotos.</sub>
</div>