-
-
Save polyfjord/fc22f22770cd4dd365bb90db67a4f2dc to your computer and use it in GitHub Desktop.
| :: ================================================================ | |
| :: 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 |
I forked and updated the script a bit: https://gist.github.com/aidv/05779c76401ae55ee6b227ee0c1e47f9
Apparently AMD GPU's are very wonky with COLMAP/GLOMAP, so forcing CPU usage is better.
This is so good!! Thank you
I ported to PowerShell because I having problem running with cmd on my PC
https://gist.github.com/rinme/db6001673e32fbf70338803bd711e39c
I had to add a few lines to make the bat work for me... Hoping to save someone some time:
I had to add COLMAPS dll folder to PATH (Add after set "SCENES_DIR=%TOP%\04 SCENES")
:: ---------- Put COLMAP’s dll folder(s) on PATH -------------------
set "PATH=%SFM_DIR%;%SFM_DIR%\bin;%PATH%"
And QT would return errors if I did not define the plugin folder...
:: ---------- Tell Qt where its plugins live -----------------------
set "QT_QPA_PLATFORM_PLUGIN_PATH=%SFM_DIR%\plugins\platforms"
set "QT_PLUGIN_PATH=%SFM_DIR%\plugins"
Lastly, the UTF-8 symbols wouldn't display correctly. (Add after @echo off)
rem Force UTF-8 so Unicode symbols display correctly
chcp 65001 >nul
can you make a new version so its works with new colmap and glomap and new blender version.please
I have lightly adapted @celestial-33 's wonderful Mac version to work in Linux. I haven't provided advice for installing the requirements, however (not convinced I'd do a good, broadly applicable job).
https://gist.github.com/Norgus/9e877924949d778db12c534ff1bafe36