kopia lustrzana https://github.com/OpenDroneMap/ODM
				
				
				
			
		
			
				
	
	
		
			151 wiersze
		
	
	
		
			6.7 KiB
		
	
	
	
		
			Python
		
	
	
			
		
		
	
	
			151 wiersze
		
	
	
		
			6.7 KiB
		
	
	
	
		
			Python
		
	
	
| import ecto, os, shutil
 | |
| 
 | |
| from opendm import log
 | |
| from opendm import io
 | |
| from opendm import system
 | |
| from opendm import context
 | |
| 
 | |
| import pmvs2nvmcams
 | |
| 
 | |
| class ODMMvsTexCell(ecto.Cell):
 | |
|     def declare_params(self, params):
 | |
|         params.declare("data_term", 'Data term: [area, gmi] default: gmi', "gmi")
 | |
|         params.declare("outlier_rem_type", 'Type of photometric outlier removal method: [none, gauss_damping, gauss_clamping]. default: none', "none")
 | |
|         params.declare("skip_vis_test", 'Skip geometric visibility test based on ray intersection.', False)
 | |
|         params.declare("skip_glob_seam_leveling", 'Skip global seam leveling.', False)
 | |
|         params.declare("skip_loc_seam_leveling", 'Skip local seam leveling (Poisson editing).', False)
 | |
|         params.declare("skip_hole_fill", 'Skip hole filling.', False)
 | |
|         params.declare("keep_unseen_faces", 'Keep unseen faces.', False)
 | |
|         params.declare("tone_mapping", 'Type of tone mapping: [none, gamma]. Default: gamma', "gamma")
 | |
| 
 | |
|     def declare_io(self, params, inputs, outputs):
 | |
|         inputs.declare("tree", "Struct with paths", [])
 | |
|         inputs.declare("args", "The application arguments.", {})
 | |
|         inputs.declare("reconstruction", "Clusters output. list of ODMReconstructions", [])
 | |
|         outputs.declare("reconstruction", "Clusters output. list of ODMReconstructions", [])
 | |
| 
 | |
|     def process(self, inputs, outputs):
 | |
| 
 | |
|         # Benchmarking
 | |
|         start_time = system.now_raw()
 | |
| 
 | |
|         log.ODM_INFO('Running MVS Texturing Cell')
 | |
| 
 | |
|         # get inputs
 | |
|         args = inputs.args
 | |
|         tree = inputs.tree
 | |
|         reconstruction = inputs.reconstruction
 | |
| 
 | |
|         # define paths and create working directories
 | |
|         system.mkdir_p(tree.odm_texturing)
 | |
|         if args.use_25dmesh: system.mkdir_p(tree.odm_25dtexturing) 
 | |
| 
 | |
|         # check if we rerun cell or not
 | |
|         rerun_cell = (args.rerun is not None and
 | |
|                       args.rerun == 'mvs_texturing') or \
 | |
|                      (args.rerun_all) or \
 | |
|                      (args.rerun_from is not None and
 | |
|                       'mvs_texturing' in args.rerun_from)
 | |
| 
 | |
|         runs = [{
 | |
|             'out_dir': tree.odm_texturing,
 | |
|             'model': tree.odm_mesh,
 | |
|             'force_skip_vis_test': False
 | |
|         }]
 | |
| 
 | |
|         if args.fast_orthophoto:
 | |
|             runs = []
 | |
| 
 | |
|         if args.use_25dmesh:
 | |
|             runs += [{
 | |
|                     'out_dir': tree.odm_25dtexturing,
 | |
|                     'model': tree.odm_25dmesh,
 | |
| 
 | |
|                     # We always skip the visibility test when using the 2.5D mesh
 | |
|                     # because many faces end up being narrow, and almost perpendicular 
 | |
|                     # to the ground plane. The visibility test improperly classifies
 | |
|                     # them as "not seen" since the test is done on a single triangle vertex,
 | |
|                     # and while one vertex might be occluded, the other two might not.
 | |
|                     'force_skip_vis_test': True 
 | |
|                 }]
 | |
| 
 | |
|         for r in runs:
 | |
|             odm_textured_model_obj = os.path.join(r['out_dir'], tree.odm_textured_model_obj)
 | |
| 
 | |
|             if not io.file_exists(odm_textured_model_obj) or rerun_cell:
 | |
|                 log.ODM_DEBUG('Writing MVS Textured file in: %s'
 | |
|                               % odm_textured_model_obj)
 | |
| 
 | |
|                 # Format arguments to fit Mvs-Texturing app
 | |
|                 skipGeometricVisibilityTest = ""
 | |
|                 skipGlobalSeamLeveling = ""
 | |
|                 skipLocalSeamLeveling = ""
 | |
|                 skipHoleFilling = ""
 | |
|                 keepUnseenFaces = ""
 | |
|                 
 | |
|                 if (self.params.skip_vis_test or r['force_skip_vis_test']):
 | |
|                     skipGeometricVisibilityTest = "--skip_geometric_visibility_test"
 | |
|                 if (self.params.skip_glob_seam_leveling):
 | |
|                     skipGlobalSeamLeveling = "--skip_global_seam_leveling"
 | |
|                 if (self.params.skip_loc_seam_leveling):
 | |
|                     skipLocalSeamLeveling = "--skip_local_seam_leveling"
 | |
|                 if (self.params.skip_hole_fill):
 | |
|                     skipHoleFilling = "--skip_hole_filling"
 | |
|                 if (self.params.keep_unseen_faces):
 | |
|                     keepUnseenFaces = "--keep_unseen_faces"
 | |
| 
 | |
|                 # mvstex definitions
 | |
|                 kwargs = {
 | |
|                     'bin': context.mvstex_path,
 | |
|                     'out_dir': io.join_paths(r['out_dir'], "odm_textured_model"),
 | |
|                     'pmvs_folder': tree.pmvs_rec_path,
 | |
|                     'nvm_file': io.join_paths(tree.pmvs_rec_path, "nvmCams.nvm"),
 | |
|                     'model': r['model'],
 | |
|                     'dataTerm': self.params.data_term,
 | |
|                     'outlierRemovalType': self.params.outlier_rem_type,
 | |
|                     'skipGeometricVisibilityTest': skipGeometricVisibilityTest,
 | |
|                     'skipGlobalSeamLeveling': skipGlobalSeamLeveling,
 | |
|                     'skipLocalSeamLeveling': skipLocalSeamLeveling,
 | |
|                     'skipHoleFilling': skipHoleFilling,
 | |
|                     'keepUnseenFaces': keepUnseenFaces,
 | |
|                     'toneMapping': self.params.tone_mapping
 | |
|                 }
 | |
| 
 | |
|                 if not args.use_pmvs:
 | |
|                     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))
 | |
| 
 | |
|                 # Make sure tmp directory is empty
 | |
|                 mvs_tmp_dir = os.path.join(r['out_dir'], 'tmp')
 | |
|                 if io.dir_exists(mvs_tmp_dir):
 | |
|                     log.ODM_INFO("Removing old tmp directory {}".format(mvs_tmp_dir))
 | |
|                     shutil.rmtree(mvs_tmp_dir)
 | |
| 
 | |
|                 # run texturing binary
 | |
|                 system.run('{bin} {nvm_file} {model} {out_dir} '
 | |
|                            '-d {dataTerm} -o {outlierRemovalType} '
 | |
|                            '-t {toneMapping} '
 | |
|                            '{skipGeometricVisibilityTest} '
 | |
|                            '{skipGlobalSeamLeveling} '
 | |
|                            '{skipLocalSeamLeveling} '
 | |
|                            '{skipHoleFilling} '
 | |
|                            '{keepUnseenFaces}'.format(**kwargs))
 | |
|             else:
 | |
|                 log.ODM_WARNING('Found a valid ODM Texture file in: %s'
 | |
|                                 % odm_textured_model_obj)
 | |
| 
 | |
|         outputs.reconstruction = reconstruction
 | |
| 
 | |
|         if args.time:
 | |
|             system.benchmark(start_time, tree.benchmarking, 'Texturing')
 | |
| 
 | |
|         log.ODM_INFO('Running ODM Texturing Cell - Finished')
 | |
|         return ecto.OK if args.end_with != 'mvs_texturing' else ecto.QUIT
 |