-
-
Save aidv/05779c76401ae55ee6b227ee0c1e47f9 to your computer and use it in GitHub Desktop.
AutoTracker workflow using GLOMAP
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 characters
:: ================================================================ | |
:: 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 | |
set COLMAP_USE_GPU=1 | |
:: Detect AMD GPU | |
set "gpuInfo=" | |
for /f "tokens=*" %%i in ('wmic path win32_VideoController get name /value ^| find "="') do ( | |
set "gpuInfo=%%i" | |
) | |
echo Detected GPU: !gpuInfo! | |
echo !gpuInfo! | find /I "AMD" >nul | |
if %errorlevel%==0 ( | |
echo ============================================================ | |
echo WARNING: AMD GPU detected. | |
echo COLMAP and GLOMAP will probably fail or crash on AMD GPUs. | |
echo ============================================================ | |
set /p useCPU="Do you want to force CPU mode instead? [y/n]: " | |
if /I "!useCPU!"=="y" ( | |
echo Using CPU mode... | |
set COLMAP_USE_GPU=0 | |
) else ( | |
echo Exiting... | |
exit /b 1 | |
) | |
) | |
:: ---------- Resolve top-level folder (one up from this .bat) ----- | |
pushd "%~dp0\.." >nul | |
set "TOP=%cd%" | |
:: Point Qt to the correct plugin folder | |
set "QT_QPA_PLATFORM_PLUGIN_PATH=%TOP%\01 GLOMAP\plugins\platforms" | |
:: ---------- 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 %COLMAP_USE_GPU% ^ | |
--SiftExtraction.max_image_size 4096 ^ | |
--SiftExtraction.max_num_features 2000 ^ | |
1> "!SCENE!\feature_extractor.log" 2>&1 | |
:: Check for warnings | |
findstr /C:"WARNING" "!SCENE!\feature_extractor.log" >nul | |
if %errorlevel%==0 ( | |
echo. | |
echo -------------------------------------------------------- | |
echo ⚠ WARNINGS during feature extraction: | |
echo -------------------------------------------------------- | |
findstr /C:"WARNING" "!SCENE!\feature_extractor.log" | |
echo -------------------------------------------------------- | |
) | |
:: Check for errors based on log content | |
findstr /C:"ERROR" "!SCENE!\feature_extractor.log" >nul | |
if %errorlevel%==0 ( | |
echo. | |
echo × feature_extractor failed – skipping "!BASE!". | |
echo -------------------------------------------------------- | |
findstr /C:"ERROR" "!SCENE!\feature_extractor.log" | |
echo -------------------------------------------------------- | |
goto :END | |
) | |
:: Check if features were actually extracted | |
findstr /C:"Processed file" "!SCENE!\feature_extractor.log" >nul | |
if %errorlevel%==0 ( | |
echo √ feature_extractor completed successfully. | |
) else ( | |
echo × feature_extractor produced no features – skipping "!BASE!". | |
goto :END | |
) | |
:: -------- 3) Sequential matching (COLMAP) ------------------------ | |
echo [3/4] COLMAP sequential_matcher … | |
"%COLMAP%" sequential_matcher ^ | |
--database_path "!SCENE!\database.db" ^ | |
--SiftMatching.use_gpu %COLMAP_USE_GPU% ^ | |
--SequentialMatching.overlap 15 ^ | |
--SiftMatching.max_num_matches 1000 | |
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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Changelog;