Skip to content

Instantly share code, notes, and snippets.

@celestial-33
Forked from polyfjord/AutoTracker_v1.4.bat
Last active September 5, 2025 23:36
Show Gist options
  • Save celestial-33/07438792a11964ee5f6f02847b6dbb03 to your computer and use it in GitHub Desktop.
Save celestial-33/07438792a11964ee5f6f02847b6dbb03 to your computer and use it in GitHub Desktop.
AutoTracker workflow using GLOMAP

Automated Video to 3D Scan Workflow (GLOMAP + COLMAP) for macOS

This repository contains a Bash script for automating a photogrammetry workflow on macOS using GLOMAP and COLMAP. It takes video files as input, extracts frames via FFmpeg, and generates a 3D sparse point cloud for each video.

This script is a macOS/Apple Silicon adaptation of Polyfjord’s workflow, rewritten to run smoothly on Mac systems.


Features

  • One-Command Automation: Processes all videos in the input folder in a single run.
  • CPU & Apple Silicon Ready: Automatically detects CPU threads and works on M-series Macs.
  • Error Handling: Skips already processed videos and ensures the workflow executes step by step without breaking.
  • Organized Output: Keeps results clean with a structured project folder.
  • COLMAP + GLOMAP Integration: Extracts features, performs sequential matching, and runs sparse reconstruction automatically.
  • TXT Export: Converts COLMAP models to TXT format for easier inspection or import.

Requirements

Software

  • COLMAP – Structure-from-motion and multi-view stereo pipeline.
  • GLOMAP – COLMAP extension for automated mapping.
  • FFmpeg – For frame extraction.

Recommended Installation Method:

  • Colmap and Glomap:

Install by following this guide

  • FFmpeg:
brew install ffmpeg

Folder Structure

    Project_Folder/
    ├── VIDEOS/      # Place input video files (.mp4, .mov) here.
    ├── SCENES/      # The script saves all outputs here.
    └── SCRIPTS/     # The run_glomap.sh script lives here.

How to Use

  1. Set Up Folders: Create the structure shown above.

  2. Add Videos: Copy your .mp4 or .mov files into the VIDEOS/ folder.

  3. Save the Script: Place the script (run_glomap.sh) in the SCRIPTS/ folder.

  4. Update Paths: Edit the script and update these variables to match your system installation:

    FFMPEG="/opt/homebrew/bin/ffmpeg"
    COLMAP="/usr/local/bin/colmap"
    GLOMAP="/usr/local/bin/glomap"

    If you are unsure of the paths, run:

    which colmap ffmpeg glomap
  5. Make it Executable:

    chmod +x run_glomap.sh
  6. Run the Script: From inside the SCRIPTS/ folder:

    ./run_glomap.sh

Troubleshooting

  • COLMAP/GLOMAP/FFmpeg not found: Ensure the paths in the script match your system installation.

  • No frames extracted: Check that your video files are valid and playable by FFmpeg.

  • Slow processing: Reduce --SiftExtraction.max_image_size (e.g., from 4096 → 2048) or process shorter clips.

  • GPU/CPU issues: This script primarily uses CPU. M-series Macs may benefit from COLMAP GPU support if configured.


Conclusion

This script fully automates Polyfjord’s photogrammetry workflow on macOS using GLOMAP and COLMAP, making it easy to generate 3D sparse point clouds from videos. Future updates may include optimizations and support for additional Mac hardware.

#!/bin/bash
# ================================================================
# BASH SCRIPT FOR AUTOMATED PHOTOGRAMMETRY TRACKING WORKFLOW (GLOMAP + COLMAP)
# macOS / Apple Silicon version (Could work in Intel Mac - Not tested yet)
# ================================================================
set -e # Stop on error
# --- Resolve top-level folder (one up from this script) ---
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
TOP="$(dirname "$SCRIPT_DIR")"
# --- Key paths ---
VIDEOS_DIR="$TOP/VIDEOS"
SCENES_DIR="$TOP/SCENES"
# --- System-wide executables ---
FFMPEG="/opt/homebrew/bin/ffmpeg"
COLMAP="/usr/local/bin/colmap"
GLOMAP="/usr/local/bin/glomap"
# --- CPU thread count ---
NUM_THREADS=$(sysctl -n hw.ncpu)
# --- Ensure executables exist ---
for cmd in "$FFMPEG" "$COLMAP" "$GLOMAP"; do
if [ ! -x "$cmd" ]; then
echo "[ERROR] Executable not found: $cmd" >&2
exit 1
fi
done
# --- Ensure required folders exist ---
if [ ! -d "$VIDEOS_DIR" ]; then
echo "[ERROR] Input folder '$VIDEOS_DIR' missing." >&2
exit 1
fi
mkdir -p "$SCENES_DIR"
# --- Count videos ---
TOTAL=$(find "$VIDEOS_DIR" -maxdepth 1 -type f | wc -l | tr -d ' ')
if [ "$TOTAL" -eq 0 ]; then
echo "[INFO] No video files found in '$VIDEOS_DIR'."
exit 0
fi
echo "=============================================================="
echo " Starting GLOMAP pipeline on $TOTAL video(s) …"
echo "=============================================================="
IDX=0
for VIDEO_FILE in "$VIDEOS_DIR"/*; do
[ -f "$VIDEO_FILE" ] || continue
IDX=$((IDX + 1))
BASENAME=$(basename "$VIDEO_FILE")
BASE="${BASENAME%.*}"
echo
echo "[$IDX/$TOTAL] === Processing \"$BASENAME\" ==="
SCENE_DIR="$SCENES_DIR/$BASE"
IMG_DIR="$SCENE_DIR/images"
SPARSE_DIR="$SCENE_DIR/sparse"
# Skip if already reconstructed
if [ -d "$SCENE_DIR" ]; then
echo " • Skipping \"$BASE\" – already reconstructed."
continue
fi
# Create directories
mkdir -p "$IMG_DIR" "$SPARSE_DIR"
# --- 1) Extract frames ---
echo " [1/4] Extracting frames …"
"$FFMPEG" -loglevel error -stats -i "$VIDEO_FILE" -qscale:v 2 "$IMG_DIR/frame_%06d.jpg"
# Remove dot-underscore macOS files
find "$IMG_DIR" -name '._*' -delete
if ! ls "$IMG_DIR"/*.jpg &> /dev/null; then
echo " × No frames extracted – skipping \"$BASE\"."
rm -rf "$SCENE_DIR"
continue
fi
# --- 2) Feature extraction (COLMAP) ---
echo " [2/4] COLMAP feature_extractor …"
"$COLMAP" feature_extractor \
--database_path "$SCENE_DIR/database.db" \
--image_path "$IMG_DIR" \
--ImageReader.single_camera 1 \
--SiftExtraction.max_image_size 4096
# --- 3) Sequential matching (COLMAP) ---
echo " [3/4] COLMAP sequential_matcher …"
"$COLMAP" sequential_matcher \
--database_path "$SCENE_DIR/database.db" \
--SequentialMatching.overlap 15
# --- 4) Sparse reconstruction (GLOMAP) ---
echo " [4/4] GLOMAP mapper …"
"$GLOMAP" mapper \
--database_path "$SCENE_DIR/database.db" \
--image_path "$IMG_DIR" \
--output_path "$SPARSE_DIR"
# --- Export TXT inside model folder ---
if [ -d "$SPARSE_DIR/0" ]; then
"$COLMAP" model_converter \
--input_path "$SPARSE_DIR/0" \
--output_path "$SPARSE_DIR/0" \
--output_type TXT > /dev/null
"$COLMAP" model_converter \
--input_path "$SPARSE_DIR/0" \
--output_path "$SPARSE_DIR" \
--output_type TXT > /dev/null
fi
echo " ✓ Finished \"$BASE\" ($IDX/$TOTAL)"
done
echo "--------------------------------------------------------------"
echo " All jobs finished – results are in \"$SCENES_DIR\"."
echo "--------------------------------------------------------------"
@Norgus
Copy link

Norgus commented Sep 3, 2025

Amazing work, it took very little adaptation to work for Linux and I have credited you in my fork https://gist.github.com/Norgus/9e877924949d778db12c534ff1bafe36

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment