2019-04-22 19:14:39 +00:00
|
|
|
import shutil, os, glob, math
|
2018-06-27 18:32:49 +00:00
|
|
|
|
|
|
|
from opendm import log
|
|
|
|
from opendm import io
|
|
|
|
from opendm import system
|
|
|
|
from opendm import context
|
2019-03-06 00:03:04 +00:00
|
|
|
from opendm import point_cloud
|
2019-04-22 19:14:39 +00:00
|
|
|
from opendm import types
|
2018-06-27 18:32:49 +00:00
|
|
|
|
2019-04-22 19:14:39 +00:00
|
|
|
class ODMMveStage(types.ODM_Stage):
|
|
|
|
def process(self, args, outputs):
|
2018-06-27 18:32:49 +00:00
|
|
|
# get inputs
|
2019-04-22 19:14:39 +00:00
|
|
|
tree = outputs['tree']
|
|
|
|
reconstruction = outputs['reconstruction']
|
2018-06-27 18:32:49 +00:00
|
|
|
photos = reconstruction.photos
|
|
|
|
|
|
|
|
if not photos:
|
2018-12-02 17:45:26 +00:00
|
|
|
log.ODM_ERROR('Not enough photos in photos array to start MVE')
|
2019-04-22 19:14:39 +00:00
|
|
|
exit(1)
|
2018-06-27 18:32:49 +00:00
|
|
|
|
|
|
|
# check if reconstruction was done before
|
2019-04-22 19:14:39 +00:00
|
|
|
if not io.file_exists(tree.mve_model) or self.rerun():
|
2018-10-29 15:39:37 +00:00
|
|
|
# cleanup if a rerun
|
2019-04-22 19:14:39 +00:00
|
|
|
if io.dir_exists(tree.mve_path) and self.rerun():
|
2018-10-29 15:39:37 +00:00
|
|
|
shutil.rmtree(tree.mve_path)
|
2018-06-30 23:36:53 +00:00
|
|
|
|
2018-06-27 18:32:49 +00:00
|
|
|
# make bundle directory
|
|
|
|
if not io.file_exists(tree.mve_bundle):
|
2018-10-29 15:39:37 +00:00
|
|
|
system.mkdir_p(tree.mve_path)
|
2018-06-27 18:32:49 +00:00
|
|
|
system.mkdir_p(io.join_paths(tree.mve_path, 'bundle'))
|
|
|
|
io.copy(tree.opensfm_image_list, tree.mve_image_list)
|
|
|
|
io.copy(tree.opensfm_bundle, tree.mve_bundle)
|
|
|
|
|
2018-07-02 19:21:30 +00:00
|
|
|
# mve makescene wants the output directory
|
|
|
|
# to not exists before executing it (otherwise it
|
|
|
|
# will prompt the user for confirmation)
|
2018-12-02 17:45:26 +00:00
|
|
|
if io.dir_exists(tree.mve):
|
|
|
|
shutil.rmtree(tree.mve)
|
2018-07-02 19:21:30 +00:00
|
|
|
|
2018-06-30 23:36:53 +00:00
|
|
|
# run mve makescene
|
2018-07-01 22:49:53 +00:00
|
|
|
if not io.dir_exists(tree.mve_views):
|
2019-04-12 17:58:25 +00:00
|
|
|
system.run('%s %s %s' % (context.makescene_path, tree.mve_path, tree.mve), env_vars={'OMP_NUM_THREADS': args.max_concurrency})
|
2018-06-30 23:36:53 +00:00
|
|
|
|
2019-04-03 20:23:21 +00:00
|
|
|
# Compute mve output scale based on depthmap_resolution
|
|
|
|
max_width = 0
|
|
|
|
max_height = 0
|
|
|
|
for photo in photos:
|
|
|
|
max_width = max(photo.width, max_width)
|
|
|
|
max_height = max(photo.height, max_height)
|
|
|
|
|
2019-04-10 14:41:35 +00:00
|
|
|
max_pixels = args.depthmap_resolution * args.depthmap_resolution
|
|
|
|
if max_width * max_height <= max_pixels:
|
|
|
|
mve_output_scale = 0
|
|
|
|
else:
|
|
|
|
ratio = float(max_width * max_height) / float(max_pixels)
|
|
|
|
mve_output_scale = int(math.ceil(math.log(ratio) / math.log(4.0)))
|
2019-04-03 20:23:21 +00:00
|
|
|
|
2019-04-03 18:47:06 +00:00
|
|
|
dmrecon_config = [
|
2019-04-03 20:23:21 +00:00
|
|
|
"-s%s" % mve_output_scale,
|
2019-04-03 18:59:10 +00:00
|
|
|
"--progress=silent",
|
2019-04-10 14:41:35 +00:00
|
|
|
"--local-neighbors=2",
|
2019-04-03 18:59:10 +00:00
|
|
|
"--force",
|
2018-06-27 18:32:49 +00:00
|
|
|
]
|
|
|
|
|
2019-04-03 18:47:06 +00:00
|
|
|
# Run MVE's dmrecon
|
2019-04-04 16:36:44 +00:00
|
|
|
log.ODM_INFO(' ')
|
|
|
|
log.ODM_INFO(' ,*/** ')
|
|
|
|
log.ODM_INFO(' ,*@%*/@%* ')
|
|
|
|
log.ODM_INFO(' ,/@%******@&*. ')
|
|
|
|
log.ODM_INFO(' ,*@&*********/@&* ')
|
|
|
|
log.ODM_INFO(' ,*@&**************@&* ')
|
|
|
|
log.ODM_INFO(' ,/@&******************@&*. ')
|
|
|
|
log.ODM_INFO(' ,*@&*********************/@&* ')
|
|
|
|
log.ODM_INFO(' ,*@&**************************@&*. ')
|
|
|
|
log.ODM_INFO(' ,/@&******************************&&*, ')
|
|
|
|
log.ODM_INFO(' ,*&&**********************************@&*. ')
|
|
|
|
log.ODM_INFO(' ,*@&**************************************@&*. ')
|
|
|
|
log.ODM_INFO(' ,*@&***************#@@@@@@@@@%****************&&*, ')
|
|
|
|
log.ODM_INFO(' .*&&***************&@@@@@@@@@@@@@@****************@@*. ')
|
|
|
|
log.ODM_INFO(' .*@&***************&@@@@@@@@@@@@@@@@@%****(@@%********@@*. ')
|
|
|
|
log.ODM_INFO(' .*@@***************%@@@@@@@@@@@@@@@@@@@@@#****&@@@@%******&@*, ')
|
|
|
|
log.ODM_INFO(' .*&@****************@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@/*****@@*. ')
|
|
|
|
log.ODM_INFO(' .*@@****************@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%*************@@*. ')
|
|
|
|
log.ODM_INFO(' .*@@****/***********@@@@@&**(@@@@@@@@@@@@@@@@@@@@@@@#*****************%@*, ')
|
|
|
|
log.ODM_INFO(' */@*******@*******#@@@@%*******/@@@@@@@@@@@@@@@@@@@@********************/@(, ')
|
|
|
|
log.ODM_INFO(' ,*@(********&@@@@@@#**************/@@@@@@@#**(@@&/**********************@&* ')
|
|
|
|
log.ODM_INFO(' *#@/*******************************@@@@@***&@&**********************&@*, ')
|
|
|
|
log.ODM_INFO(' *#@#******************************&@@@***@#*********************&@*, ')
|
|
|
|
log.ODM_INFO(' */@#*****************************@@@************************@@*. ')
|
|
|
|
log.ODM_INFO(' *#@/***************************/@@/*********************%@*, ')
|
|
|
|
log.ODM_INFO(' *#@#**************************#@@%******************%@*, ')
|
|
|
|
log.ODM_INFO(' */@#*************************(@@@@@@@&%/********&@*. ')
|
|
|
|
log.ODM_INFO(' *(@(*********************************/%@@%**%@*, ')
|
|
|
|
log.ODM_INFO(' *(@%************************************%@** ')
|
|
|
|
log.ODM_INFO(' **@%********************************&@*, ')
|
|
|
|
log.ODM_INFO(' *(@(****************************%@/* ')
|
|
|
|
log.ODM_INFO(' ,(@%************************#@/* ')
|
|
|
|
log.ODM_INFO(' ,*@%********************&@/, ')
|
|
|
|
log.ODM_INFO(' */@#****************#@/* ')
|
|
|
|
log.ODM_INFO(' ,/@&************#@/* ')
|
|
|
|
log.ODM_INFO(' ,*@&********%@/, ')
|
|
|
|
log.ODM_INFO(' */@#****(@/* ')
|
|
|
|
log.ODM_INFO(' ,/@@@@(* ')
|
|
|
|
log.ODM_INFO(' .**, ')
|
|
|
|
log.ODM_INFO('')
|
2019-04-04 16:30:28 +00:00
|
|
|
log.ODM_INFO("Running dense reconstruction. This might take a while. Please be patient, the process is not dead or hung.")
|
2019-04-04 16:41:27 +00:00
|
|
|
log.ODM_INFO(" Process is running")
|
2019-04-12 17:58:25 +00:00
|
|
|
system.run('%s %s %s' % (context.dmrecon_path, ' '.join(dmrecon_config), tree.mve), env_vars={'OMP_NUM_THREADS': args.max_concurrency})
|
2019-02-19 20:08:38 +00:00
|
|
|
|
2019-04-03 18:47:06 +00:00
|
|
|
scene2pset_config = [
|
2019-04-03 20:23:21 +00:00
|
|
|
"-F%s" % mve_output_scale
|
2019-04-03 18:47:06 +00:00
|
|
|
]
|
2019-02-19 20:08:38 +00:00
|
|
|
|
2019-03-20 20:55:35 +00:00
|
|
|
# run scene2pset
|
2019-04-12 17:58:25 +00:00
|
|
|
system.run('%s %s "%s" "%s"' % (context.scene2pset_path, ' '.join(scene2pset_config), tree.mve, tree.mve_model), env_vars={'OMP_NUM_THREADS': args.max_concurrency})
|
2018-06-27 18:32:49 +00:00
|
|
|
else:
|
2018-12-02 17:45:26 +00:00
|
|
|
log.ODM_WARNING('Found a valid MVE reconstruction file in: %s' %
|
|
|
|
tree.mve_model)
|