From 9183218f1b29273bb76221b77720d3f2dbea249e Mon Sep 17 00:00:00 2001 From: Piero Toffanin Date: Fri, 12 Jan 2024 00:20:35 -0500 Subject: [PATCH 01/17] Bump version --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index a0891f563..fa7adc7ac 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.3.4 +3.3.5 From f79362740289b1d6aafceffdaf9782f821d0f787 Mon Sep 17 00:00:00 2001 From: Piero Toffanin Date: Mon, 15 Jan 2024 09:51:17 -0500 Subject: [PATCH 02/17] Ignore multispectral band groups that are missing images --- opendm/osfm.py | 1 - opendm/types.py | 47 ++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 40 insertions(+), 8 deletions(-) diff --git a/opendm/osfm.py b/opendm/osfm.py index 2c3a7dcd2..7a3f2e039 100644 --- a/opendm/osfm.py +++ b/opendm/osfm.py @@ -64,7 +64,6 @@ def reconstruct(self, rolling_shutter_correct=False, merge_partial=False, rerun= "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.") if rolling_shutter_correct: diff --git a/opendm/types.py b/opendm/types.py index ccab5ede3..3e437c0f2 100644 --- a/opendm/types.py +++ b/opendm/types.py @@ -13,6 +13,7 @@ from opendm import io from opendm import system from opendm import context +from opendm import multispectral from opendm.progress import progressbc from opendm.photo import ODM_Photo @@ -45,19 +46,51 @@ def detect_multi_camera(self): band_photos[p.band_name].append(p) bands_count = len(band_photos) - if bands_count >= 2 and bands_count <= 8: + + # Band name with the minimum number of photos + max_band_name = None + max_photos = -1 + for band_name in band_photos: + if len(band_photos[band_name]) > max_photos: + max_band_name = band_name + max_photos = len(band_photos[band_name]) + + if bands_count >= 2 and bands_count <= 10: # Validate that all bands have the same number of images, # otherwise this is not a multi-camera setup - img_per_band = len(band_photos[p.band_name]) - for band in band_photos: - if len(band_photos[band]) != img_per_band: - log.ODM_ERROR("Multi-camera setup detected, but band \"%s\" (identified from \"%s\") has only %s images (instead of %s), perhaps images are missing or are corrupted. Please include all necessary files to process all bands and try again." % (band, band_photos[band][0].filename, len(band_photos[band]), img_per_band)) - raise RuntimeError("Invalid multi-camera images") + img_per_band = len(band_photos[max_band_name]) mc = [] for band_name in band_indexes: mc.append({'name': band_name, 'photos': band_photos[band_name]}) + filter_missing = False + for band in band_photos: + if len(band_photos[band]) < img_per_band: + log.ODM_WARNING("Multi-camera setup detected, but band \"%s\" (identified from \"%s\") has only %s images (instead of %s), perhaps images are missing or are corrupted." % (band, band_photos[band][0].filename, len(band_photos[band]), len(band_photos[max_band_name]))) + filter_missing = True + + if filter_missing: + # Calculate files to ignore + _, p2s = multispectral.compute_band_maps(mc, max_band_name) + + max_files_per_band = 0 + + for filename in p2s: + max_files_per_band = max(max_files_per_band, len(p2s[filename])) + + for filename in p2s: + if len(p2s[filename]) < max_files_per_band: + photos_to_remove = p2s[filename] + [p for p in self.photos if p.filename == filename] + for photo in photos_to_remove: + log.ODM_WARNING("Excluding %s" % photo.filename) + + self.photos = [p for p in self.photos if p != photo] + for i in range(len(mc)): + mc[i]['photos'] = [p for p in mc[i]['photos'] if p != photo] + + log.ODM_INFO("New image count: %s" % len(self.photos)) + # We enforce a normalized band order for all bands that we can identify # and rely on the manufacturer's band_indexes as a fallback for all others normalized_band_order = { @@ -94,7 +127,7 @@ def detect_multi_camera(self): for c, d in enumerate(mc): log.ODM_INFO(f"Band {c + 1}: {d['name']}") - + return mc return None From 260b4ef8647119ed330d3570b230714c193a34fe Mon Sep 17 00:00:00 2001 From: Piero Toffanin Date: Mon, 15 Jan 2024 16:21:08 -0500 Subject: [PATCH 03/17] Manually install numpy --- configure.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/configure.sh b/configure.sh index 2648f7a88..93fa32999 100755 --- a/configure.sh +++ b/configure.sh @@ -127,6 +127,9 @@ installreqs() { installdepsfromsnapcraft build openmvs set -e + + # edt requires numpy to build + pip install --ignore-installed numpy==1.23.1 pip install --ignore-installed -r requirements.txt #if [ ! -z "$GPU_INSTALL" ]; then #fi From fb85b754fb7c5e0180ce8da87b207ceb662bbfaa Mon Sep 17 00:00:00 2001 From: Piero Toffanin Date: Tue, 23 Jan 2024 17:03:36 -0500 Subject: [PATCH 04/17] Classify point cloud before generating derivative outputs --- VERSION | 2 +- opendm/config.py | 4 ++-- opendm/point_cloud.py | 28 ++++++++++++++++++++++++++++ stages/odm_dem.py | 29 +---------------------------- 4 files changed, 32 insertions(+), 31 deletions(-) diff --git a/VERSION b/VERSION index fa7adc7ac..18091983f 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.3.5 +3.4.0 diff --git a/opendm/config.py b/opendm/config.py index 3f51ff204..3db8151f7 100755 --- a/opendm/config.py +++ b/opendm/config.py @@ -60,14 +60,14 @@ 'orthophoto_no_tiled': 'odm_orthophoto', 'orthophoto_png': 'odm_orthophoto', 'orthophoto_resolution': 'odm_orthophoto', - 'pc_classify': 'odm_dem', + 'pc_classify': 'odm_georeferencing', 'pc_copc': 'odm_georeferencing', 'pc_csv': 'odm_georeferencing', 'pc_ept': 'odm_georeferencing', 'pc_filter': 'openmvs', 'pc_las': 'odm_georeferencing', 'pc_quality': 'opensfm', - 'pc_rectify': 'odm_dem', + 'pc_rectify': 'odm_georeferencing', 'pc_sample': 'odm_filterpoints', 'pc_skip_geometric': 'openmvs', 'primary_band': 'dataset', diff --git a/opendm/point_cloud.py b/opendm/point_cloud.py index abe7ee916..0c16c4930 100644 --- a/opendm/point_cloud.py +++ b/opendm/point_cloud.py @@ -9,6 +9,8 @@ from opendm.utils import double_quote from opendm.boundary import as_polygon, as_geojson from opendm.dem.pdal import run_pipeline +from opendm.opc import classify +from opendm.dem import commands def ply_info(input_ply): if not os.path.exists(input_ply): @@ -274,6 +276,32 @@ def merge_ply(input_point_cloud_files, output_file, dims=None): system.run(' '.join(cmd)) def post_point_cloud_steps(args, tree, rerun=False): + # Classify and rectify before generating derivate files + if args.pc_classify: + pc_classify_marker = os.path.join(tree.odm_georeferencing, 'pc_classify_done.txt') + + if not io.file_exists(pc_classify_marker) or rerun: + log.ODM_INFO("Classifying {} using Simple Morphological Filter (1/2)".format(tree.odm_georeferencing_model_laz)) + commands.classify(tree.odm_georeferencing_model_laz, + args.smrf_scalar, + args.smrf_slope, + args.smrf_threshold, + args.smrf_window + ) + + log.ODM_INFO("Classifying {} using OpenPointClass (2/2)".format(tree.odm_georeferencing_model_laz)) + classify(tree.odm_georeferencing_model_laz, args.max_concurrency) + + with open(pc_classify_marker, 'w') as f: + f.write('Classify: smrf\n') + f.write('Scalar: {}\n'.format(args.smrf_scalar)) + f.write('Slope: {}\n'.format(args.smrf_slope)) + f.write('Threshold: {}\n'.format(args.smrf_threshold)) + f.write('Window: {}\n'.format(args.smrf_window)) + + if args.pc_rectify: + commands.rectify(tree.odm_georeferencing_model_laz) + # XYZ point cloud output if args.pc_csv: log.ODM_INFO("Creating CSV file (XYZ format)") diff --git a/stages/odm_dem.py b/stages/odm_dem.py index 1146879a8..6964e036d 100755 --- a/stages/odm_dem.py +++ b/stages/odm_dem.py @@ -12,7 +12,6 @@ from opendm import pseudogeo from opendm.tiles.tiler import generate_dem_tiles from opendm.cogeo import convert_to_cogeo -from opendm.opc import classify class ODMDEMStage(types.ODM_Stage): def process(self, args, outputs): @@ -35,7 +34,6 @@ def process(self, args, outputs): ignore_resolution=ignore_resolution and args.ignore_gsd, has_gcp=reconstruction.has_gcp()) - log.ODM_INFO('Classify: ' + str(args.pc_classify)) log.ODM_INFO('Create DSM: ' + str(args.dsm)) log.ODM_INFO('Create DTM: ' + str(args.dtm)) log.ODM_INFO('DEM input file {0} found: {1}'.format(dem_input, str(pc_model_found))) @@ -45,34 +43,9 @@ def process(self, args, outputs): if not io.dir_exists(odm_dem_root): system.mkdir_p(odm_dem_root) - if args.pc_classify and pc_model_found: - pc_classify_marker = os.path.join(odm_dem_root, 'pc_classify_done.txt') - - if not io.file_exists(pc_classify_marker) or self.rerun(): - log.ODM_INFO("Classifying {} using Simple Morphological Filter (1/2)".format(dem_input)) - commands.classify(dem_input, - args.smrf_scalar, - args.smrf_slope, - args.smrf_threshold, - args.smrf_window - ) - - log.ODM_INFO("Classifying {} using OpenPointClass (2/2)".format(dem_input)) - classify(dem_input, args.max_concurrency) - - with open(pc_classify_marker, 'w') as f: - f.write('Classify: smrf\n') - f.write('Scalar: {}\n'.format(args.smrf_scalar)) - f.write('Slope: {}\n'.format(args.smrf_slope)) - f.write('Threshold: {}\n'.format(args.smrf_threshold)) - f.write('Window: {}\n'.format(args.smrf_window)) - progress = 20 self.update_progress(progress) - if args.pc_rectify: - commands.rectify(dem_input) - # Do we need to process anything here? if (args.dsm or args.dtm) and pc_model_found: dsm_output_filename = os.path.join(odm_dem_root, 'dsm.tif') @@ -120,7 +93,7 @@ def process(self, args, outputs): if args.cog: convert_to_cogeo(dem_geotiff_path, max_workers=args.max_concurrency) - progress += 30 + progress += 40 self.update_progress(progress) else: log.ODM_WARNING('Found existing outputs in: %s' % odm_dem_root) From 9fd3bf3eddbc856511eb931613b6157606c99f6c Mon Sep 17 00:00:00 2001 From: Piero Toffanin Date: Tue, 23 Jan 2024 22:24:38 +0000 Subject: [PATCH 05/17] Improve SRT parser to handle abs_alt altitude reference --- opendm/video/srtparser.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/opendm/video/srtparser.py b/opendm/video/srtparser.py index c7188f863..fc5bf0618 100644 --- a/opendm/video/srtparser.py +++ b/opendm/video/srtparser.py @@ -54,8 +54,10 @@ def get_gps(self, timestamp): if not self.gps_data: for d in self.data: lat, lon, alt = d.get('latitude'), d.get('longitude'), d.get('altitude') + if alt is None: + alt = 0 tm = d.get('start') - + if lat is not None and lon is not None: if self.ll_to_utm is None: self.ll_to_utm, self.utm_to_ll = location.utm_transformers_from_ll(lon, lat) @@ -127,6 +129,13 @@ def parse(self): # 00:00:35,000 --> 00:00:36,000 # F/6.3, SS 60, ISO 100, EV 0, RTK (120.083799, 30.213635, 28), HOME (120.084146, 30.214243, 103.55m), D 75.36m, H 76.19m, H.S 0.30m/s, V.S 0.00m/s, F.PRY (-5.3°, 2.1°, 28.3°), G.PRY (-40.0°, 0.0°, 28.2°) + # DJI Unknown Model #1 + # 1 + # 00:00:00,000 --> 00:00:00,033 + # SrtCnt : 1, DiffTime : 33ms + # 2024-01-18 10:23:26.397 + # [iso : 150] [shutter : 1/5000.0] [fnum : 170] [ev : 0] [ct : 5023] [color_md : default] [focal_len : 240] [dzoom_ratio: 10000, delta:0],[latitude: -22.724555] [longitude: -47.602414] [rel_alt: 0.300 abs_alt: 549.679] + with open(self.filename, 'r') as f: iso = None @@ -211,4 +220,5 @@ def parse(self): ("altitude: ([\d\.\-]+)", lambda v: float(v) if v != 0 else None), ("GPS \([\d\.\-]+,? [\d\.\-]+,? ([\d\.\-]+)\)", lambda v: float(v) if v != 0 else None), ("RTK \([-+]?\d+\.\d+, [-+]?\d+\.\d+, (-?\d+)\)", lambda v: float(v) if v != 0 else None), + ("abs_alt: ([\d\.\-]+)", lambda v: float(v) if v != 0 else None), ], line) \ No newline at end of file From f7c7044823cdeb130da9c27f9441919cab675811 Mon Sep 17 00:00:00 2001 From: kielnino Date: Thu, 1 Feb 2024 09:25:10 +0100 Subject: [PATCH 06/17] remove unused mvs_tmp_dir --- stages/mvstex.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/stages/mvstex.py b/stages/mvstex.py index a45c3b179..eff47183e 100644 --- a/stages/mvstex.py +++ b/stages/mvstex.py @@ -108,13 +108,6 @@ def add_run(nvm_file, primary=True, band=None): 'labelingFile': '-L "%s"' % r['labeling_file'] if r['labeling_file'] else '' } - mvs_tmp_dir = os.path.join(r['out_dir'], 'tmp') - - # Make sure tmp directory is empty - 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} ' From 10947ecddfc77d3b99d59eb5d6874105cd635987 Mon Sep 17 00:00:00 2001 From: kielnino Date: Thu, 1 Feb 2024 12:02:06 +0100 Subject: [PATCH 07/17] clarify usage of tmp directory --- stages/mvstex.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/stages/mvstex.py b/stages/mvstex.py index eff47183e..6b4b64b12 100644 --- a/stages/mvstex.py +++ b/stages/mvstex.py @@ -108,6 +108,13 @@ def add_run(nvm_file, primary=True, band=None): 'labelingFile': '-L "%s"' % r['labeling_file'] if r['labeling_file'] else '' } + mvs_tmp_dir = os.path.join(r['out_dir'], 'tmp') + + # mvstex creates a tmp directory, so make sure it is empty + 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} ' From b204a2eb98604ec6ceb7f53d17fa536a1bbca624 Mon Sep 17 00:00:00 2001 From: kielnino Date: Fri, 9 Feb 2024 15:06:02 +0100 Subject: [PATCH 08/17] set extensionsUsed in all cases --- opendm/gltf.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/opendm/gltf.py b/opendm/gltf.py index 673dc86b8..3521ddd14 100644 --- a/opendm/gltf.py +++ b/opendm/gltf.py @@ -279,9 +279,10 @@ def addBufferView(buf, target=None): ) gltf.extensionsRequired = ['KHR_materials_unlit'] + gltf.extensionsUsed = ['KHR_materials_unlit'] if rtc != (None, None) and len(rtc) >= 2: - gltf.extensionsUsed = ['CESIUM_RTC', 'KHR_materials_unlit'] + gltf.extensionsUsed.append('CESIUM_RTC') gltf.extensions = { 'CESIUM_RTC': { 'center': [float(rtc[0]), float(rtc[1]), 0.0] From cb3229a3d47aea36a9f1edf110c757fc8486ff15 Mon Sep 17 00:00:00 2001 From: Sylvain POULAIN Date: Mon, 12 Feb 2024 18:50:22 +0400 Subject: [PATCH 09/17] Add Mavic 3 rolling shutter, not enterprise version (#1747) * Add Mavic 3 rolling shutter * M3 --- opendm/rollingshutter.py | 1 + 1 file changed, 1 insertion(+) diff --git a/opendm/rollingshutter.py b/opendm/rollingshutter.py index 8b0fa577a..9447eeb4f 100644 --- a/opendm/rollingshutter.py +++ b/opendm/rollingshutter.py @@ -19,6 +19,7 @@ 'dji fc220': 64, # DJI Mavic Pro (Platinum) 'hasselblad l1d-20c': lambda p: 47 if p.get_capture_megapixels() < 17 else 56, # DJI Mavic 2 Pro (at 16:10 => 16.8MP 47ms, at 3:2 => 19.9MP 56ms. 4:3 has 17.7MP with same image height as 3:2 which can be concluded as same sensor readout) + 'hasselblad l2d-20c': 16.6, # DJI Mavic 3 (not enterprise version) 'dji fc3582': lambda p: 26 if p.get_capture_megapixels() < 48 else 60, # DJI Mini 3 pro (at 48MP readout is 60ms, at 12MP it's 26ms) From 2c6fd1dd9f122afbfc41d1c6fa97631f863a6520 Mon Sep 17 00:00:00 2001 From: Stephen Mather <1174901+smathermather@users.noreply.github.com> Date: Fri, 8 Mar 2024 22:13:54 -0500 Subject: [PATCH 10/17] increase default GPS-Accuracy to 3m --- opendm/config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opendm/config.py b/opendm/config.py index 3db8151f7..d8e3a1790 100755 --- a/opendm/config.py +++ b/opendm/config.py @@ -838,7 +838,7 @@ def config(argv=None, parser=None): type=float, action=StoreValue, metavar='', - default=10, + default=3, help='Set a value in meters for the GPS Dilution of Precision (DOP) ' 'information for all images. If your images are tagged ' 'with high precision GPS information (RTK), this value will be automatically ' From 5a439c0ab697b5168f8b36aa9bdeb9f2b9d188e2 Mon Sep 17 00:00:00 2001 From: Stephen Mather Date: Mon, 11 Mar 2024 22:56:48 -0400 Subject: [PATCH 11/17] replace fisheye with fisheye_opencv but keep API the same until 4.0 --- opendm/photo.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/opendm/photo.py b/opendm/photo.py index a7e638be4..0baaf2595 100644 --- a/opendm/photo.py +++ b/opendm/photo.py @@ -430,7 +430,8 @@ def parse_exif_values(self, _path_file): camera_projection = camera_projection.lower() # Parrot Sequoia's "fisheye" model maps to "fisheye_opencv" - if camera_projection == "fisheye" and self.camera_make.lower() == "parrot" and self.camera_model.lower() == "sequoia": + # or better yet, replace all fisheye with fisheye_opencv, but wait to change API signature + if camera_projection == "fisheye": camera_projection = "fisheye_opencv" if camera_projection in projections: From 77f8ffc8cdd06b60f0a09904181bbb43daafa787 Mon Sep 17 00:00:00 2001 From: Piero Toffanin Date: Tue, 2 Apr 2024 12:46:20 -0400 Subject: [PATCH 12/17] Fix BOM encoding bug with geo files --- opendm/geo.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/opendm/geo.py b/opendm/geo.py index 3e826f849..7baa8c913 100644 --- a/opendm/geo.py +++ b/opendm/geo.py @@ -12,6 +12,9 @@ def __init__(self, geo_path): with open(self.geo_path, 'r') as f: contents = f.read().strip() + + # Strip eventual BOM characters + contents = contents.replace('\ufeff', '') lines = list(map(str.strip, contents.split('\n'))) if lines: From 981bf88b48ac11e426ba9c4b59922b327f4537f1 Mon Sep 17 00:00:00 2001 From: Piero Toffanin Date: Wed, 10 Apr 2024 11:13:58 -0400 Subject: [PATCH 13/17] Use min views filter = 1 --- VERSION | 2 +- stages/openmvs.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/VERSION b/VERSION index 18091983f..47b322c97 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.4.0 +3.4.1 diff --git a/stages/openmvs.py b/stages/openmvs.py index f3b50644d..1936dc024 100644 --- a/stages/openmvs.py +++ b/stages/openmvs.py @@ -94,7 +94,7 @@ def process(self, args, outputs): extra_config.append("--ignore-mask-label 0") with open(densify_ini_file, 'w+') as f: - f.write("Optimize = 7\n") + f.write("Optimize = 7\nMin Views Filter = 1\n") def run_densify(): system.run('"%s" "%s" %s' % (context.omvs_densify_path, From a70e7445ad425cbe9eae7440e3c7631f6b9c4187 Mon Sep 17 00:00:00 2001 From: Piero Toffanin Date: Wed, 10 Apr 2024 12:26:34 -0400 Subject: [PATCH 14/17] Update default feature-type, pc-filter values --- opendm/config.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/opendm/config.py b/opendm/config.py index d8e3a1790..1eafee11e 100755 --- a/opendm/config.py +++ b/opendm/config.py @@ -217,7 +217,7 @@ def config(argv=None, parser=None): parser.add_argument('--feature-type', metavar='', action=StoreValue, - default='sift', + default='dspsift', choices=['akaze', 'dspsift', 'hahog', 'orb', 'sift'], help=('Choose the algorithm for extracting keypoints and computing descriptors. ' 'Can be one of: %(choices)s. Default: ' @@ -485,7 +485,7 @@ def config(argv=None, parser=None): metavar='', action=StoreValue, type=float, - default=2.5, + default=20, help='Filters the point cloud by removing points that deviate more than N standard deviations from the local mean. Set to 0 to disable filtering. ' 'Default: %(default)s') From 17dfc7599a277491b3d3e37d67e8d0e3bb7d3cbf Mon Sep 17 00:00:00 2001 From: Piero Toffanin Date: Wed, 10 Apr 2024 13:48:11 -0400 Subject: [PATCH 15/17] Update pc-filter value to 5 --- opendm/config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opendm/config.py b/opendm/config.py index 1eafee11e..b1d195e95 100755 --- a/opendm/config.py +++ b/opendm/config.py @@ -485,7 +485,7 @@ def config(argv=None, parser=None): metavar='', action=StoreValue, type=float, - default=20, + default=5, help='Filters the point cloud by removing points that deviate more than N standard deviations from the local mean. Set to 0 to disable filtering. ' 'Default: %(default)s') From 6c0fe6e79d422212be49f3c9f8994f4457066aa5 Mon Sep 17 00:00:00 2001 From: Piero Toffanin Date: Wed, 10 Apr 2024 22:07:36 -0400 Subject: [PATCH 16/17] Bump version --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 47b322c97..1545d9665 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.4.1 +3.5.0 From aef4182cf9e63e773ec0066e78a2cb51b69a67e9 Mon Sep 17 00:00:00 2001 From: Piero Toffanin Date: Thu, 11 Apr 2024 14:18:20 -0400 Subject: [PATCH 17/17] More solid OpenMVS clustering fallback --- stages/openmvs.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/stages/openmvs.py b/stages/openmvs.py index 1936dc024..b02c42f4c 100644 --- a/stages/openmvs.py +++ b/stages/openmvs.py @@ -110,7 +110,7 @@ def run_densify(): log.ODM_WARNING("OpenMVS failed with GPU, is your graphics card driver up to date? Falling back to CPU.") gpu_config = ["--cuda-device -2"] run_densify() - elif (e.errorCode == 137 or e.errorCode == 3221226505) and not pc_tile: + elif (e.errorCode == 137 or e.errorCode == 143 or e.errorCode == 3221226505) and not pc_tile: log.ODM_WARNING("OpenMVS ran out of memory, we're going to turn on tiling to see if we can process this.") pc_tile = True config.append("--fusion-mode 1") @@ -127,7 +127,7 @@ def run_densify(): subscene_densify_ini_file = os.path.join(tree.openmvs, 'subscene-config.ini') with open(subscene_densify_ini_file, 'w+') as f: - f.write("Optimize = 0\nEstimation Geometric Iters = 0\n") + f.write("Optimize = 0\nEstimation Geometric Iters = 0\nMin Views Filter = 1\n") config = [ "--sub-scene-area 660000", # 8000 @@ -223,7 +223,7 @@ def skip_filtering(): try: system.run('"%s" %s' % (context.omvs_densify_path, ' '.join(config + gpu_config + extra_config))) except system.SubprocessException as e: - if e.errorCode == 137 or e.errorCode == 3221226505: + if e.errorCode == 137 or e.errorCode == 143 or e.errorCode == 3221226505: log.ODM_WARNING("OpenMVS filtering ran out of memory, visibility checks will be skipped.") skip_filtering() else: