Local submodel reconstruction, alignment

pull/979/head
Piero Toffanin 2019-04-23 18:01:14 -04:00
rodzic 277b60c22d
commit 3087af2775
5 zmienionych plików z 62 dodań i 31 usunięć

Wyświetl plik

@ -2,6 +2,7 @@
OpenSfM related utils
"""
import os
from opendm import io
from opendm import log
from opendm import system
@ -13,7 +14,7 @@ def run(command, opensfm_project_path):
def export_bundler(opensfm_project_path, destination_bundle_file, rerun=False):
if not io.file_exists(destination_bundle_file) or self.rerun():
if not io.file_exists(destination_bundle_file) or rerun:
# convert back to bundler's format
system.run('%s/bin/export_bundler %s' %
(context.opensfm_path, opensfm_project_path))
@ -21,6 +22,31 @@ def export_bundler(opensfm_project_path, destination_bundle_file, rerun=False):
log.ODM_WARNING('Found a valid Bundler file in: %s' % destination_bundle_file)
def reconstruct(opensfm_project_path, rerun=False):
tracks_file = os.path.join(opensfm_project_path, 'tracks.csv')
reconstruction_file = os.path.join(opensfm_project_path, 'reconstruction.json')
if not io.file_exists(tracks_file) or rerun:
run('create_tracks', opensfm_project_path)
else:
log.ODM_WARNING('Found a valid OpenSfM tracks file in: %s' % tracks_file)
if not io.file_exists(reconstruction_file) or rerun:
run('reconstruct', opensfm_project_path)
else:
log.ODM_WARNING('Found a valid OpenSfM reconstruction file in: %s' % reconstruction_file)
# Check that a reconstruction file has been created
if not io.file_exists(reconstruction_file):
log.ODM_ERROR("The program could not process this dataset using the current settings. "
"Check that the images have enough overlap, "
"that there are enough recognizable features "
"and that the images are in focus. "
"You could also try to increase the --min-num-features parameter."
"The program will now exit.")
raise Exception("Reconstruction could not be generated")
def setup(args, images_path, opensfm_path, photos, gcp_path=None, append_config = []):
"""
Setup a OpenSfM project
@ -82,7 +108,7 @@ def setup(args, images_path, opensfm_path, photos, gcp_path=None, append_config
with open(config_filename, 'w') as fout:
fout.write("\n".join(config))
def run_feature_matching(opensfm_project_path, rerun=False):
def feature_matching(opensfm_project_path, rerun=False):
matched_done_file = io.join_paths(opensfm_project_path, 'matching_done.txt')
if not io.file_exists(matched_done_file) or rerun:
run('extract_metadata', opensfm_project_path)

Wyświetl plik

@ -373,11 +373,9 @@ class ODM_Stage:
"""
Does this stage need to be rerun?
"""
return (self.args.rerun is not None and
self.args.rerun == self.name) or \
return (self.args.rerun is not None and self.args.rerun == self.name) or \
(self.args.rerun_all) or \
(self.args.rerun_from is not None and
self.name in self.args.rerun_from)
(self.args.rerun_from is not None and self.name in self.args.rerun_from)
def run(self, outputs = {}):
start_time = system.now_raw()

0
run.py 100644 → 100755
Wyświetl plik

Wyświetl plik

@ -28,34 +28,15 @@ class ODMOpenSfMStage(types.ODM_Stage):
output_file = tree.opensfm_reconstruction
# check if reconstruction was done before
# TODO: more granularity for each step (setup/featurematch/reconstruction/etc.)
if not io.file_exists(output_file) or self.rerun():
osfm.setup(args, tree.dataset_raw, tree.opensfm, photos, gcp_path=tree.odm_georeferencing_gcp)
osfm.run_feature_matching(tree.opensfm, self.rerun())
if not io.file_exists(tree.opensfm_tracks) or self.rerun():
osfm.run('create_tracks', tree.opensfm)
else:
log.ODM_WARNING('Found a valid OpenSfM tracks file in: %s' %
tree.opensfm_tracks)
if not io.file_exists(tree.opensfm_reconstruction) or self.rerun():
osfm.run('reconstruct', tree.opensfm)
else:
log.ODM_WARNING('Found a valid OpenSfM reconstruction file in: %s' %
tree.opensfm_reconstruction)
# Check that a reconstruction file has been created
if not io.file_exists(tree.opensfm_reconstruction):
log.ODM_ERROR("The program could not process this dataset using the current settings. "
"Check that the images have enough overlap, "
"that there are enough recognizable features "
"and that the images are in focus. "
"You could also try to increase the --min-num-features parameter."
"The program will now exit.")
sys.exit(1)
osfm.feature_matching(tree.opensfm, self.rerun())
osfm.reconstruction(tree.opensfm, self.rerun())
# Always export VisualSFM's reconstruction and undistort images
# as we'll use these for texturing (after GSD estimation and resizing)

Wyświetl plik

@ -1,7 +1,9 @@
import os
from opendm import log
from opendm import osfm
from opendm import types
from opendm import io
from opensfm.large import metadataset
class ODMSplitStage(types.ODM_Stage):
def process(self, args, outputs):
@ -23,7 +25,7 @@ class ODMSplitStage(types.ODM_Stage):
osfm.setup(args, tree.dataset_raw, tree.opensfm, photos, gcp_path=tree.odm_georeferencing_gcp, append_config=config)
osfm.run_feature_matching(tree.opensfm, self.rerun())
osfm.feature_matching(tree.opensfm, self.rerun())
# Create submodels
if not io.dir_exists(tree.submodels_path) or self.rerun():
@ -34,8 +36,32 @@ class ODMSplitStage(types.ODM_Stage):
osfm.run("create_submodels", tree.opensfm)
else:
log.ODM_WARNING("Submodels directory already exist at: %s" % tree.submodels_path)
# TODO: on a network workflow we probably stop here
# and let NodeODM take over
# exit(0)
# Find paths of all submodels
mds = metadataset.MetaDataSet(tree.opensfm)
submodel_paths = [os.path.abspath(p) for p in mds.get_submodel_paths()]
# Reconstruct each submodel
log.ODM_INFO("Dataset has been split into %s submodels. Reconstructing each submodel..." % len(submodel_paths))
for sp in submodel_paths:
log.ODM_INFO("Reconstructing %s" % sp)
osfm.reconstruct(sp, self.rerun())
# Align
log.ODM_INFO("Aligning submodels...")
osfm.run('align_submodels', tree.opensfm)
# Dense reconstruction for each submodel
# TODO
exit(1)
else:
log.ODM_INFO("Normal dataset, will process all at once.")