Lightweight insect detection and tracking using motion-based detection
Project description
BugSpot
Lightweight insect detection and tracking using motion-based GMM background subtraction, Hungarian algorithm tracking, and path topology analysis. Core library for B++ and Sensing Garden.
No ML framework dependencies — only requires OpenCV, NumPy, and SciPy.
Installation
pip install bugspot
Quick Start
Command Line
# Run with defaults
bugspot video.mp4
# Run with a custom config
bugspot video.mp4 --config detection_config.yaml --output results/
Python API
from bugspot import DetectionPipeline
pipeline = DetectionPipeline()
result = pipeline.process_video("video.mp4")
print(f"Confirmed: {len(result.confirmed_tracks)} tracks")
for track_id, track in result.confirmed_tracks.items():
print(f" Track {track_id[:8]}: {track.num_detections} detections, {track.duration:.1f}s")
for frame_num, crop in track.crops:
pass # feed crop to your classifier
if track.composite is not None:
import cv2
cv2.imwrite(f"track_{track_id[:8]}.jpg", track.composite)
Save Outputs to Disk
result = pipeline.process_video(
"video.mp4",
save_crops_dir="output/crops",
save_composites_dir="output/composites",
)
Continuous Operation (Multi-Chunk)
For processing video chunks where tracks persist across boundaries:
pipeline = DetectionPipeline(config)
for video_chunk in video_queue:
result = pipeline.process_video(video_chunk)
# Process results...
pipeline.clear() # Keep tracker state, clear detections
Single Video (Stateless)
For one-off processing without persistent state:
pipeline = DetectionPipeline(config)
result = pipeline.process_video("video.mp4")
pipeline.reset() # Full reset — clear everything including tracker
Pipeline
- Detection — GMM background subtraction → morphological filtering → shape filters → cohesiveness check
- Tracking — Hungarian algorithm matching with lost track recovery
- Topology Analysis — Path analysis confirms insect-like movement (vs plants/noise)
- Crop Extraction — Re-reads video to extract crop images for confirmed tracks
- Composite Rendering — Lighten blend on darkened background showing temporal trail
Configuration
See detection_config.yaml for all parameters with descriptions.
Resolution-independent units
Scene-scale pixel parameters are expressed as fractions of image dimensions, not as absolute pixels, so the same config works across resolutions. Two reference dimensions are used:
- Length → fraction of image width
W(keys:min_displacement,max_frame_jump,revisit_radius) - Area → fraction of image area
W * H(keys:min_area,max_area)
Fractions are resolved to absolute pixels at runtime via resolve_detection_params(params, W, H) once the frame size is known. The 1080 px column below shows the resolved pixel value for a 1080×1080 frame (width = 1080, area = 1 166 400) for intuition. morph_kernel_size is an exception — it stays in absolute NxN pixels since it targets sensor-level noise, not scene-scale features.
| Parameter | Default | 1080 px wide | Description |
|---|---|---|---|
| GMM | |||
gmm_history |
500 | — | Frames to build background model |
gmm_var_threshold |
16 | — | Foreground variance threshold |
| Morphological | |||
morph_kernel_size |
3 | 3 | Kernel size (NxN), absolute pixels |
| Cohesiveness | |||
min_largest_blob_ratio |
0.80 | — | Min largest blob / total motion |
max_num_blobs |
5 | — | Max blobs in detection |
min_motion_ratio |
0.15 | — | Min motion pixels / bbox area |
| Shape | |||
min_area |
0.0002 | ~233 px² | Min contour area, fraction of image area |
max_area |
0.035 | ~40 824 px² | Max contour area, fraction of image area |
min_density |
3.0 | — | Min area/perimeter ratio (unitless) |
min_solidity |
0.55 | — | Min convex hull fill ratio |
| Tracking | |||
min_displacement |
0.05 | 54 px | Min net movement, fraction of image width |
min_path_points |
10 | — | Min points for topology |
max_frame_jump |
0.1 | 108 px | Max jump between frames, fraction of image width |
max_lost_frames |
45 | — | Frames before track deleted |
max_area_change_ratio |
3.0 | — | Max area change ratio |
| Tracker Matching | |||
tracker_w_dist |
0.6 | — | Distance weight (0-1) |
tracker_w_area |
0.4 | — | Area weight (0-1) |
tracker_cost_threshold |
0.3 | — | Max cost for match |
| Topology | |||
max_revisit_ratio |
0.30 | — | Max revisited positions |
min_progression_ratio |
0.70 | — | Min forward progression |
max_directional_variance |
0.90 | — | Max heading variance |
revisit_radius |
0.05 | 54 px | Revisit radius, fraction of image width |
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file bugspot-0.3.2.tar.gz.
File metadata
- Download URL: bugspot-0.3.2.tar.gz
- Upload date:
- Size: 16.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/2.1.3 CPython/3.10.12 Linux/6.8.0-107-generic
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
af357f802135c5ae624b46df3628cf0a5ee87b780e28a5379b68c47b59ade6fc
|
|
| MD5 |
47959d8b7f4b09ad86e2133bcbb77bbb
|
|
| BLAKE2b-256 |
80739025afcca79d8f76cc476ef5aa3393cc82d09cec34b1c01860f73fb3e558
|
File details
Details for the file bugspot-0.3.2-py3-none-any.whl.
File metadata
- Download URL: bugspot-0.3.2-py3-none-any.whl
- Upload date:
- Size: 17.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/2.1.3 CPython/3.10.12 Linux/6.8.0-107-generic
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
58d4e6b9cb08151df09d1edfadf16ca1370aea7fdb083a8becef583c551b83a3
|
|
| MD5 |
0d6ecc5e4571a0dda3a3802bca2e3d5b
|
|
| BLAKE2b-256 |
6b7ee62013d2a81ce45e46fa502e3149181c4efca6c9c0f2cabdad3e2bbba9c5
|