From 0d3b169822ed6df62fa1e2658e86e2dc5785af32 Mon Sep 17 00:00:00 2001 From: Piero Toffanin Date: Tue, 8 Mar 2022 11:32:32 -0500 Subject: [PATCH] More resiliant GPU feature detection --- opendm/osfm.py | 14 +++++++++++++- opendm/system.py | 6 +++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/opendm/osfm.py b/opendm/osfm.py index 7657fca1..d0eaedc8 100644 --- a/opendm/osfm.py +++ b/opendm/osfm.py @@ -257,6 +257,7 @@ class OSFMContext: if has_popsift_and_can_handle_texsize(w, h) and feature_type == "SIFT": log.ODM_INFO("Using GPU for extracting SIFT features") feature_type = "SIFT_GPU" + self.gpu_sift_feature_extraction = True config.append("feature_type: %s" % feature_type) @@ -361,7 +362,18 @@ class OSFMContext: matches_dir = self.path("matches") if not io.dir_exists(features_dir) or rerun: - self.run('detect_features') + try: + self.run('detect_features') + except SubprocessException as e: + # Sometimes feature extraction by GPU can fail + # for various reasons, so before giving up + # we try to fallback to CPU + if hasattr(self, 'gpu_sift_feature_extraction'): + log.ODM_WARNING("GPU SIFT extraction failed, maybe your graphics card is too old, attempting fallback to CPU") + self.update_config({'feature_type': "SIFT"}) + self.run('detect_features') + else: + raise e else: log.ODM_WARNING('Detect features already done: %s exists' % features_dir) diff --git a/opendm/system.py b/opendm/system.py index bf5f279a..c795b221 100644 --- a/opendm/system.py +++ b/opendm/system.py @@ -7,6 +7,7 @@ import subprocess import string import signal import io +import ctypes from collections import deque from opendm import context @@ -73,8 +74,11 @@ def run(cmd, env_paths=[context.superbuild_bin_path], env_vars={}, packages_path env = os.environ.copy() sep = ":" + flags = 0 if sys.platform == 'win32': sep = ";" + ctypes.windll.kernel32.SetErrorMode(0x0002) #SEM_NOGPFAULTERRORBOX + flags = 0x8000000 #CREATE_NO_WINDOW if len(env_paths) > 0: env["PATH"] = env["PATH"] + sep + sep.join(env_paths) @@ -85,7 +89,7 @@ def run(cmd, env_paths=[context.superbuild_bin_path], env_vars={}, packages_path for k in env_vars: env[k] = str(env_vars[k]) - p = subprocess.Popen(cmd, shell=True, env=env, start_new_session=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + p = subprocess.Popen(cmd, shell=True, env=env, start_new_session=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, creationflags=flags) running_subprocesses.append(p) lines = deque() for line in io.TextIOWrapper(p.stdout):