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.
78 lines
3.7 KiB
Markdown
78 lines
3.7 KiB
Markdown
# Wie die Erkennung funktioniert
|
|
|
|
<sub>[← zurück zum Überblick](../README.md) · [alle Kapitel](README.md)</sub>
|
|
|
|
Drei Stufen, ein Artenfilter und eine Abstimmung über den ganzen Besuch. Wer
|
|
nur wissen will, *ob* es funktioniert, ist in [Wie gut ist das
|
|
wirklich](genauigkeit.md) besser bedient — hier steht, *warum* es funktioniert.
|
|
|
|
Drei Stufen, jede filtert für die nächste vor.
|
|
|
|
**1. Bewegung** (`motion.py`, <1 ms) — Frame-Differencing gegen einen
|
|
gleitenden Hintergrund. Der zieht langsam nach, damit Sonnenstand und Wolken
|
|
keine Dauerbewegung auslösen; bei erkannter Bewegung *langsamer*, sonst frisst
|
|
sich ein still sitzender Vogel binnen Sekunden in den Hintergrund ein.
|
|
|
|
Diese Stufe lässt sich abschalten (`--gate detector`), und an unserer Kamera
|
|
ist das nötig: Sie schaut aus dem Futterhaus in eine Hecke, die im Wind steht.
|
|
Gemessen sind dort 6,9 % bewegte Pixel im Median und 95 % aller Bilder über der
|
|
Schwelle — als Vorfilter damit wertlos.
|
|
|
|
**2. Vogel ja/nein** (`classify.py`, ~15 ms) — SSD-MobileNet auf COCO. Sagt
|
|
nur, ob und wo ein Vogel im Bild ist. Verhindert, dass ein wackelnder Ast als
|
|
Kohlmeise in der Sammlung landet, und liefert den Ausschnitt für Stufe 3.
|
|
|
|
**3. Welche Art** (`classify.py`, ~25 ms) — MobileNetV2 auf iNaturalist,
|
|
965 Vogelarten, angewendet auf den zugeschnittenen Vogel statt aufs ganze Bild.
|
|
|
|
### Der Kniff mit dem Artenfilter
|
|
|
|
Das iNat-Modell ist Nordamerika-lastig. Ungefiltert wird aus einer Kohlmeise
|
|
gern eine *Carolina Chickadee* — die sieht ähnlich aus und ist im
|
|
Trainingsmaterial häufiger.
|
|
|
|
Der Katalog schränkt die Modellausgabe deshalb auf Arten ein, die hier
|
|
realistisch vorkommen, und normiert die Wahrscheinlichkeit neu. Der Anteil der
|
|
Wahrscheinlichkeitsmasse, der überhaupt auf heimische Arten fällt
|
|
(`bird_score`), ist dabei das eigentliche Gütemaß — nicht die Confidence des
|
|
Top-Treffers, denn die ist nach der Neunormierung per Konstruktion hoch. Liegt
|
|
`bird_score` unter `--min-bird-score`, sieht das Modell zwar sicher einen
|
|
Vogel, aber keinen von hier; die Sichtung wird dann als *unbestimmt*
|
|
gespeichert statt geraten.
|
|
|
|
`--habitats` engt weiter ein. Eine Kamera am Futterhaus soll gar nicht erst
|
|
erwägen, ob der Fleck auf dem Ast ein Kranich ist.
|
|
|
|
### Abstimmung über den ganzen Besuch
|
|
|
|
Eine einzelne Klassifikation ist wackelig: Von hinten ist eine Kohlmeise nur
|
|
eine olivgrüne Kugel. Die Einheit ist deshalb nicht das Bild, sondern der
|
|
**Besuch** — von der ersten Erkennung bis zu einigen Sekunden Ruhe.
|
|
|
|
Über den Besuch hinweg wird abgestimmt, gewichtet nach Detektor-Sicherheit,
|
|
Größe des Vogels im Bild und `bird_score`. Parallel wird das schärfste Foto
|
|
behalten (Varianz der Laplace-Antwort), damit in der Sammlung kein
|
|
verwackeltes Bild landet. Kippt die Abstimmung, wird die Sichtung als
|
|
unbestimmt gespeichert — eine Lücke im Dex ist besser als ein falscher
|
|
Eintrag, aus dem ein Kind etwas Falsches lernt.
|
|
|
|
### Was das Modell nicht kann
|
|
|
|
Sechs in Deutschland vorkommende Arten fehlen im Trainingsmaterial und werden
|
|
zwangsläufig auf verwandte Arten gemappt:
|
|
|
|
Sumpfmeise · Weidenmeise · Haubenmeise · Gartenbaumläufer · Kleinspecht ·
|
|
Waldkauz
|
|
|
|
`python -m detector species` listet das mit auf.
|
|
|
|
Der Weg dahin: eigene Bilder sammeln (`--save-to` tut genau das), im Admin von
|
|
Hand bestätigen (Feld *Von Hand bestätigt als*) und später ein eigenes Modell
|
|
nachtrainieren. Dann lernt es gleich die Beleuchtung und den Blickwinkel der
|
|
eigenen Kamera mit.
|
|
|
|
> **Beim Nachschlagen im Label-File aufpassen:** Es benutzt teils veraltete
|
|
> wissenschaftliche Namen. Der Bluthänfling steht dort als *Carduelis
|
|
> cannabina*, nicht als *Linaria cannabina* — wer nach dem heutigen Namen
|
|
> sucht, hält die Art fälschlich für eine Lücke.
|