[general]
name=Bambi - QGIS Integration
qgisMinimumVersion=3.22
description=Detect and track wildlife in drone videos/photos with geo-referencing
version=5.2.0
author=Christoph Praschl, Anna Maschek, David C.Schedl
email=christoph.praschl@fh-hagenberg.at

about=A comprehensive QGIS plugin for detecting, tracking, and geo-referencing wildlife in aerial drone recordings (videos or still photos) from DJI Enterprise drones with thermal and/or RGB cameras.
    Features include:
    - Frame extraction and undistortion from drone videos (SRT timestamps) or photo collections (EXIF)
    - Animal detection using YOLO models (auto-downloaded from HuggingFace)
    - Multi-object tracking with built-in, BoxMOT, or geo-referenced backends; import of pre-computed TRex tracklets
    - Geo-referencing of detections, tracks, and SAM3 segmentations onto a DEM (real-world UTM coordinates)
    - Flight route visualization and perpendicular distance sampling for transect-based surveys
    - Survey analytics: kernel-density heatmaps, line-transect distance-sampling density/abundance estimation (from detections or tracks), and transect-based population estimation (naive, bootstrap, zero-inflated negative binomial)
    - Per-frame camera field-of-view footprints and coverage areas
    - Georeferenced map products: per-frame GeoTIFFs, true orthomosaics, and ALFS light-field mosaics
    - DEM import: automatic download (Austria), GeoTIFF conversion, or flat surface meshes for aquatic surveys
    - Calibration wizards for camera intrinsics (single-camera SfM, stereo RGB+thermal) and per-flight pose corrections
    - Companion tools: result video creator, radiometric thermal image viewer (DJI Thermal SDK), randomized transect flight planner, and interactive map-canvas inspectors
    - Key-frame based labelling tool: review detections/tracks on extracted frames (thermal or RGB), draw and edit track bounding boxes with species/sex/age/occlusion classes, interpolate between key frames, and propagate boxes of one or several tracks across frames via DEM geo-referencing
    - Transect splitting tool: split a flight into named transects (frame ranges) on the extracted frames, with a flight-route overview map, flight-path length measurement and an "end after X metres" helper
    - Built-in dependency manager to install all required and optional packages from within QGIS
    All results are automatically added as styled layers to the QGIS project.

changelog=Version 5.2.0:
    Added:
    - Thermal tone-curve mapping: both the Thermal Image Viewer and the photo-extraction thermal visualisation now offer a "Curve (custom mapping)" mode as a fine-granular alternative to the lower/upper thresholds — a curve with draggable control points maps a fixed temperature range to display intensity (with a live temperature histogram). The range can be entered manually or determined via "Auto Detect", which scans the flight's thermal images for the actual minimum/maximum temperature. The curve is stored in the QGIS project.
    - Labelling tool: new "Replace detections in project" button that replaces the existing detections/tracks instead of appending to them.
    - Labelling tool: new "Import all as label tracks" button to import every pipeline track at once instead of one by one.
    - Labelling tool: now supports to merge/split tracks
    - Labelling tool: the geo-referenced propagation now works on several tracks at once — select multiple tracks in the track list (Ctrl/Shift click) and the boxes of every selected track on the current frame are propagated in one step (the DEM is loaded once). Tracks without a box on the current frame, or whose box cannot be projected, are skipped instead of aborting the run and are listed in a summary afterwards.
    - Processing tool: Now also supports the "no images" flag of the pose extractors for debugging purposes.
    Changed:
    - Generate Flight Route is now also usable without frame extraction, based only on the AirData file (camera positions are skipped).
    - Add Tracks to QGIS now allows filtering tracks between a start and an end frame.
    - Detection models can now be configured separately for RGB and thermal recordings (previously a single model was used for both).
    - Distance sampling and transect-based population estimation can now pool the outputs of multiple projects into one combined estimate.
    - Detect Animals now shows an Ultralytics license notice (AGPL-3.0; commercial use requires an Ultralytics Enterprise License) before running; cancelling aborts the detection, and a "Remember my decision" checkbox skips the notice in subsequent runs.
    - Processing tool: Added a label about the target CRS input form, that we need a UTM CRS.
    Fixed:
    - Frame GeoTIFF export: the antialiased edge of each frame's footprint left a thin dark rim (alpha > 0 but the RGB bled towards black), which showed up as seams wherever frames overlapped in the orthomosaic. Each frame's valid footprint is now eroded inward by a configurable number of pixels (new "Erode px" control next to "Export Frames as GeoTIFF", default 2) before saving, so neighbouring frames cover the rim; set it to 0 to disable.
    - GeoTIFF to mesh conversion: DEMs with a compound CRS (e.g. Dutch AHN tiles tagged "Amersfoort / RD New + NAP height") were converted without reprojection and silently mislabeled with the target CRS, placing the mesh hundreds of kilometres from the flight and yielding empty geo-referencing results. The CRS is now identified via GDAL when rasterio cannot read it, and the conversion fails with a clear message if the source CRS cannot be determined.
    - GeoTIFF to mesh conversion now supports any UTM target zone (previously only zones 32-34) and EPSG:28992 (Dutch RD New) as a source CRS, including its Bessel datum shift.
    - Re-tagging a GeoTIFF with a source CRS override failed with newer rasterio versions (read-only LIBERTIFF driver).
    Version 5.1.0:
    Added:
    - Transect splitting tool: define named transects as start/end frame ranges of a flight, with a flight-route overview map highlighting the current frame's position, flight-path length measurement between start and end, and an "end after X metres" helper. Definitions are saved to transects_{t,w}/transects.json (+ .csv) in the output folder and loaded automatically.
    - Survey analytics: transect-based population estimation with three estimators (naive, bootstrap and zero-inflated negative binomial regression), ported from the R analysis of Praschl et al. 2026 and validated against it. Tracks are assigned to the transect nearest in perpendicular distance (with an optional truncation), and a transect's monitored area is the union of its frames' field-of-view footprints. Requires the transect definitions, "Calculate Field of View" and "Calculate Track Perpendicular"; results are written to analytics_{t,w}/population_estimate.json plus per-transect and per-track CSVs, and the transects can be loaded into QGIS as one layer group each (its merged field of view, its sub-flight route and the tracks assigned to it), nested under a "BAMBI Transect Areas" group. An optional study area (entered manually or derived from the flight's total field-of-view coverage) extrapolates every density to an abundance.
    Changed:
    - Labelling tool: considering masks during frame propagation; allows to move/rescale all bounding boxes of a track simultaneously
    Version 5.0.0:
    Added:
    - Labelling tool: key-frame based review and annotation of detections/tracks on extracted frames. Draw and edit track bounding boxes, assign species/sex/age/occlusion classes, interpolate between key frames, mark stop frames, and propagate boxes across frames via DEM geo-referencing. Includes a "Copy labels from RGB/Thermal" action that time-matches and reprojects labels between both modalities, plus user-defined custom label fields.
    - Result video creator: renders annotated result videos from processed flights.
    - Survey analytics: kernel-density heatmaps (points/ha) and line-transect distance sampling for density and abundance estimation, computed from either detections or tracks.
    - Coverage map tool: per-pixel frame-overlap count raster for a flight.
    - TRex tracklet import: pre-computed TRex tracklets can now be imported directly from the tracking configuration.
    - True orthomosaic export: a new step that merges the per-frame GeoTIFFs into a real orthomosaic (methods: first, last, min, max, average).
    - Pixel-based track export: converts geo-referenced tracks back into pixel-space tracks.
    - Manual padding input for flat-surface DEM generation.
    Changed:
    - BREAKING: what previous versions called "orthomosaic" was in fact a light-field mosaic and is now called "ALFS", with its config key renamed from "orthomosaic" to "alfs". The "orthomosaic" key still exists but now selects the new true-orthomosaic step, so an unmodified v4 config will silently run a different algorithm. Rename "orthomosaic" to "alfs" in existing configs to keep the previous behaviour.
    - Correction wizard reworked around an analytic tz/rz solver instead of a brute-force probe.
    - DEM and Target form groups reordered, since downloaded/created DEMs are written to the target folder.
    - Plugin settings are reset when a new QGIS project is opened.
    - Scrollbars added to the labelling and video creator dialogs; video creator dialog refined; minor default settings adjusted.
    - Bumped the required bambi-detection version.
    Fixed:
    - SRT/AirData timestamp offsets caused by timezone shifts.
    - Field-of-view footprint computation.
    - GeoTIFF and orthomosaic georeferencing bugs; added a GeoTIFF size sanity check.
    - Orthomosaic generation failure during mosaic assembly.
    - Processing step ordering and status-code signalling.
    - Duplicated camera selector in the TRex import dialog.
    - Consistency of pixel-based tracks.

tracker=https://github.com/bambi-eco/Bambi-QGIS/issues
repository=https://github.com/bambi-eco/Bambi-QGIS
tags=wildlife,detection,tracking,drone,thermal,YOLO,geo-referencing

homepage=https://github.com/bambi-eco/Bambi-QGIS
category=Analysis
icon=icons/icon.png
experimental=True
deprecated=False
