Skip to content

Commit b3cd865

Browse files
authored
Merge pull request #74 from BasisResearch/db-tracking-studio
tracking studio
2 parents 5e99399 + d2ff6e1 commit b3cd865

22 files changed

Lines changed: 3316 additions & 55 deletions

.dockerignore

Lines changed: 6 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,7 @@
1-
# Git
2-
.git
3-
.gitignore
1+
# Exclude everything by default
2+
*
43

5-
# Python
6-
__pycache__/
7-
*.py[cod]
8-
*$py.class
9-
*.so
10-
.Python
11-
build/
12-
develop-eggs/
13-
dist/
14-
downloads/
15-
eggs/
16-
.eggs/
17-
lib/
18-
lib64/
19-
parts/
20-
sdist/
21-
var/
22-
wheels/
23-
*.egg-info/
24-
.installed.cfg
25-
*.egg
26-
27-
# Virtual Environment
28-
venv/
29-
env/
30-
ENV/
31-
32-
# IDE
33-
.idea/
34-
.vscode/
35-
*.swp
36-
*.swo
37-
38-
# Docker
39-
Dockerfile
40-
.dockerignore
41-
42-
# Documentation
43-
docs/
44-
*.md
45-
*.rst
46-
47-
# Tests
48-
tests/
49-
.pytest_cache/
50-
.coverage
51-
htmlcov/
52-
53-
# Misc
54-
.DS_Store
4+
# Allow only what the Dockerfile needs
5+
!collab_env/
6+
!scripts/
7+
!pyproject.toml

.gcloudignore

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Upload only what the Docker build needs
2+
# .gcloudignore controls what gcloud builds submit uploads
3+
4+
# Start by ignoring everything
5+
*
6+
7+
# Allow only what Dockerfile.tracking-studio needs
8+
!collab_env/
9+
!scripts/
10+
!pyproject.toml
11+
!Dockerfile.tracking-studio
12+
!cloudbuild.yaml
13+
!.dockerignore

Dockerfile.tracking-studio

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
FROM python:3.10-slim
2+
3+
# Install system dependencies
4+
RUN apt-get update && apt-get install -y \
5+
ffmpeg \
6+
libgl1 \
7+
libglib2.0-0 \
8+
libsm6 \
9+
libxext6 \
10+
libxrender-dev \
11+
&& rm -rf /var/lib/apt/lists/*
12+
13+
# Install uv for fast dependency resolution
14+
RUN pip install uv
15+
16+
WORKDIR /workspace
17+
18+
# Install CPU-only PyTorch first (prevents ultralytics pulling 900MB CUDA version)
19+
RUN uv pip install --system --no-cache \
20+
torch torchvision --index-url https://download.pytorch.org/whl/cpu
21+
22+
# Install Python dependencies (Roboflow models load via .pt download, no inference SDK needed)
23+
COPY pyproject.toml .
24+
RUN uv pip install --system --no-cache \
25+
nicegui \
26+
ultralytics \
27+
supervision \
28+
google-cloud-storage \
29+
gcsfs \
30+
opencv-python-headless \
31+
pandas \
32+
numpy \
33+
loguru
34+
35+
# Copy application code
36+
COPY collab_env/ collab_env/
37+
COPY scripts/ scripts/
38+
39+
# Create model cache and tmp directories
40+
RUN mkdir -p /workspace/models
41+
RUN mkdir -p /tmp/videos /tmp/outputs /tmp/uploads
42+
43+
ENV PORT=8080
44+
ENV PYTHONUNBUFFERED=1
45+
ENV PYTHONPATH=/workspace
46+
ENV NICEGUI_RELOAD=false
47+
48+
CMD ["python", "scripts/tracking/run_tracking_studio.py"]

README.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,5 +117,6 @@ Detailed documentation for specific modules:
117117
* `GNN Training <docs/gnn/GNNReadMe.md>`_ - Graph Neural Network training and rollouts
118118
* `Simulation <docs/sim/README.md>`_ - Boids simulation and output format
119119
* `Tracking <docs/tracking/README.md>`_ - Animal tracking and thermal video processing
120+
* `Tracking Studio <docs/tracking/tracking_web_gui.md>`_ - Interactive web GUI for video object detection and tracking
120121

121122
For contributing guidelines, see `CONTRIBUTING.md <CONTRIBUTING.md>`_.

cloudbuild.yaml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
steps:
2+
- name: 'gcr.io/cloud-builders/docker'
3+
args:
4+
- 'build'
5+
- '-t'
6+
- 'gcr.io/$PROJECT_ID/tracking-studio:latest'
7+
- '-f'
8+
- 'Dockerfile.tracking-studio'
9+
- '.'
10+
11+
- name: 'gcr.io/cloud-builders/docker'
12+
args: ['push', 'gcr.io/$PROJECT_ID/tracking-studio:latest']
13+
14+
- name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
15+
entrypoint: gcloud
16+
args:
17+
- 'run'
18+
- 'deploy'
19+
- 'tracking-studio'
20+
- '--image=gcr.io/$PROJECT_ID/tracking-studio:latest'
21+
- '--platform=managed'
22+
- '--region=us-central1'
23+
- '--memory=4Gi'
24+
- '--cpu=2'
25+
- '--timeout=900'
26+
- '--concurrency=1'
27+
- '--max-instances=5'
28+
- '--set-secrets=ROBOFLOW_API_KEY=roboflow-api-key:latest'
29+
- '--no-allow-unauthenticated'
30+
31+
images:
32+
- 'gcr.io/$PROJECT_ID/tracking-studio:latest'
33+
34+
options:
35+
machineType: 'N1_HIGHCPU_8'

collab_env/tracking/visualization.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ def overlay_tracks_on_video(
135135

136136
# Get frame size
137137
sample_frame = cv2.imread(str(frame_paths[0]))
138+
assert sample_frame is not None, f"Failed to read frame: {frame_paths[0]}"
138139
h, w = sample_frame.shape[:2]
139140
writer = cv2.VideoWriter(
140141
str(output_video),
@@ -146,6 +147,8 @@ def overlay_tracks_on_video(
146147
for frame_path in frame_paths:
147148
frame_idx = int(frame_path.stem.split("_")[-1])
148149
frame = cv2.imread(str(frame_path))
150+
if frame is None:
151+
continue
149152

150153
frame_tracks = df[df["frame"] == frame_idx]
151154
for _, row in frame_tracks.iterrows():
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
"""
2+
NiceGUI-based Video Tracking Studio
3+
4+
A web application for interactive video tracking with support for:
5+
- GCS bucket video browsing and upload
6+
- YOLO and Roboflow model selection
7+
- Real-time tracking visualization
8+
- ByteTrack with Re-ID support
9+
- CSV output export
10+
"""
11+
12+
__version__ = "0.1.0"

0 commit comments

Comments
 (0)