(Insect Detect) trigger capture.py

Aus TippvomTibb
Zur Navigation springen Zur Suche springen

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):

  1. 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).
  2. 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.
  3. 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)
  4. 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.
  5. 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)
  6. 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.py gibt es eine Haupt-Schleife, die:
    1. LQ-Frames vom OAK holt
    2. Detektionen + Tracking auswertet
    3. Auf Basis des Ergebnisses Flags setzt, z. B. insect_present = True/False
    4. 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)
    5. 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

      1. B. capture_interval_triggered → Zeitabstand zwischen zwei HQ-Frames, solange eine Insekten-Detektion aktiv ist.
  • Time-Lapse

      1. B. capture_interval_timelapse → unabhängig von Insekten, für regelmäßige Übersichtsbilder. (maxsitt.github.io)

→ 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:

  1. Die Model-Outputs (Bounding Boxes + Confidence) eingelesen werden.
  2. Daraus eine Liste/Dict der aktiven Tracks gebaut wird.
  3. Anhand dieser Liste entschieden wird, ob trigger_active gesetzt 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
    • Zeit­raffer-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.py
    

    oder automatisch via startup-Konfiguration. (maxsitt.github.io)