Created
December 18, 2016 21:13
-
-
Save oculushut/ef54e4eb4fb598b768e494dd3a2e98b6 to your computer and use it in GitHub Desktop.
MvgMvs_Pipeline.py with adjustments to stop it hanging - just specify start step, finish step, input and output folders
This file contains 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
#!/usr/bin/python | |
#! -*- encoding: utf-8 -*- | |
# | |
# Created by @FlachyJoe | |
# | |
# this script is for easy use of OpenMVG and OpenMVS | |
# | |
#usage: SfM_MyPipeline.py input_dir output_dir | |
# [-h] [-f FIRST_STEP] [-l LAST_STEP] [--0 0 [0 ...]] | |
# [--1 1 [1 ...]] [--2 2 [2 ...]] [--3 3 [3 ...]] | |
# [--4 4 [4 ...]] [--5 5 [5 ...]] [--6 6 [6 ...]] | |
# [--7 7 [7 ...]] [--8 8 [8 ...]] [--9 9 [9 ...]] | |
# [--10 10 [10 ...]] [--11 11 [11 ...]] | |
# | |
#Photogrammetry reconstruction with these steps : | |
# 0. Intrinsics analysis openMVG_main_SfMInit_ImageListing | |
# 1. Compute features openMVG_main_ComputeFeatures | |
# 2. Compute matches openMVG_main_ComputeMatches | |
#AW: Changed matches -g to have e instead of f... whatever that means! | |
# 3. Incremental reconstruction openMVG_main_IncrementalSfM | |
#AW: Changed to openMVG_main_GlobalSfM as Incremental keeps on hanging. | |
# 4. Colorize Structure openMVG_main_ComputeSfM_DataColor | |
# 5. Structure from Known Poses openMVG_main_ComputeStructureFromKnownPoses | |
# 6. Colorized robust triangulation openMVG_main_ComputeSfM_DataColor | |
# 7. Export to openMVS openMVG_main_openMVG2openMVS | |
# 8. Densify point cloud OpenMVS/DensifyPointCloud | |
# 9. Reconstruct the mesh OpenMVS/ReconstructMesh | |
# 10. Refine the mesh OpenMVS/RefineMesh | |
# 11. Texture the mesh OpenMVS/TextureMesh | |
# | |
#positional arguments: | |
# input_dir the directory which contains the pictures set. | |
# output_dir the directory which will contain the resulting files. | |
# | |
#optional arguments: | |
# -h, --help show this help message and exit | |
# -f FIRST_STEP, --first_step FIRST_STEP | |
# the first step to process | |
# -l LAST_STEP, --last_step LAST_STEP | |
# the last step to process | |
# | |
#Passthrough: | |
# Option to be pass to command lines (remove - in front of option names) | |
# e.g. --1 p ULTRA to use the ULTRA preset in openMVG_main_ComputeFeatures | |
import commands | |
import os | |
import subprocess | |
import sys | |
# Indicate the openMVG and openMVS binary directories | |
# OPENMVG_BIN = "D:/Pro/OpenMVG/install/bin/" | |
# OPENMVS_BIN = "D:/Pro/OpenMVS/install/bin/" | |
OPENMVG_BIN = "F:\#Downloads RAW\ReleaseV1.0 Pangio kuhlii WindowsBinaries_VS2015/" | |
OPENMVS_BIN = "F:\#Downloads RAW\openMVS_sample-0.7/" | |
# Indicate the openMVG camera sensor width directory | |
CAMERA_SENSOR_WIDTH_DIRECTORY = OPENMVG_BIN | |
DEBUG=False | |
## HELPERS for terminal colors | |
BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = range(8) | |
NO_EFFECT, BOLD, UNDERLINE, BLINK, INVERSE, HIDDEN = (0,1,4,5,7,8) | |
#from Python cookbook, #475186 | |
def has_colours(stream): | |
if not hasattr(stream, "isatty"): | |
return False | |
if not stream.isatty(): | |
return False # auto color only on TTYs | |
try: | |
import curses | |
curses.setupterm() | |
return curses.tigetnum("colors") > 2 | |
except: | |
# guess false in case of error | |
return False | |
has_colours = has_colours(sys.stdout) | |
def printout(text, colour=WHITE, background=BLACK, effect=NO_EFFECT): | |
if has_colours: | |
seq = "\x1b[%d;%d;%dm" % (effect, 30+colour, 40+background) + text + "\x1b[0m" | |
sys.stdout.write(seq+'\r\n') | |
else: | |
sys.stdout.write(text+'\r\n') | |
## OBJECTS to store config and data in | |
class ConfContainer(object): | |
"""Container for all the config variables""" | |
pass | |
conf=ConfContainer() | |
class aStep: | |
def __init__(self, info, cmd, opt): | |
self.info = info | |
self.cmd = cmd | |
self.opt = opt | |
class stepsStore : | |
def __init__(self): | |
self.steps_data=[ | |
[ "Intrinsics analysis", | |
os.path.join(OPENMVG_BIN,"openMVG_main_SfMInit_ImageListing"), | |
["-i", "%input_dir%", "-o", "%matches_dir%", "-d", "%camera_file_params%"] ], | |
[ "Compute features", | |
os.path.join(OPENMVG_BIN,"openMVG_main_ComputeFeatures"), | |
["-i", "%matches_dir%/sfm_data.json", "-o", "%matches_dir%", "-m", "SIFT", "-n", "4"] ], | |
#[ "Compute matches", | |
# os.path.join(OPENMVG_BIN, "openMVG_main_ComputeMatches"), | |
# ["-i", "%matches_dir%/sfm_data.json", "-o", "%matches_dir%"] ], | |
#[ "Incremental reconstruction", | |
# os.path.join(OPENMVG_BIN, "openMVG_main_IncrementalSfM"), | |
# ["-i", "%matches_dir%/sfm_data.json", "-m", "%matches_dir%", "-o", "%reconstruction_dir%"] ], | |
#kept on crashing so changed ComputeMatches to use -g e and using GlobalSfM instead of incremental | |
[ "Compute matches", | |
os.path.join(OPENMVG_BIN, "openMVG_main_ComputeMatches"), | |
["-i", "%matches_dir%/sfm_data.json", "-o", "%matches_dir%", "-g", "e"] ], | |
[ "Global reconstruction", | |
os.path.join(OPENMVG_BIN, "openMVG_main_GlobalSfM"), | |
["-i", "%matches_dir%/sfm_data.json", "-m", "%matches_dir%", "-o", "%reconstruction_dir%"] ], | |
[ "Colorize Structure", | |
os.path.join(OPENMVG_BIN,"openMVG_main_ComputeSfM_DataColor"), | |
["-i", "%reconstruction_dir%/sfm_data.bin", "-o", "%reconstruction_dir%/colorized.ply"]], | |
[ "Structure from Known Poses", | |
os.path.join(OPENMVG_BIN,"openMVG_main_ComputeStructureFromKnownPoses"), | |
["-i", "%reconstruction_dir%/sfm_data.bin", "-m", "%matches_dir%", "-f", "%matches_dir%/matches.f.bin", "-o", "%reconstruction_dir%/robust.bin"]], | |
[ "Colorized robust triangulation", | |
os.path.join(OPENMVG_BIN,"openMVG_main_ComputeSfM_DataColor"), | |
["-i", "%reconstruction_dir%/robust.bin", "-o", "%reconstruction_dir%/robust_colorized.ply"]], | |
[ "Export to openMVS", | |
os.path.join(OPENMVG_BIN,"openMVG_main_openMVG2openMVS"), | |
["-i", "%reconstruction_dir%/sfm_data.bin", "-o", "%mvs_dir%/scene.mvs","-d","%mvs_dir%"]], | |
[ "Densify point cloud", | |
os.path.join(OPENMVS_BIN,"DensifyPointCloud"), | |
["scene.mvs", "-w","%mvs_dir%"]], | |
[ "Reconstruct the mesh", | |
os.path.join(OPENMVS_BIN,"ReconstructMesh"), | |
["scene_dense.mvs", "-w","%mvs_dir%"]], | |
[ "Refine the mesh", | |
os.path.join(OPENMVS_BIN,"RefineMesh"), | |
["scene_dense_mesh.mvs", "-w","%mvs_dir%"]], | |
[ "Texture the mesh", | |
os.path.join(OPENMVS_BIN,"TextureMesh"), | |
["scene_dense_mesh_refine.mvs", "-w","%mvs_dir%"]] | |
] | |
def __getitem__(self, indice): | |
return aStep(*self.steps_data[indice]) | |
def length(self): | |
return len(self.steps_data) | |
def apply_conf(self, conf): | |
""" replace each %var% per conf.var value in steps data """ | |
for s in self.steps_data : | |
o2=[] | |
for o in s[2]: | |
co=o.replace("%input_dir%",conf.input_dir) | |
co=co.replace("%output_dir%",conf.output_dir) | |
co=co.replace("%matches_dir%",conf.matches_dir) | |
co=co.replace("%reconstruction_dir%",conf.reconstruction_dir) | |
co=co.replace("%mvs_dir%",conf.mvs_dir) | |
co=co.replace("%camera_file_params%",conf.camera_file_params) | |
o2.append(co) | |
s[2]=o2 | |
steps=stepsStore() | |
## ARGS | |
import argparse | |
parser = argparse.ArgumentParser( | |
formatter_class=argparse.RawDescriptionHelpFormatter, | |
description="Photogrammetry reconstruction with these steps : \r\n"+ | |
"\r\n".join(("\t%i. %s\t %s" % (t, steps[t].info, steps[t].cmd) for t in range(steps.length()))) | |
) | |
parser.add_argument('input_dir', help="the directory wich contains the pictures set.") | |
parser.add_argument('output_dir', help="the directory wich will contain the resulting files.") | |
parser.add_argument('-f','--first_step', type=int, default=0, help="the first step to process") | |
parser.add_argument('-l','--last_step', type=int, default=11, help="the last step to process" ) | |
group = parser.add_argument_group('Passthrough',description="Option to be passed to command lines (remove - in front of option names)\r\ne.g. --1 p ULTRA to use the ULTRA preset in openMVG_main_ComputeFeatures") | |
for n in range(steps.length()) : | |
group.add_argument('--'+str(n), nargs='+') | |
parser.parse_args(namespace=conf) #store args in the ConfContainer | |
## FOLDERS | |
def mkdir_ine(dirname): | |
"""Create the folder if not presents""" | |
if not os.path.exists(dirname): | |
os.mkdir(dirname) | |
#Absolute path for input and ouput dirs | |
conf.input_dir=os.path.abspath(conf.input_dir) | |
conf.output_dir=os.path.abspath(conf.output_dir) | |
if not os.path.exists(conf.input_dir): | |
sys.exit("%s : path not found" % conf.input_dir) | |
conf.matches_dir = os.path.join(conf.output_dir, "matches") | |
conf.reconstruction_dir = os.path.join(conf.output_dir, "reconstruction_sequential") | |
conf.mvs_dir = os.path.join(conf.output_dir, "mvs") | |
conf.camera_file_params = os.path.join(CAMERA_SENSOR_WIDTH_DIRECTORY, "sensor_width_camera_database.txt") | |
mkdir_ine(conf.output_dir) | |
mkdir_ine(conf.matches_dir) | |
mkdir_ine(conf.reconstruction_dir) | |
mkdir_ine(conf.mvs_dir) | |
steps.apply_conf(conf) | |
## WALK | |
print "# Using input dir : %s" % conf.input_dir | |
print "# output_dir : %s" % conf.output_dir | |
print "# First step : %i" % conf.first_step | |
print "# Last step : %i" % conf.last_step | |
for cstep in range(conf.first_step, conf.last_step+1): | |
printout("#%i. %s" % (cstep, steps[cstep].info), effect=INVERSE) | |
opt=getattr(conf,str(cstep)) | |
if opt is not None : | |
#add - sign to short options and -- to long ones | |
for o in range(0,len(opt),2): | |
if len(opt[o])>1: | |
opt[o]='-'+opt[o] | |
opt[o]='-'+opt[o] | |
else: | |
opt=[] | |
#Remove steps[cstep].opt options now defined in opt | |
for anOpt in steps[cstep].opt : | |
if anOpt in opt : | |
idx=steps[cstep].opt.index(anOpt) | |
if DEBUG : | |
print '#\t'+'Remove '+ str(anOpt) + ' from defaults options at id ' + str(idx) | |
del steps[cstep].opt[idx:idx+2] | |
cmdline = [steps[cstep].cmd] + steps[cstep].opt + opt | |
if not DEBUG : | |
pStep = subprocess.Popen(cmdline) | |
pStep.wait() | |
else: | |
print '\t'+' '.join(cmdline) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment