Skip to content

Instantly share code, notes, and snippets.

@Norgus
Forked from celestial-33/readme-mac.md
Last active September 14, 2025 21:49
Show Gist options
  • Select an option

  • Save Norgus/9e877924949d778db12c534ff1bafe36 to your computer and use it in GitHub Desktop.

Select an option

Save Norgus/9e877924949d778db12c534ff1bafe36 to your computer and use it in GitHub Desktop.
AutoTracker workflow using GLOMAP

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

This repository contains a Bash script for automating a photogrammetry workflow on Linux 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 Linux adaptation of celestial's Mac adaptation of Polyfjord’s workflow here, with minimul adaptations to run smoothly on Linux systems.


Features

  • One-Command Automation: Processes all videos in the input folder in a single run.
  • 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.

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 (only necessary if they aren't already on $PATH):

    FFMPEG="$(which ffmpeg)"
    COLMAP="$(which colmap)"
    GLOMAP="$(which 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.


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.

#!/usr/bin/env bash
# ================================================================
# BASH SCRIPT FOR AUTOMATED PHOTOGRAMMETRY TRACKING WORKFLOW (GLOMAP + COLMAP)
# for Linux!
# ================================================================
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 ---
# replace with full paths to binaries if using one
# not on $PATH
FFMPEG="$(which ffmpeg)"
COLMAP="$(which colmap)"
GLOMAP="$(which glomap)"
# --- CPU thread count ---
NUM_THREADS=$(nproc)
# --- 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.png"
if ! ls "$IMG_DIR"/*.png &> /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 "--------------------------------------------------------------"
@PaulPink
Copy link

Hi, could you perhaps give me a tip or a link on how to properly install Colmap + Glomap?
I use CachyOS (Arch) and haven't managed to build both together yet.
It keeps failing due to version conflicts and similar issues. Polyfiord's Windows method isn't possible, is it?

@Norgus
Copy link
Author

Norgus commented Sep 13, 2025

Hi @PaulPink - I'm not confident I can help, but I am using a flavour of Arch (Garuda).
What worked for me is the AUR package fails to build for a stupid reason, so I modified the PKGBUILD and got it installed that way.
See: bartoszek/AUR-colmap#9 (comment)
(where I set the number manually to 32, make sure to use a number that's no larger than the number of threads your CPU has)

I think once I had colmap working, the build instructions on the glomap github page worked for me
https://github.com/colmap/glomap?tab=readme-ov-file

@PaulPink
Copy link

Hi @Norgus, first of all, thank you very much for your reply.
Unfortunately, it didn't get me directly to my goal, but by analyzing the error with the help of our beloved AI, I was able to achieve my goal. I'll try to summarize it here.
The installation of Colmap, as described by you, worked perfectly. I only had to change the line
ninja -C “$srcdir/build” $(grep -oP -- ‘-+[A-z]+ ?[0-9]*’<<<“${MAKEFLAGS:--j1}”)
in PKBUILD with
ninja -C “$srcdir/build” -j$(nproc)

Then it got trickier. But that's where ChatGPT came in. The following answer made all the difference:

  1. Build with an older compiler
    Since CachyOS uses extremely up-to-date packages, you can try installing an older gcc, e.g.:
    sudo pacman -S gcc14
    and then build with:
    CC=gcc-14 CXX=g++-14 cmake .. -GNinja
    This prevents the brand new C++17 standard from GCC 15 from breaking the old COLMAP code.
    Now everything works.

I probably wouldn't have figured that out on my own.
So thank you again.

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