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