(Insect Detect) trigger capture.py
Allgemeines
trigger_capture.py ist eines von zwei zentralen Scripts (webapp.py) auf dem Raspi.
Festures
- LQ-Videostream Auswertung
- Trigger bei (Insekten-)Erkennung
- Speichern eines HQ-Foto, oder mehrerer Frames.
- Speichern der einer MetaDatei (CSV) mit Timestamp, Label, Confidence Score, Tracker ID, Bounding Box Koordinaten
- Time-Lapse Capture Funktion
- Energiemanagement
MetaDatei
Felder:
- cam_ID Freitext
- rec_ID Bedeutung noch zu klaeren
- timestamp selbsterklaerend
- lens_postion Bedeutung noch zu klaeren
- iso_sensitivity Bedeutung noch zu klaeren
- exposure_time Bedeutung noch zu klaeren
- label vom DetectionsTrigger Bedeutung noch zu klaeren
- confidence vom DetectionsTrigger DetektionsSicherheit normiert auf 1 (1 = 100 Prozent)
- track_status Bedeutung noch zu klaeren
- x_min BoundingBox-Koordinate
- y_min BoundingBox-Koordinate
- x_max BoundingBox-Koordinate
- y_max BoundingBox-Koordinate
ergaenzt:
- x_size = x_max - x_min
- y_size = y_max - y_min
- x_start = x_min * 3840
- y_start = y_min * 2160
Die HQ-Fotos haben bei meinen Versuchen eine Aufloesung von 3840x2160. Mit den Start-Koordinaten und den Dimensionen (Size) konnte ich die BoundingBoxes zum Ueberpruefen in Gimp einfuegen.
cam_ID,rec_ID,timestamp,lens_position,iso_sensitivity,exposure_time,label,confidence,track_ID,track_status,x_min,y_min,x_max,y_max,x_size,y_size,x_start,y_start insdet-cam01,1,2025-08-26T19:37:56.028,154,1575,30,insect,0.69,1,TRACKED,0.2569,0.0026,0.3112,0.0824,208.512,172.368,986.496,5.616 insdet-cam01,1,2025-08-26T19:37:56.028,154,1575,30,insect,0.84,2,TRACKED,0.2038,0.7776,0.2667,0.9097,241.536,285.336,782.592,1679.616 insdet-cam01,1,2025-08-26T19:37:56.028,154,1575,30,insect,0.85,3,TRACKED,0.243,0.2083,0.3025,0.3196,228.48,240.408,933.12,449.928
CodeAnalyse
ChatGPT meint:
Kurz gesagt: trigger_capture.py ist das Aufnahmescript, das dauerhaft läuft und auf Basis der Insekten-Detektion entscheidet, wann und was aufgezeichnet wird. Die eigentliche „Magie“ – also der Trigger – passiert in der Kombination aus Detektions-Schwelle, Tracker und den Aufnahme-Intervallen, die du in der Config einstellst, nicht direkt hart im Code.
1. Was macht trigger_capture.py genau?
Aus der Doku und dem Repo ergibt sich grob dieser Ablauf (GitHub):
- Konfiguration laden
- Es liest die aktuell gewählte Config (
config_selector.yaml→ z. B.config_custom.yaml). - Darin stehen u. a.:
- Modellpfad (YOLO-Blob)
- Auflösung / FPS für LQ- und HQ-Stream
- Schwellwerte für Detektion
- Intervalle für Triggered Capture und Time-Lapse
- Pfade für Bilder/Metadaten
- Power-Management-Einstellungen (WittyPi / PiJuice).
- Es liest die aktuell gewählte Config (
- OAK-Kamera + Pipeline initialisieren
- LQ-Stream (runtergerechnet, z. B. 320×320) für Live-Detektion.
- HQ-Stream (z. B. 4K MJPEG) für Speichern von Bildern.
- Insekten-Detektion & Tracking
- Auf jedem LQ-Frame läuft das YOLO-Modell („insect“ als Klasse).
- Ein Tracker bekommt die Bounding Boxes und vergibt Tracking-IDs, damit ein Individuum über mehrere Frames verfolgt werden kann. (GitHub)
- Trigger-Logik
- Wenn mindestens eine gültige Insekten-Detektion vorliegt (Konfidenz über deiner Detektions-Schwelle, evtl. Mindest-Boxgröße etc.), setzt das Script intern sowas wie einen „Recording active“-Status.
- Solange dieser Status aktiv ist, werden HQ-Frames in einem bestimmten Intervall gespeichert („triggered capture“).
- Zusätzlich laufen unabhängig davon Time-Lapse-Aufnahmen (z. B. alle X Sekunden/Minuten), um den Hintergrundverlauf zu dokumentieren – auch ohne Insekten.
- Speichern von Bildern + Metadaten
- HQ-Frames → JPEG/PNG im Zielordner.
- Dazu eine Metadata-CSV pro Detektion mit:
- Timestamp
- Label („insect“)
- Confidence
- Tracking-ID
- Status (z. B. „new“, „tracked“, „lost“)
- Bounding-Box-Koordinaten. (GitHub)
- Optional: Power-Management
- Wenn ein WittyPi oder PiJuice konfiguriert ist, prüft das Script Ladezustand / Zeitfenster und passt Aufnahmedauer daran an. (GitHub)
2. Wo ist der Trigger im Code – und wie „steuert“ man ihn?
Da der direkte Codezugriff hier eingeschränkt ist, kann ich dir keine konkreten Zeilennummern zitieren – aber die Struktur ist so:
- In
trigger_capture.pygibt es eine Haupt-Schleife, die:- LQ-Frames vom OAK holt
- Detektionen + Tracking auswertet
- Auf Basis des Ergebnisses Flags setzt, z. B.
insect_present = True/False - In einem Timer / Zeitstempel-Vergleich prüft, ob:
- seit letzter gespeicherter Aufnahme genug Zeit vergangen ist (capture-Intervall)
- der Trigger noch aktiv ist (noch Insekten im Bild)
- Dann HQ-Frames vom zweiten Stream holt und speichert.
Wichtig: Die meisten Parameter, die dein Verhalten beeinflussen (Schwellen, Intervalle etc.), liegen NICHT als Magic Numbers im Script, sondern in config_custom.yaml und werden dort von dir (oder über die Web-App) gesetzt. (maxsitt.github.io)
3. Was kannst du praktisch anpassen – ohne Code zu ändern?
a) Detektions-Empfindlichkeit (weniger / mehr False Positives)
Machst du entweder in der Web-App (Software → Web App) oder direkt in configs/config_custom.yaml:
Typische Parameter dort (Namen können leicht variieren, aber sinngemäß):
- Konfidenz-Schwelle für YOLO
- Höher stellen → nur sichere Insekten werden getriggert, weniger Müll, aber mehr verpasste Tiere.
- Niedriger stellen → empfindlicher, mehr Trigger, aber mehr False Positives.
- Mindest-Boxgröße / -Fläche
- Verhindert Trigger durch ganz kleine Störungen (Rauschen, kleine Pollen/Flecken).
In der Web-App findest du das im Bereich „Detection“/„Model“‐Einstellungen; in der YAML irgendwas in Richtung detection: / confidence_threshold / min_box_area (o. ä.).
b) Wie oft Bilder gespeichert werden (wenn Insekten da sind)
In der Config gibt es getrennte Intervalle für:
Triggered Capture
- B.
capture_interval_triggered→ Zeitabstand zwischen zwei HQ-Frames, solange eine Insekten-Detektion aktiv ist.
- B.
Time-Lapse
- B.
capture_interval_timelapse→ unabhängig von Insekten, für regelmäßige Übersichtsbilder. (maxsitt.github.io)
- B.
→ Wenn du mehr Bilder pro Besuch willst: Trigger-Intervall verkürzen. → Wenn du Datenmenge reduzieren willst: Trigger-Intervall vergrößern, Time-Lapse seltener.
c) Wie lange der Trigger „nachläuft“
Meist gibt es eine Art „Nachlauf-Zeit“:
- „Wenn X Sekunden lang keine neue Detektion für eine laufende Tracking-ID kommt → Trigger-Status wieder auf false setzen.“
- Das verhindert, dass bei kurzen Frame-Aussetzern sofort alles stoppt.
In der Config könnte das etwas wie max_inactive_time / tracker_timeout o. ä. sein.
4. Was würdest du im Code selbst anfassen?
Nur, wenn du wirklich in die Logik eingreifen willst, z. B.:
- Andere Trigger-Bedingung:
- statt „mindestens 1 Insekt“ → „mindestens N Insekten“
- oder Trigger nur für bestimmte Größen / Positionen (z. B. nur mittlerer Bereich der Plattform).
Dann würdest du in trigger_capture.py an die Stelle gehen, an der:
- Die Model-Outputs (Bounding Boxes + Confidence) eingelesen werden.
- Daraus eine Liste/Dict der aktiven Tracks gebaut wird.
- Anhand dieser Liste entschieden wird, ob
trigger_activegesetzt wird.
Logisch wäre dort sowas wie (vereinfacht):
if any(det.conf > conf_thresh for det in detections):
trigger_active = True
last_detection_time = now
elif now - last_detection_time > timeout:
trigger_active = False
Das ist nicht der Originalcode, nur Pseudocode – aber so in etwa läuft es.
5. TL;DR für dich als Anwender
Ohne Code anzufassen kannst du:
Über Web-App → Config / Detection / Capture:
- Detektions-Schwelle (Empfindlichkeit) einstellen
- Trigger-Intervall (wie oft Bild bei Insekt) einstellen
- Zeitraffer-Intervall unabhängig vom Trigger setzen
- ggf. Tracker-/Time-out-Parameter anpassen
Das Script startest du wie in der Doku:
env_insdet/bin/python3 insect-detect/trigger_capture.pyoder automatisch via
startup-Konfiguration. (maxsitt.github.io)