# conservationtechlab/cougarvision architecture

> Architecture diagram of the GitHub repository conservationtechlab/cougarvision, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-06-22). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/conservationtechlab/cougarvision
- Repository: https://github.com/conservationtechlab/cougarvision

## Overview

1. **What this repo is**
   CougarVision is a set of command-line pipelines for wildlife camera-trap analysis, not a single app. The code centers on one repeated pattern: ingest media, run Megadetector-based animal detection, crop detections, classify cropped animals with an Imagenet-style model, then optionally emit alerts or annotated outputs.

2. **Top-level execution entrypoints**
   The main workflows are separate scripts:
   - `fetch_and_alert.py` for retrieving images from Strikeforce and email attachments, then alerting on detections
   - `stream_detect.py` for live stream inference and optional recording
   - `run_batch_images.py` for folder-based batch processing and annotation
   - `annotate_video.py` for video annotation
   - `test_rtsp.py` as a stream connectivity/test utility  
   This is a pipeline-style repo where each script is an orchestrator over shared utilities.

3. **Shared processing library**
   Most reusable logic lives in `cougarvision_utils/`. The notable responsibilities are:
   - detection inference helpers in `detect_img.py`
   - crop generation in `cropping.py` and `ImageCropGenerator.py`
   - image acquisition in `get_images.py`
   - alert formatting/sending in `alert.py`
   - email ingestion in `fetch_emails.py`
   - logging helpers in `log_utils.py`
   - generic utilities in `more_utils.py`  
   The entrypoint scripts are thin coordinators around these modules.

4. **Core vision pipeline**
   The system’s main data flow is: input image/video frame → Megadetector animal detection → bounding-box crop generation → secondary classifier on crops → final label decision.  
   The README makes clear that the detector is Megadetector v5/PyTorch-compatible, while the classifier is interchangeable and model-specific. The repo is designed so detector and classifier model paths can be configured per workflow.

5. **Input sources and acquisition boundaries**
   CougarVision supports several upstream media sources:
   - local image folders for batch processing
   - video files for annotation
   - live RTSP-like streams
   - Strikeforce camera trap downloads
   - email inboxes with image attachments  
   These are distinct ingestion boundaries, but they all feed the same downstream detection/classification/alerting pipeline.

6. **Strikeforce integration**
   `fetch_and_alert.py` depends on Strikeforce credentials and camera metadata. The helper scripts `strikeforceget.py` and `strikeforcegetcameras.py` are used to obtain the auth token and camera IDs. This creates a specific operational dependency on Strikeforce’s API and camera naming conventions, including the repo’s requirement that camera names be 4 characters long for downstream mapping.

7. **Alerting and external response**
   `fetch_and_alert.py` and `stream_detect.py` can trigger alerts when target species are detected. The README mentions email/text alerts and optional EarthRanger event creation. That means the post-inference boundary is not just output generation; it can also push events into external operational systems. EarthRanger integration depends on matching camera names between the local config and the EarthRanger instance.

8. **Batch output and artifacts**
   `run_batch_images.py` produces annotated images and JSON outputs. The README describes two important artifacts:
   - an intermediate JSON for crop detections
   - a final `output.json` for crop-level classifications  
   This implies a two-stage output model: first detection/cropping metadata, then final classification results. Batch runs also write rendered images and supporting data under configured output directories.

9. **Streaming-specific behavior**
   `stream_detect.py` is the live-analysis path. It not only runs inference on frames, but can trigger recording when a cougar or lizard remains present. That makes it a stateful, continuous pipeline with temporal behavior, unlike the stateless batch scripts.

10. **Configuration as the orchestration layer**
   The `config/` directory contains separate YAML files for each workflow: `fetch_and_alert.yml`, `stream_detect.yml`, `run_batch_images.yml`, `annotate_video.yml`, and `cameratraps.yml`. These configs define model paths, credentials, camera mappings, output directories, and integration toggles. In practice, the architecture is “same code, different config-driven deployment modes.”

11. **Model and label assets**
   The `labels/` directory stores class lists and mappings such as `megadetector.names`, `labels_map.txt`, and region-specific label sets. This indicates the classifier layer is label-file driven and likely supports multiple deployment geographies/species sets without code changes.

12. **Runtime and dependency environment**
   The repo is built around Conda environments (`cougarvision_env.yml`, `mlgpuenv.yml`) and an external `CameraTraps` checkout that is added to the Python path at runtime. That matters architecturally because inference is coupled to external ML tooling rather than being fully self-contained in this repo.

13. **Operational outputs and logs**
   The README calls for separate `images` and `logs` directories, with local storage for downloaded media and per-image detection dataframes/logs. `stream.log` also exists at the repo root, suggesting live runs produce persistent operational logs alongside media artifacts.

14. **Architectural summary**
   The cleanest diagram for this repo is: multiple media sources and integrations on the left, a shared detection/crop/classification core in the middle, and multiple sinks on the right: annotated files, JSON results, logs, alerts, email/text messages, and EarthRanger events. The same core pipeline is reused across batch, stream, and fetch/alert workflows, with config files determining which edges are active.

Main entry points: [`fetch_and_alert.py`](https://github.com/conservationtechlab/cougarvision/blob/master/fetch_and_alert.py) (Fetch & alert), [`run_batch_images.py`](https://github.com/conservationtechlab/cougarvision/blob/master/run_batch_images.py) (Batch images), [`stream_detect.py`](https://github.com/conservationtechlab/cougarvision/blob/master/stream_detect.py) (Stream detect), [`cougarvision_utils/detect_img.py`](https://github.com/conservationtechlab/cougarvision/blob/master/cougarvision_utils/detect_img.py) (Detection)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_entrypoints["Entry scripts"]
  node_fetch_and_alert["Fetch & alert<br/>pipeline orchestrator<br/>[fetch_and_alert.py]"]
  node_stream_detect["Stream detect<br/>live pipeline<br/>[stream_detect.py]"]
  node_run_batch_images["Batch images<br/>batch pipeline"]
  node_annotate_video["Annotate video<br/>video pipeline<br/>[annotate_video.py]"]
  node_test_rtsp["RTSP test<br/>connectivity tool<br/>[test_rtsp.py]"]
end

subgraph group_utils["Shared utils"]
  node_detect_img{{"Detection<br/>megadetector inference<br/>[detect_img.py]"}}
  node_cropping{{"Cropping<br/>bbox cropper<br/>[cropping.py]"}}
  node_cropgen{{"Crop generator<br/>crop iterator"}}
  node_get_images{{"Image intake<br/>media acquisition<br/>[get_images.py]"}}
  node_fetch_emails{{"Email fetch<br/>mail ingestion<br/>[fetch_emails.py]"}}
  node_alert{{"Alerting<br/>notification<br/>[alert.py]"}}
  node_log_utils["Logging<br/>[log_utils.py]"]
  node_more_utils["Helpers<br/>misc utilities<br/>[more_utils.py]"]
  node_strikeforceget["Strikeforce auth<br/>api helper<br/>[strikeforceget.py]"]
  node_strikeforcegetcameras["Camera lookup<br/>api helper"]
end

subgraph group_config["Config and assets"]
  node_configs["YAML configs<br/>workflow config"]
  node_labels["Label sets<br/>class labels"]
  node_envs["Conda envs<br/>runtime env"]
  node_cameratraps["Camera traps<br/>mapping config<br/>[cameratraps.yml]"]
end

subgraph group_external["External systems"]
  node_camera_traps[("Camera Traps<br/>external ML dependency")]
  node_strikeforce_api(("Strikeforce<br/>external api"))
  node_earthranger(("EarthRanger<br/>external system"))
  node_email_system(("Email inbox<br/>external mailbox"))
end

node_fetch_and_alert -->|"auth"| node_strikeforceget
node_fetch_and_alert -->|"camera ids"| node_strikeforcegetcameras
node_fetch_and_alert -->|"ingest"| node_get_images
node_fetch_and_alert -->|"mail ingest"| node_fetch_emails
node_fetch_and_alert -->|"detect"| node_detect_img
node_fetch_and_alert -->|"crop"| node_cropping
node_fetch_and_alert -->|"notify"| node_alert
node_fetch_and_alert -->|"logs"| node_log_utils
node_stream_detect -->|"frames"| node_get_images
node_stream_detect -->|"detect"| node_detect_img
node_stream_detect -->|"crop"| node_cropping
node_stream_detect -->|"notify"| node_alert
node_stream_detect -->|"logs"| node_log_utils
node_run_batch_images -->|"ingest"| node_get_images
node_run_batch_images -->|"detect"| node_detect_img
node_run_batch_images -->|"crop"| node_cropping
node_run_batch_images -->|"iterate"| node_cropgen
node_run_batch_images -->|"helpers"| node_more_utils
node_run_batch_images -->|"logs"| node_log_utils
node_annotate_video -->|"read video"| node_get_images
node_annotate_video -->|"detect"| node_detect_img
node_annotate_video -->|"crop"| node_cropping
node_test_rtsp -->|"probe"| node_get_images
node_detect_img -.->|"model support"| node_camera_traps
node_cropping -->|"generate"| node_cropgen
node_fetch_emails -->|"read inbox"| node_email_system
node_alert -->|"send mail"| node_email_system
node_alert -->|"events"| node_earthranger
node_strikeforceget -->|"token"| node_strikeforce_api
node_strikeforcegetcameras -->|"metadata"| node_strikeforce_api
node_configs -.->|"mode"| node_fetch_and_alert
node_configs -.->|"mode"| node_stream_detect
node_configs -.->|"mode"| node_run_batch_images
node_configs -.->|"mode"| node_annotate_video
node_labels -->|"classes"| node_detect_img
node_envs -.->|"runtime"| node_camera_traps
node_cameratraps -.->|"mapping"| node_earthranger

click node_fetch_and_alert "https://github.com/conservationtechlab/cougarvision/blob/master/fetch_and_alert.py"
click node_stream_detect "https://github.com/conservationtechlab/cougarvision/blob/master/stream_detect.py"
click node_run_batch_images "https://github.com/conservationtechlab/cougarvision/blob/master/run_batch_images.py"
click node_annotate_video "https://github.com/conservationtechlab/cougarvision/blob/master/annotate_video.py"
click node_test_rtsp "https://github.com/conservationtechlab/cougarvision/blob/master/test_rtsp.py"
click node_detect_img "https://github.com/conservationtechlab/cougarvision/blob/master/cougarvision_utils/detect_img.py"
click node_cropping "https://github.com/conservationtechlab/cougarvision/blob/master/cougarvision_utils/cropping.py"
click node_cropgen "https://github.com/conservationtechlab/cougarvision/blob/master/cougarvision_utils/ImageCropGenerator.py"
click node_get_images "https://github.com/conservationtechlab/cougarvision/blob/master/cougarvision_utils/get_images.py"
click node_fetch_emails "https://github.com/conservationtechlab/cougarvision/blob/master/cougarvision_utils/fetch_emails.py"
click node_alert "https://github.com/conservationtechlab/cougarvision/blob/master/cougarvision_utils/alert.py"
click node_log_utils "https://github.com/conservationtechlab/cougarvision/blob/master/cougarvision_utils/log_utils.py"
click node_more_utils "https://github.com/conservationtechlab/cougarvision/blob/master/cougarvision_utils/more_utils.py"
click node_strikeforceget "https://github.com/conservationtechlab/cougarvision/blob/master/cougarvision_utils/strikeforceget.py"
click node_strikeforcegetcameras "https://github.com/conservationtechlab/cougarvision/blob/master/cougarvision_utils/strikeforcegetcameras.py"
click node_configs "https://github.com/conservationtechlab/cougarvision/tree/master/config"
click node_labels "https://github.com/conservationtechlab/cougarvision/tree/master/labels"
click node_envs "https://github.com/conservationtechlab/cougarvision/blob/master/cougarvision_env.yml"
click node_cameratraps "https://github.com/conservationtechlab/cougarvision/blob/master/config/cameratraps.yml"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_fetch_and_alert,node_stream_detect,node_run_batch_images,node_annotate_video,node_test_rtsp toneBlue
class node_detect_img,node_cropping,node_cropgen,node_get_images,node_fetch_emails,node_alert,node_log_utils,node_more_utils,node_strikeforceget,node_strikeforcegetcameras toneAmber
class node_configs,node_labels,node_envs,node_cameratraps toneMint
class node_camera_traps,node_strikeforce_api,node_earthranger,node_email_system toneRose
```

## Components

### Entry scripts

Top-level workflow orchestrators for batch, streaming, annotation, and alerting.

- [Fetch & alert](https://github.com/conservationtechlab/cougarvision/blob/master/fetch_and_alert.py): pipeline orchestrator · Downloads camera trap and email images, runs detection/classification, and sends alerts. · `fetch_and_alert.py`
- [Stream detect](https://github.com/conservationtechlab/cougarvision/blob/master/stream_detect.py): live pipeline · Processes live frames from a stream, with optional recording on target species. · `stream_detect.py`
- [Batch images](https://github.com/conservationtechlab/cougarvision/blob/master/run_batch_images.py): batch pipeline · Folder-based image processing that writes annotations and JSON outputs. · `run_batch_images.py`
- [Annotate video](https://github.com/conservationtechlab/cougarvision/blob/master/annotate_video.py): video pipeline · Annotates video files using the shared detection and classification flow. · `annotate_video.py`
- [RTSP test](https://github.com/conservationtechlab/cougarvision/blob/master/test_rtsp.py): connectivity tool · Utility for testing stream connectivity and RTSP access. · `test_rtsp.py`

### Shared utils

Reusable media acquisition, vision, alerting, and support modules.

- [Detection](https://github.com/conservationtechlab/cougarvision/blob/master/cougarvision_utils/detect_img.py): megadetector inference · Runs image detection and produces animal bounding boxes. · `cougarvision_utils/detect_img.py`
- [Cropping](https://github.com/conservationtechlab/cougarvision/blob/master/cougarvision_utils/cropping.py): bbox cropper · Converts detections into crops for downstream classification. · `cougarvision_utils/cropping.py`
- [Crop generator](https://github.com/conservationtechlab/cougarvision/blob/master/cougarvision_utils/ImageCropGenerator.py): crop iterator · Generates and manages image crop sequences. · `cougarvision_utils/ImageCropGenerator.py`
- [Image intake](https://github.com/conservationtechlab/cougarvision/blob/master/cougarvision_utils/get_images.py): media acquisition · Loads images from folders, streams, or other sources into the pipeline. · `cougarvision_utils/get_images.py`
- [Email fetch](https://github.com/conservationtechlab/cougarvision/blob/master/cougarvision_utils/fetch_emails.py): mail ingestion · Retrieves image attachments from email inboxes. · `cougarvision_utils/fetch_emails.py`
- [Alerting](https://github.com/conservationtechlab/cougarvision/blob/master/cougarvision_utils/alert.py): notification · Formats and sends alerts for target detections. · `cougarvision_utils/alert.py`
- [Logging](https://github.com/conservationtechlab/cougarvision/blob/master/cougarvision_utils/log_utils.py): runtime logging · Shared logging helpers for workflow execution and outputs. · `cougarvision_utils/log_utils.py`
- [Helpers](https://github.com/conservationtechlab/cougarvision/blob/master/cougarvision_utils/more_utils.py): misc utilities · Generic utility functions used across workflows. · `cougarvision_utils/more_utils.py`
- [Strikeforce auth](https://github.com/conservationtechlab/cougarvision/blob/master/cougarvision_utils/strikeforceget.py): api helper · Obtains Strikeforce access tokens for camera trap downloads. · `cougarvision_utils/strikeforceget.py`
- [Camera lookup](https://github.com/conservationtechlab/cougarvision/blob/master/cougarvision_utils/strikeforcegetcameras.py): api helper · Fetches Strikeforce camera IDs and metadata for mapping. · `cougarvision_utils/strikeforcegetcameras.py`

### Config and assets

Workflow configs, label mappings, and runtime environment files.

- [YAML configs](https://github.com/conservationtechlab/cougarvision/tree/master/config): workflow config · Per-workflow configuration files for models, credentials, outputs, and integration toggles. · `config`
- [Label sets](https://github.com/conservationtechlab/cougarvision/tree/master/labels): class labels · Species and detector label files used by the classifier and detector. · `labels`
- [Conda envs](https://github.com/conservationtechlab/cougarvision/blob/master/cougarvision_env.yml): runtime env · Environment definitions for ML and cougarvision execution. · `cougarvision_env.yml`
- [Camera traps](https://github.com/conservationtechlab/cougarvision/blob/master/config/cameratraps.yml): mapping config · Camera naming and deployment mapping for camera-trap workflows. · `config/cameratraps.yml`

### External systems

Outside services and dependencies that the pipelines integrate with.

- **Camera Traps**: external ML dependency · External CameraTraps checkout added to the Python path for inference support.
- **Strikeforce**: external api · Camera trap source system used for downloads and camera metadata.
- **EarthRanger**: external system · Optional event sink for alerts and operational reporting.
- **Email inbox**: external mailbox · Source of image attachments and destination for notifications.

## Connections

- Fetch & alert → Strikeforce auth: auth · Uses Strikeforce credentials to obtain access tokens.
- Fetch & alert → Camera lookup: camera ids · Resolves camera IDs and names for Strikeforce downloads.
- Fetch & alert → Image intake: ingest · Pulls media into the shared vision pipeline.
- Fetch & alert → Email fetch: mail ingest · Reads email attachments as an alternate input source.
- Fetch & alert → Detection: detect · Runs Megadetector inference on incoming images.
- Fetch & alert → Cropping: crop · Generates crops from detected bounding boxes.
- Fetch & alert → Alerting: notify · Sends detection alerts to external responders.
- Fetch & alert → Logging: logs · Writes workflow logs and operational status.
- Stream detect → Image intake: frames · Consumes live stream frames for inference.
- Stream detect → Detection: detect · Runs detection on stream frames.
- Stream detect → Cropping: crop · Creates target crops for downstream classification.
- Stream detect → Alerting: notify · Triggers alerts when target species appear.
- Stream detect → Logging: logs · Persists stream runtime logs.
- Batch images → Image intake: ingest · Loads images from folders for batch analysis.
- Batch images → Detection: detect · Detects animals in batch images.
- Batch images → Cropping: crop · Produces intermediate crop metadata.
- Batch images → Crop generator: iterate · Builds crop sequences for classification stages.
- Batch images → Helpers: helpers · Uses shared utility functions during orchestration.
- Batch images → Logging: logs · Records batch processing status and outputs.
- Annotate video → Image intake: read video · Extracts frames from video sources.
- Annotate video → Detection: detect · Runs detection over video frames.
- Annotate video → Cropping: crop · Uses detection boxes for annotations.
- RTSP test → Image intake: probe · Checks stream access and frame retrieval.
- Detection → Camera Traps: model support · Relies on external CameraTraps tooling for detector execution.
- Cropping → Crop generator: generate · Shares crop generation logic.
- Email fetch → Email inbox: read inbox · Consumes emails with image attachments.
- Alerting → Email inbox: send mail · Can deliver notifications via email.
- Alerting → EarthRanger: events · Can push detections into EarthRanger.
- Strikeforce auth → Strikeforce: token · Authenticates against the Strikeforce service.
- Camera lookup → Strikeforce: metadata · Reads Strikeforce camera listings and IDs.
- YAML configs → Fetch & alert: mode · Configures fetch-and-alert workflow behavior.
- YAML configs → Stream detect: mode · Configures stream workflow behavior.
- YAML configs → Batch images: mode · Configures batch workflow behavior.
- YAML configs → Annotate video: mode · Configures video annotation behavior.
- Label sets → Detection: classes · Provides detector and classifier label sets.
- Conda envs → Camera Traps: runtime · Defines the ML environment used with external tooling.
- Camera traps → EarthRanger: mapping · Supports camera-name alignment for external event creation.
