Skip to content

Usage

Complete command-line reference for sample and calibrate executables.

Overview

  • sample: Extract diverse frames from video collection
  • calibrate: Analyze video metrics and tune thresholds

Both tools share common parameters for quality gates and metric computation.


sample — Frame Sampling

Extract a diverse subset of high-quality frames from a directory of videos.

Basic Usage

./sample --root-dir /path/to/videos --output-dir ./frames

Required Parameters

--root-dir <path>

Root directory containing .mp4 video files.

Example:

--root-dir /data/Triton/2025/09/04/Recordings

Common Parameters

--camera <int>

Camera index to process (matches Cam<N> in filename).

Default: 1

Example:

--camera 2  # Processes files like Triton43_Cam2_*.mp4

--output-dir <path>

Directory to write extracted frames.

Default: ./sampled_frames

Created automatically if it doesn't exist.

--max-frames <int>

Target number of output frames. Actual count may be lower if insufficient candidates.

Default: 5000

Example:

--max-frames 10000  # Extract up to 10,000 frames

--format <ext>

Output image format: .png, .jpg, or .jpeg.

Default: .png (lossless)

Example:

--format .jpg  # Use JPEG (smaller files, lossy compression)

Quality Gates

--min-brightness <int>

Minimum mean pixel value (0–255). Rejects dark frames.

Default: 12

Range: 0–255

Example:

--min-brightness 20  # Reject frames darker than 20/255

--max-brightness <int>

Maximum mean pixel value (0–255). Rejects overexposed frames.

Default: 243

Range: 0–255

Example:

--max-brightness 220  # Reject frames brighter than 220/255

--min-sharpness <float>

Minimum Laplacian variance. Rejects blurry frames.

Default: 15.0

Range: 0+

Example:

--min-sharpness 25.0  # Reject blurry frames (variance < 25)

--min-entropy <float>

Minimum Shannon entropy in bits. Rejects featureless frames.

Default: 2.5

Range: 0–8 (theoretical max is 8 bits for 256 gray levels)

Example:

--min-entropy 3.0  # Reject low-texture frames (entropy < 3 bits)

Diversity Parameters

--sample-fps <float>

Frames per second to examine in Pass 1.

Default: 1.0 (one frame per second)

Example:

--sample-fps 2.0  # Examine 2 frames per second (every 0.5s at 30fps)

Rule of thumb: Set to ~1–2× regardless of video frame rate.

--min-gap <float>

Minimum seconds between selected frames from the same video.

Default: 1.0

Example:

--min-gap 3.0  # Enforce 3-second gaps (avoid near-duplicates)

--n-bins <int>

Number of bins per feature axis. Total grid cells = n_bins³.

Default: 8 (512 cells)

Example:

--n-bins 10  # Use 10³ = 1000 cells (finer diversity resolution)

Recommendations: 5–7 for small datasets, 8–10 for medium, 10–12 for large.

--max-per-cell <int>

Maximum frames selected from each grid cell.

Default: ceil(max_frames / n_bins³)

Example:

--max-per-cell 5  # Each cell contributes ≤5 frames (strong diversity)

Performance Parameters

--jobs <int>

Number of parallel threads for Pass 1 (metric extraction). Requires OpenMP.

Default: 1 (single-threaded)

Example:

--jobs 8  # Use 8 threads (4–8× speedup on multi-core CPUs)

Note: Set to nproc or slightly lower for best performance.

--cache-dir <path>

Directory for metric cache files.

Default: ./.metric_cache

Example:

--cache-dir /tmp/metric_cache  # Use temporary directory

--no-cache

Ignore existing cache, force full re-scan.

Example:

--no-cache  # Recompute all metrics (e.g., after algorithm change)

Testing Parameters

--max-videos <int>

Maximum number of videos to process (for testing).

Default: -1 (unlimited)

Example:

--max-videos 5  # Process only first 5 videos


calibrate — Threshold Calibration

Analyze metric distributions and tune quality thresholds.

Basic Usage

./calibrate /path/to/video.mp4

Required Parameters

<video_path>

Path to video file (positional argument).

Example:

./calibrate /data/Triton43_Cam1_sample.mp4

Supports multiple videos:

./calibrate video1.mp4 video2.mp4 video3.mp4

Metrics are pooled across all provided videos.

Optional Parameters

All quality gate parameters (--min-brightness, --min-sharpness, etc.) are supported to test different thresholds.

Example:

./calibrate sample.mp4 \
  --sample-fps 2.0 \
  --min-brightness 15 \
  --min-sharpness 20 \
  --min-entropy 2.8

Output

Metric Distributions

Metric distributions (all examined frames):
  brightness    min=8.2   p5=18.3   median=87.2   p95=201.4  max=243.1
  sharpness     min=3.1   p5=12.7   median=45.3   p95=187.9  max=321.5
  entropy       min=1.3   p5=2.2    median=3.9    p95=5.3    max=6.2
  motion        min=0.5   p5=1.8    median=8.4    p95=28.7   max=89.3

Interpretation: See Tuning Guide.

Per-Gate Rejection

Per-gate rejection counts:
  min-brightness (≥15):    125 / 1200 rejected  (10.4%)
  max-brightness (≤243):   43 / 1200 rejected   (3.6%)
  min-sharpness (≥20):     187 / 1200 rejected  (15.6%)
  min-entropy (≥2.8):      223 / 1200 rejected  (18.6%)

Combined quality filter:   412 / 1200 rejected  (34.3%)
                          788 / 1200 passed     (65.7%)

Interpretation: Shows which gates are rejecting the most frames.

Threshold Recommendations

Threshold recommendations (for target pass rates):

  80% pass:  --min-brightness 18  --max-brightness 220  --min-sharpness 12  --min-entropy 2.2
  60% pass:  --min-brightness 28  --max-brightness 205  --min-sharpness 25  --min-entropy 2.8
  40% pass:  --min-brightness 42  --max-brightness 185  --min-sharpness 48  --min-entropy 3.5
  20% pass:  --min-brightness 68  --max-brightness 160  --min-sharpness 92  --min-entropy 4.3

Usage: Copy the row matching your desired selectivity (e.g., 60%) into sample command.


Common Workflows

Workflow 1: First-Time Setup

# Step 1: Calibrate on sample video
./calibrate /data/sample_video.mp4 --sample-fps 2.0

# Step 2: Choose thresholds (e.g., 60% pass rate)
# (from calibrate output)

# Step 3: Run sampler
./sample \
  --root-dir /data/videos \
  --camera 1 \
  --max-frames 5000 \
  --min-brightness 28 \
  --min-sharpness 25 \
  --min-entropy 2.8 \
  --output-dir ./frames \
  --jobs 8

Workflow 2: Iterate on Diversity

# Run with default diversity settings
./sample --root-dir /data --output-dir ./frames_v1

# Inspect output, decide to increase diversity
./sample \
  --root-dir /data \
  --output-dir ./frames_v2 \
  --n-bins 10 \
  --max-per-cell 5 \
  --min-gap 3.0

Note: Pass 1 uses cache, so iteration is fast (only Pass 2 re-runs).

Workflow 3: Multi-Camera Dataset

# Process each camera separately
for cam in 1 2 3 4; do
  ./sample \
    --root-dir /data/videos \
    --camera $cam \
    --max-frames 5000 \
    --output-dir ./frames_cam${cam} \
    --jobs 8
done

# Combine outputs
mkdir ./frames_all
cp ./frames_cam*/*.png ./frames_all/

Workflow 4: Large-Scale Processing

# Process in parallel across camera/date combinations
parallel -j 4 ./sample \
  --root-dir /data/{1}/{2} \
  --camera {3} \
  --output-dir ./frames_{1}_{2}_cam{3} \
  --jobs 2 \
  ::: $(seq 2025 2026) \
  ::: $(seq -w 1 12) \
  ::: $(seq 1 4)

Note: Reduce --jobs per instance when running multiple instances in parallel.


Tips and Tricks

Fast Iteration with Caching

Metric caching enables fast parameter tuning:

  1. Run once with broad thresholds (everything passes):

    ./sample --min-brightness 0 --min-sharpness 0 --min-entropy 0 ...
    

  2. Inspect distributions, adjust thresholds

  3. Re-run with tighter thresholds:

    ./sample --min-brightness 30 --min-sharpness 25 --min-entropy 3.0 ...
    

Pass 1 uses cache (instant), only Pass 2 re-runs (~seconds).

Combining Multiple Runs

To create a dataset from multiple sampling runs:

# Run 1: General diversity
./sample --root-dir /data --output-dir ./frames_general

# Run 2: Target rare conditions (high entropy)
./sample --root-dir /data --output-dir ./frames_rare --min-entropy 4.0

# Combine (remove duplicates by filename)
mkdir ./frames_combined
rsync -av --ignore-existing ./frames_general/ ./frames_combined/
rsync -av --ignore-existing ./frames_rare/ ./frames_combined/

Checking What Would Be Selected

To see candidate counts without extracting frames (fast dry-run):

Modify sample.cpp: - Comment out save_frames() call - Rebuild: make - Run as normal

Or use calibrate with tight thresholds to estimate pass rate.


Environment Variables

OpenCV Video Backend

Force specific backend (if auto-detection fails):

# Use FFMPEG
export OPENCV_VIDEOIO_BACKEND=ffmpeg
./sample ...

# Use GStreamer
export OPENCV_VIDEOIO_BACKEND=gstreamer
./sample ...

OpenMP Thread Count

Override --jobs dynamically:

export OMP_NUM_THREADS=4
./sample --jobs 8  # Uses 4 threads (env var takes precedence)

Exit Codes

  • 0: Success
  • 1: Error (invalid arguments, missing files, etc.)
  • 2: No frames selected (quality gates too strict or insufficient data)

Next Steps