From f0f0765f97809fb6032e96f9384b2ec2958a5533 Mon Sep 17 00:00:00 2001 From: Pau Gargallo Date: Thu, 29 Sep 2016 15:10:24 +0200 Subject: [PATCH 1/7] Export paths before building, otherwise ecto build fails Former-commit-id: 2f2d3aa5c1f71d7d25ba933dfb80b0ac39b8b2bd --- configure.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/configure.sh b/configure.sh index dbebd753..7ccd8f12 100755 --- a/configure.sh +++ b/configure.sh @@ -1,5 +1,10 @@ #!/bin/bash +## Set up library paths +RUNPATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +export PYTHONPATH=$RUNPATH/SuperBuild/install/lib/python2.7/dist-packages:$RUNPATH/SuperBuild/src/opensfm:$PYTHONPATH +export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$RUNPATH/SuperBuild/install/lib + ## Before installing echo "Updating the system" sudo apt-get update From ab72eb381ffa6b6bdfc52b4c15ac853b8fadcdc6 Mon Sep 17 00:00:00 2001 From: Pau Gargallo Date: Thu, 29 Sep 2016 15:26:13 +0200 Subject: [PATCH 2/7] Build OpenSfM dense branch Former-commit-id: 5dd69b8f599d05f20e4f9cfec55b9f570f6dbbe4 --- SuperBuild/cmake/External-OpenSfM.cmake | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/SuperBuild/cmake/External-OpenSfM.cmake b/SuperBuild/cmake/External-OpenSfM.cmake index fefd20cf..56c81a3a 100644 --- a/SuperBuild/cmake/External-OpenSfM.cmake +++ b/SuperBuild/cmake/External-OpenSfM.cmake @@ -8,15 +8,17 @@ ExternalProject_Add(${_proj_name} STAMP_DIR ${_SB_BINARY_DIR}/stamp #--Download step-------------- DOWNLOAD_DIR ${SB_DOWNLOAD_DIR} - URL https://github.com/mapillary/OpenSfM/archive/a4b07056aec1184692c1432fbdd1074710aec32b.zip - URL_MD5 42B2B1994C3309BBF4525C8CC1F6F741 + GIT_REPOSITORY https://github.com/mapillary/OpenSfM.git + GIT_TAG dense #--Update/Patch step---------- UPDATE_COMMAND "" #--Configure step------------- SOURCE_DIR ${SB_SOURCE_DIR}/${_proj_name} CONFIGURE_COMMAND cmake /${_proj_name}/src - -DCERES_ROOT_DIR=${SB_INSTALL_DIR} + -DCERES_ROOT_DIR=${SB_INSTALL_DIR} -DOpenCV_DIR=${SB_INSTALL_DIR}/share/OpenCV + -DOPENSFM_BUILD_TESTS=off + #--Build step----------------- BINARY_DIR ${_SB_BINARY_DIR} #--Install step--------------- From 5fe2acd3600fdb20b36fb4a074c050c8a4649750 Mon Sep 17 00:00:00 2001 From: Pau Gargallo Date: Fri, 30 Sep 2016 15:08:56 +0200 Subject: [PATCH 3/7] Add option to compute and use OpenSfM's point cloud Former-commit-id: 6d94dcaf16d97ec7e509dfb01b81b1812da356b0 --- opendm/config.py | 6 +++++ opendm/types.py | 1 + scripts/mvstex.py | 20 ++++++++------ scripts/odm_app.py | 30 ++++++++++++--------- scripts/odm_georeferencing.py | 5 +++- scripts/odm_meshing.py | 5 +++- scripts/opensfm.py | 51 +++++++++++++++++++++-------------- 7 files changed, 76 insertions(+), 42 deletions(-) diff --git a/opendm/config.py b/opendm/config.py index e0394113..bcb99d0c 100644 --- a/opendm/config.py +++ b/opendm/config.py @@ -110,6 +110,12 @@ def config(): 'images based on GPS exif data. Set to 0 to skip ' 'pre-matching. Default: %(default)s') + parser.add_argument('--use-opensfm-pointcloud', + action='store_true', + default=False, + help='Use OpenSfM to compute the point cloud instead ' + 'of PMVS') + parser.add_argument('--cmvs-maxImages', metavar='', default=500, diff --git a/opendm/types.py b/opendm/types.py index 581d5753..edf524c3 100644 --- a/opendm/types.py +++ b/opendm/types.py @@ -360,6 +360,7 @@ class ODM_Tree(object): self.opensfm_bundle_list = io.join_paths(self.opensfm, 'list_r000.out') self.opensfm_image_list = io.join_paths(self.opensfm, 'image_list.txt') self.opensfm_reconstruction = io.join_paths(self.opensfm, 'reconstruction.json') + self.opensfm_model = io.join_paths(self.opensfm, 'depthmaps/merged.ply') # pmvs self.pmvs_rec_path = io.join_paths(self.pmvs, 'recon0') diff --git a/scripts/mvstex.py b/scripts/mvstex.py index fa860995..a893df22 100644 --- a/scripts/mvstex.py +++ b/scripts/mvstex.py @@ -84,14 +84,18 @@ class ODMMvsTexCell(ecto.Cell): 'skipHoleFilling': skipHoleFilling, 'keepUnseenFaces': keepUnseenFaces } - - log.ODM_DEBUG('Generating .nvm file from pmvs output: %s' - % '{nvm_file}'.format(**kwargs)) - - # Create .nvm camera file. - pmvs2nvmcams.run('{pmvs_folder}'.format(**kwargs), - '{nvm_file}'.format(**kwargs)) - + + if args.use_opensfm_pointcloud: + kwargs['nvm_file'] = io.join_paths(tree.opensfm, + "reconstruction.nvm") + else: + log.ODM_DEBUG('Generating .nvm file from pmvs output: %s' + % '{nvm_file}'.format(**kwargs)) + + # Create .nvm camera file. + pmvs2nvmcams.run('{pmvs_folder}'.format(**kwargs), + '{nvm_file}'.format(**kwargs)) + # run texturing binary system.run('{bin} {nvm_file} {model} {out_dir} ' '-d {dataTerm} -o {outlierRemovalType} ' diff --git a/scripts/odm_app.py b/scripts/odm_app.py index 008049a9..730165d9 100644 --- a/scripts/odm_app.py +++ b/scripts/odm_app.py @@ -110,20 +110,26 @@ class ODMApp(ecto.BlackBox): self.args[:] >> self.opensfm['args'], self.resize['photos'] >> self.opensfm['photos']] - # run cmvs - connections += [self.tree[:] >> self.cmvs['tree'], - self.args[:] >> self.cmvs['args'], - self.opensfm['reconstruction'] >> self.cmvs['reconstruction']] + if _p.args.use_opensfm_pointcloud: + # create odm mesh from opensfm point cloud + connections += [self.tree[:] >> self.meshing['tree'], + self.args[:] >> self.meshing['args'], + self.opensfm['reconstruction'] >> self.meshing['reconstruction']] + else: + # run cmvs + connections += [self.tree[:] >> self.cmvs['tree'], + self.args[:] >> self.cmvs['args'], + self.opensfm['reconstruction'] >> self.cmvs['reconstruction']] - # run pmvs - connections += [self.tree[:] >> self.pmvs['tree'], - self.args[:] >> self.pmvs['args'], - self.cmvs['reconstruction'] >> self.pmvs['reconstruction']] + # run pmvs + connections += [self.tree[:] >> self.pmvs['tree'], + self.args[:] >> self.pmvs['args'], + self.cmvs['reconstruction'] >> self.pmvs['reconstruction']] - # create odm mesh - connections += [self.tree[:] >> self.meshing['tree'], - self.args[:] >> self.meshing['args'], - self.pmvs['reconstruction'] >> self.meshing['reconstruction']] + # create odm mesh from pmvs point cloud + connections += [self.tree[:] >> self.meshing['tree'], + self.args[:] >> self.meshing['args'], + self.pmvs['reconstruction'] >> self.meshing['reconstruction']] # create odm texture connections += [self.tree[:] >> self.texturing['tree'], diff --git a/scripts/odm_georeferencing.py b/scripts/odm_georeferencing.py index 50f9fc39..00dbb9be 100644 --- a/scripts/odm_georeferencing.py +++ b/scripts/odm_georeferencing.py @@ -85,7 +85,6 @@ class ODMGeoreferencingCell(ecto.Cell): 'imgs': tree.dataset_raw, 'imgs_list': tree.opensfm_bundle_list, 'model': tree.odm_textured_model_obj, - 'pc': tree.pmvs_model, 'log': tree.odm_georeferencing_log, 'coords': tree.odm_georeferencing_coords, 'pc_geo': tree.odm_georeferencing_model_ply_geo, @@ -95,6 +94,10 @@ class ODMGeoreferencingCell(ecto.Cell): 'gcp': gcpfile, } + if args.use_opensfm_pointcloud: + kwargs['pc'] = tree.opensfm_model + else: + kwargs['pc'] = tree.pmvs_model if self.params.use_gcp and \ io.file_exists(gcpfile): diff --git a/scripts/odm_meshing.py b/scripts/odm_meshing.py index dc8f1973..1db4dab8 100644 --- a/scripts/odm_meshing.py +++ b/scripts/odm_meshing.py @@ -52,7 +52,6 @@ class ODMeshingCell(ecto.Cell): kwargs = { 'bin': context.odm_modules_path, - 'infile': tree.pmvs_model, 'outfile': tree.odm_mesh, 'log': tree.odm_meshing_log, 'max_vertex': self.params.max_vertex, @@ -60,6 +59,10 @@ class ODMeshingCell(ecto.Cell): 'samples': self.params.samples, 'solver': self.params.solver } + if args.use_opensfm_pointcloud: + kwargs['infile'] = tree.opensfm_model + else: + kwargs['infile'] = tree.pmvs_model # run meshing binary system.run('{bin}/odm_meshing -inputFile {infile} ' diff --git a/scripts/opensfm.py b/scripts/opensfm.py index 21d80221..6b98c4f4 100644 --- a/scripts/opensfm.py +++ b/scripts/opensfm.py @@ -48,9 +48,13 @@ class ODMOpenSfMCell(ecto.Cell): (args.rerun_from is not None and 'opensfm' in args.rerun_from) - # check if reconstruction was done before + if args.use_opensfm_pointcloud: + output_file = tree.opensfm_model + else: + output_file = tree.opensfm_reconstruction - if not io.file_exists(tree.opensfm_reconstruction) or rerun_cell: + # check if reconstruction was done before + if not io.file_exists(output_file) or rerun_cell: # create file list list_path = io.join_paths(tree.opensfm, 'image_list.txt') with open(list_path, 'w') as fout: @@ -77,31 +81,38 @@ class ODMOpenSfMCell(ecto.Cell): # run OpenSfM reconstruction system.run('PYTHONPATH=%s %s/bin/run_all %s' % (context.pyopencv_path, context.opensfm_path, tree.opensfm)) + if args.use_opensfm_pointcloud: + system.run('PYTHONPATH=%s %s/bin/opensfm export_visualsfm %s' % + (context.pyopencv_path, context.opensfm_path, tree.opensfm)) + system.run('PYTHONPATH=%s %s/bin/opensfm undistort %s' % + (context.pyopencv_path, context.opensfm_path, tree.opensfm)) + system.run('PYTHONPATH=%s %s/bin/opensfm compute_depthmaps %s' % + (context.pyopencv_path, context.opensfm_path, tree.opensfm)) else: log.ODM_WARNING('Found a valid OpenSfM file in: %s' % tree.opensfm_reconstruction) - # check if reconstruction was exported to bundler before + if not args.use_opensfm_pointcloud: + # check if reconstruction was exported to bundler before + if not io.file_exists(tree.opensfm_bundle_list) or rerun_cell: + # convert back to bundler's format + system.run('PYTHONPATH=%s %s/bin/export_bundler %s' % + (context.pyopencv_path, context.opensfm_path, tree.opensfm)) + else: + log.ODM_WARNING('Found a valid Bundler file in: %s' % + tree.opensfm_reconstruction) - if not io.file_exists(tree.opensfm_bundle_list) or rerun_cell: - # convert back to bundler's format - system.run('PYTHONPATH=%s %s/bin/export_bundler %s' % - (context.pyopencv_path, context.opensfm_path, tree.opensfm)) - else: - log.ODM_WARNING('Found a valid Bundler file in: %s' % - tree.opensfm_reconstruction) + # check if reconstruction was exported to pmvs before - # check if reconstruction was exported to pmvs before + if not io.file_exists(tree.pmvs_visdat) or rerun_cell: + # run PMVS converter + system.run('PYTHONPATH=%s %s/bin/export_pmvs %s --output %s' % + (context.pyopencv_path, context.opensfm_path, tree.opensfm, tree.pmvs)) + else: + log.ODM_WARNING('Found a valid CMVS file in: %s' % tree.pmvs_visdat) - if not io.file_exists(tree.pmvs_visdat) or rerun_cell: - # run PMVS converter - system.run('PYTHONPATH=%s %s/bin/export_pmvs %s --output %s' % - (context.pyopencv_path, context.opensfm_path, tree.opensfm, tree.pmvs)) - else: - log.ODM_WARNING('Found a valid CMVS file in: %s' % tree.pmvs_visdat) - - if args.time: - system.benchmark(start_time, tree.benchmarking, 'OpenSfM') + if args.time: + system.benchmark(start_time, tree.benchmarking, 'OpenSfM') log.ODM_INFO('Running ODM OpenSfM Cell - Finished') return ecto.OK if args.end_with != 'opensfm' else ecto.QUIT From 5c46d5e7ef3eb71cb8e02ded9a4e597707ad92b0 Mon Sep 17 00:00:00 2001 From: Pau Gargallo Date: Fri, 30 Sep 2016 15:43:27 +0200 Subject: [PATCH 4/7] Install pyproj Former-commit-id: bfadf0ec10d99bd58d202e8b4acce2895c7cf839 --- configure.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/configure.sh b/configure.sh index 7ccd8f12..b2049791 100755 --- a/configure.sh +++ b/configure.sh @@ -58,7 +58,8 @@ sudo apt-get install -y -qq python-networkx \ libboost-regex-dev \ libboost-python-dev \ libboost-date-time-dev \ - libboost-thread-dev + libboost-thread-dev \ + python-pyproj sudo pip install -U PyYAML \ exifread \ From 160b282fa66a81c5f4f8350dfe57b4bf03fd2a42 Mon Sep 17 00:00:00 2001 From: Pau Gargallo Date: Fri, 30 Sep 2016 16:11:10 +0200 Subject: [PATCH 5/7] Export to bundler format even if using OpenSfM point cloud. odm_extract_utm uses the list_r000.txt file. Former-commit-id: d1caf45ad6f6e265f5bf25e47ad43da47c0fec2a --- scripts/opensfm.py | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/scripts/opensfm.py b/scripts/opensfm.py index 6b98c4f4..4f99f539 100644 --- a/scripts/opensfm.py +++ b/scripts/opensfm.py @@ -92,18 +92,17 @@ class ODMOpenSfMCell(ecto.Cell): log.ODM_WARNING('Found a valid OpenSfM file in: %s' % tree.opensfm_reconstruction) + # check if reconstruction was exported to bundler before + if not io.file_exists(tree.opensfm_bundle_list) or rerun_cell: + # convert back to bundler's format + system.run('PYTHONPATH=%s %s/bin/export_bundler %s' % + (context.pyopencv_path, context.opensfm_path, tree.opensfm)) + else: + log.ODM_WARNING('Found a valid Bundler file in: %s' % + tree.opensfm_reconstruction) + if not args.use_opensfm_pointcloud: - # check if reconstruction was exported to bundler before - if not io.file_exists(tree.opensfm_bundle_list) or rerun_cell: - # convert back to bundler's format - system.run('PYTHONPATH=%s %s/bin/export_bundler %s' % - (context.pyopencv_path, context.opensfm_path, tree.opensfm)) - else: - log.ODM_WARNING('Found a valid Bundler file in: %s' % - tree.opensfm_reconstruction) - # check if reconstruction was exported to pmvs before - if not io.file_exists(tree.pmvs_visdat) or rerun_cell: # run PMVS converter system.run('PYTHONPATH=%s %s/bin/export_pmvs %s --output %s' % From 88a476646d00f8561586dd723f27c27121a818bf Mon Sep 17 00:00:00 2001 From: Pau Gargallo Date: Mon, 3 Oct 2016 15:52:06 +0200 Subject: [PATCH 6/7] Use OpenSfM's master branch Former-commit-id: b60abe3a4d6c9c89ed81508132443775476722d4 --- SuperBuild/cmake/External-OpenSfM.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SuperBuild/cmake/External-OpenSfM.cmake b/SuperBuild/cmake/External-OpenSfM.cmake index 56c81a3a..e487ba57 100644 --- a/SuperBuild/cmake/External-OpenSfM.cmake +++ b/SuperBuild/cmake/External-OpenSfM.cmake @@ -9,7 +9,7 @@ ExternalProject_Add(${_proj_name} #--Download step-------------- DOWNLOAD_DIR ${SB_DOWNLOAD_DIR} GIT_REPOSITORY https://github.com/mapillary/OpenSfM.git - GIT_TAG dense + GIT_TAG master #--Update/Patch step---------- UPDATE_COMMAND "" #--Configure step------------- From 7f5103772d027b62af71a6fb51365fb0b9fad53a Mon Sep 17 00:00:00 2001 From: Pau Gargallo Date: Tue, 4 Oct 2016 15:48:28 +0200 Subject: [PATCH 7/7] Fetch opensfm release instead of git's master Former-commit-id: e3187de10f13fdb91c395057acf2ad60c1a23e62 --- SuperBuild/cmake/External-OpenSfM.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SuperBuild/cmake/External-OpenSfM.cmake b/SuperBuild/cmake/External-OpenSfM.cmake index e487ba57..049322a7 100644 --- a/SuperBuild/cmake/External-OpenSfM.cmake +++ b/SuperBuild/cmake/External-OpenSfM.cmake @@ -8,8 +8,8 @@ ExternalProject_Add(${_proj_name} STAMP_DIR ${_SB_BINARY_DIR}/stamp #--Download step-------------- DOWNLOAD_DIR ${SB_DOWNLOAD_DIR} - GIT_REPOSITORY https://github.com/mapillary/OpenSfM.git - GIT_TAG master + URL https://github.com/mapillary/OpenSfM/archive/odm-3.zip + URL_MD5 a0853c6fe6d8193f7006e17dd896154e #--Update/Patch step---------- UPDATE_COMMAND "" #--Configure step-------------