-
-
Save Norgus/9e877924949d778db12c534ff1bafe36 to your computer and use it in GitHub Desktop.
Revisions
-
Norgus renamed this gist
Sep 3, 2025 . 1 changed file with 0 additions and 0 deletions.There are no files selected for viewing
File renamed without changes. -
Norgus revised this gist
Sep 3, 2025 . 2 changed files with 18 additions and 37 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,15 +1,14 @@ # 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](https://gist.github.com/celestial-33/07438792a11964ee5f6f02847b6dbb03) of [Polyfjord](https://www.youtube.com/@Polyfjord)’s workflow [here](https://gist.github.com/AeroGenesiX/009654b40d8911ccebb347537d5782b6), 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. @@ -25,18 +24,7 @@ This script is a macOS/Apple Silicon adaptation of [Polyfjord](https://www.youtu * **GLOMAP** – COLMAP extension for automated mapping. * **FFmpeg** – For frame extraction. ### Folder Structure @@ -57,15 +45,11 @@ brew install ffmpeg 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): ```bash FFMPEG="$(which ffmpeg)" COLMAP="$(which colmap)" GLOMAP="$(which glomap)" ``` 5. **Make it Executable:** @@ -88,10 +72,8 @@ brew install ffmpeg * **Slow processing:** Reduce `--SiftExtraction.max_image_size` (e.g., from 4096 → 2048) or process shorter clips. ----- ## Conclusion This script fully automates [Polyfjord](https://www.youtube.com/@Polyfjord)’s photogrammetry workflow on macOS using GLOMAP and COLMAP, making it easy to generate 3D sparse point clouds from videos. This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,7 +1,7 @@ #!/usr/bin/env bash # ================================================================ # BASH SCRIPT FOR AUTOMATED PHOTOGRAMMETRY TRACKING WORKFLOW (GLOMAP + COLMAP) # for Linux! # ================================================================ set -e # Stop on error @@ -15,12 +15,14 @@ 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 @@ -73,12 +75,9 @@ for VIDEO_FILE in "$VIDEOS_DIR"/*; do # --- 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 -
celestial-33 revised this gist
Sep 2, 2025 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -29,7 +29,7 @@ This script is a macOS/Apple Silicon adaptation of [Polyfjord](https://www.youtu * **Colmap and Glomap:** [Install by following this guide](https://youtu.be/tr5LrANp470) * **FFmpeg:** -
celestial-33 revised this gist
Sep 2, 2025 . 3 changed files with 222 additions and 186 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,186 +0,0 @@ This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,97 @@ # 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](https://www.youtube.com/@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](https://gist.github.com/celestial-33/a016465fd854d79a1b93458f167baa6a) * **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: ```bash FFMPEG="/opt/homebrew/bin/ffmpeg" COLMAP="/usr/local/bin/colmap" GLOMAP="/usr/local/bin/glomap" ``` **If you are unsure of the paths, run:** ```bash which colmap ffmpeg glomap ``` 5. **Make it Executable:** ```bash chmod +x run_glomap.sh ``` 6. **Run the Script:** From inside the `SCRIPTS/` folder: ```bash ./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](https://www.youtube.com/@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. This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,125 @@ #!/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 "--------------------------------------------------------------" -
polyfjord created this gist
Aug 20, 2025 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,186 @@ :: ================================================================ :: BATCH SCRIPT FOR AUTOMATED PHOTOGRAMMETRY TRACKING WORKFLOW :: By polyfjord - https://youtube.com/polyfjord :: GLOMAP mapping (faster), COLMAP for features/matching + TXT export :: ================================================================ @echo off setlocal EnableExtensions EnableDelayedExpansion :: ---------- Resolve top-level folder (one up from this .bat) ----- pushd "%~dp0\.." >nul set "TOP=%cd%" :: ---------- Key paths ------------------------------------------- set "SFM_DIR=%TOP%\01 GLOMAP" set "VIDEOS_DIR=%TOP%\02 VIDEOS" set "FFMPEG_DIR=%TOP%\03 FFMPEG" set "SCENES_DIR=%TOP%\04 SCENES" :: ---------- Locate ffmpeg.exe ----------------------------------- if exist "%FFMPEG_DIR%\ffmpeg.exe" ( set "FFMPEG=%FFMPEG_DIR%\ffmpeg.exe" ) else if exist "%FFMPEG_DIR%\bin\ffmpeg.exe" ( set "FFMPEG=%FFMPEG_DIR%\bin\ffmpeg.exe" ) else ( echo [ERROR] ffmpeg.exe not found inside "%FFMPEG_DIR%". popd & pause & goto :eof ) :: ---------- Locate glomap.exe ----------------------------------- if exist "%SFM_DIR%\glomap.exe" ( set "GLOMAP=%SFM_DIR%\glomap.exe" ) else if exist "%SFM_DIR%\bin\glomap.exe" ( set "GLOMAP=%SFM_DIR%\bin\glomap.exe" ) else ( echo [ERROR] glomap.exe not found inside "%SFM_DIR%". popd & pause & goto :eof ) :: ---------- Locate colmap.exe (DB + TXT export) ------------------ if exist "%SFM_DIR%\colmap.exe" ( set "COLMAP=%SFM_DIR%\colmap.exe" ) else if exist "%SFM_DIR%\bin\colmap.exe" ( set "COLMAP=%SFM_DIR%\bin\colmap.exe" ) else ( echo [ERROR] colmap.exe not found inside "%SFM_DIR%". popd & pause & goto :eof ) :: ---------- Put binaries on PATH -------------------------------- set "PATH=%SFM_DIR%;%SFM_DIR%\bin;%PATH%" :: ---------- Ensure required folders exist ------------------------ if not exist "%VIDEOS_DIR%" ( echo [ERROR] Input folder "%VIDEOS_DIR%" missing. popd & pause & goto :eof ) if not exist "%SCENES_DIR%" mkdir "%SCENES_DIR%" :: ---------- Count videos for progress bar ------------------------ for /f %%C in ('dir /b /a-d "%VIDEOS_DIR%\*" ^| find /c /v ""') do set "TOTAL=%%C" if "%TOTAL%"=="0" ( echo [INFO] No video files found in "%VIDEOS_DIR%". popd & pause & goto :eof ) echo ============================================================== echo Starting GLOMAP pipeline on %TOTAL% video(s) … echo ============================================================== set /a IDX=0 for %%V in ("%VIDEOS_DIR%\*.*") do ( set /a IDX+=1 call :PROCESS_VIDEO "%%~fV" "%%IDX%%" "%TOTAL%" ) echo -------------------------------------------------------------- echo All jobs finished – results are in "%SCENES_DIR%". echo -------------------------------------------------------------- popd pause goto :eof :PROCESS_VIDEO :: ---------------------------------------------------------------- :: %1 = full path to video %2 = current index %3 = total :: ---------------------------------------------------------------- setlocal EnableDelayedExpansion set "VIDEO=%~1" set "NUM=%~2" set "TOT=%~3" for %%I in ("%VIDEO%") do ( set "BASE=%%~nI" set "EXT=%%~xI" ) echo. echo [!NUM!/!TOT!] === Processing "!BASE!!EXT!" === :: -------- Directory layout for this scene ----------------------- set "SCENE=%SCENES_DIR%\!BASE!" set "IMG_DIR=!SCENE!\images" set "SPARSE_DIR=!SCENE!\sparse" :: -------- Skip if already reconstructed ------------------------- if exist "!SCENE!" ( echo • Skipping "!BASE!" – already reconstructed. goto :END ) :: Clean slate ---------------------------------------------------- mkdir "!IMG_DIR!" >nul mkdir "!SPARSE_DIR!" >nul :: -------- 1) Extract every frame -------------------------------- echo [1/4] Extracting frames … "%FFMPEG%" -loglevel error -stats -i "!VIDEO!" -qscale:v 2 ^ "!IMG_DIR!\frame_%%06d.jpg" if errorlevel 1 ( echo × FFmpeg failed – skipping "!BASE!". goto :END ) dir /b "!IMG_DIR!\*.jpg" >nul 2>&1 || ( echo × No frames extracted – skipping "!BASE!". goto :END ) :: -------- 2) Feature extraction (COLMAP) ------------------------- echo [2/4] COLMAP feature_extractor … "%COLMAP%" feature_extractor ^ --database_path "!SCENE!\database.db" ^ --image_path "!IMG_DIR!" ^ --ImageReader.single_camera 1 ^ --SiftExtraction.use_gpu 1 ^ --SiftExtraction.max_image_size 4096 if errorlevel 1 ( echo × feature_extractor failed – skipping "!BASE!". goto :END ) :: -------- 3) Sequential matching (COLMAP) ------------------------ echo [3/4] COLMAP sequential_matcher … "%COLMAP%" sequential_matcher ^ --database_path "!SCENE!\database.db" ^ --SequentialMatching.overlap 15 if errorlevel 1 ( echo × sequential_matcher failed – skipping "!BASE!". goto :END ) :: -------- 4) Sparse reconstruction (GLOMAP) ---------------------- echo [4/4] GLOMAP mapper … "%GLOMAP%" mapper ^ --database_path "!SCENE!\database.db" ^ --image_path "!IMG_DIR!" ^ --output_path "!SPARSE_DIR!" if errorlevel 1 ( echo × glomap mapper failed – skipping "!BASE!". goto :END ) :: -------- Export TXT **inside the model folder** ----------------- :: Keep TXT next to BIN so Blender can import from sparse\0 directly. if exist "!SPARSE_DIR!\0" ( "%COLMAP%" model_converter ^ --input_path "!SPARSE_DIR!\0" ^ --output_path "!SPARSE_DIR!\0" ^ --output_type TXT >nul ) :: -------- Export TXT to parent sparse\ (for Blender auto-detect) -- if exist "!SPARSE_DIR!\0" ( "%COLMAP%" model_converter ^ --input_path "!SPARSE_DIR!\0" ^ --output_path "!SPARSE_DIR!" ^ --output_type TXT >nul ) echo ✓ Finished "!BASE!" (!NUM!/!TOT!) :END endlocal & goto :eof