Fix homography calculations

pull/1740/head
Piero Toffanin 2024-06-28 17:12:53 +00:00
rodzic 75c363994c
commit 5c68df75b3
3 zmienionych plików z 33 dodań i 25 usunięć

Wyświetl plik

@ -1 +1 @@
3.5.2 3.5.3

Wyświetl plik

@ -427,14 +427,14 @@ def find_ecc_homography(image_gray, align_image_gray, number_of_iterations=1000,
pyramid_levels = 0 pyramid_levels = 0
h,w = image_gray.shape h,w = image_gray.shape
max_dim = max(h, w) max_dim = max(h, w)
downscale = 0
max_size = 1280 max_size = 2048
while max_dim / (2**downscale) > max_size:
downscale += 1
if max_dim > max_size: if downscale > 0:
if max_dim == w: f = 1 / (2**downscale)
f = max_size / w
else:
f = max_size / h
image_gray = cv2.resize(image_gray, None, fx=f, fy=f, interpolation=cv2.INTER_AREA) image_gray = cv2.resize(image_gray, None, fx=f, fy=f, interpolation=cv2.INTER_AREA)
h,w = image_gray.shape h,w = image_gray.shape
@ -445,6 +445,7 @@ def find_ecc_homography(image_gray, align_image_gray, number_of_iterations=1000,
pyramid_levels += 1 pyramid_levels += 1
log.ODM_INFO("Pyramid levels: %s" % pyramid_levels) log.ODM_INFO("Pyramid levels: %s" % pyramid_levels)
log.ODM_INFO("Downscale: %s" % downscale)
# Quick check on size # Quick check on size
if align_image_gray.shape[0] != image_gray.shape[0]: if align_image_gray.shape[0] != image_gray.shape[0]:
@ -473,7 +474,6 @@ def find_ecc_homography(image_gray, align_image_gray, number_of_iterations=1000,
# Define the motion model, scale the initial warp matrix to smallest level # Define the motion model, scale the initial warp matrix to smallest level
warp_matrix = np.eye(3, 3, dtype=np.float32) warp_matrix = np.eye(3, 3, dtype=np.float32)
warp_matrix = warp_matrix * np.array([[1,1,2],[1,1,2],[0.5,0.5,1]], dtype=np.float32)**(1-(pyramid_levels+1))
for level in range(pyramid_levels+1): for level in range(pyramid_levels+1):
ig = gradient(gaussian(image_gray_pyr[level])) ig = gradient(gaussian(image_gray_pyr[level]))
@ -495,13 +495,15 @@ def find_ecc_homography(image_gray, align_image_gray, number_of_iterations=1000,
if level != pyramid_levels: if level != pyramid_levels:
log.ODM_INFO("Could not compute ECC warp_matrix at pyramid level %s, resetting matrix" % level) log.ODM_INFO("Could not compute ECC warp_matrix at pyramid level %s, resetting matrix" % level)
warp_matrix = np.eye(3, 3, dtype=np.float32) warp_matrix = np.eye(3, 3, dtype=np.float32)
warp_matrix = warp_matrix * np.array([[1,1,2],[1,1,2],[0.5,0.5,1]], dtype=np.float32)**(1-(pyramid_levels+1))
else: else:
raise e raise e
if level != pyramid_levels: if level != pyramid_levels:
warp_matrix = warp_matrix * np.array([[1,1,2],[1,1,2],[0.5,0.5,1]], dtype=np.float32) warp_matrix = warp_matrix * np.array([[1,1,2],[1,1,2],[0.5,0.5,1]], dtype=np.float32)
if downscale > 0:
return warp_matrix * (np.array([[1,1,2],[1,1,2],[0.5,0.5,1]], dtype=np.float32) ** downscale)
else:
return warp_matrix return warp_matrix
@ -512,13 +514,15 @@ def find_features_homography(image_gray, align_image_gray, feature_retention=0.7
h,w = image_gray.shape h,w = image_gray.shape
max_dim = max(h, w) max_dim = max(h, w)
downscale = 0
max_size = 2048 max_size = 4096
if max_dim > max_size: while max_dim / (2**downscale) > max_size:
if max_dim == w: downscale += 1
f = max_size / w log.ODM_INFO("Downscale: %s" % downscale)
else:
f = max_size / h if downscale > 0:
f = 1 / (2**downscale)
image_gray = cv2.resize(image_gray, None, fx=f, fy=f, interpolation=cv2.INTER_AREA) image_gray = cv2.resize(image_gray, None, fx=f, fy=f, interpolation=cv2.INTER_AREA)
h,w = image_gray.shape h,w = image_gray.shape
@ -570,6 +574,10 @@ def find_features_homography(image_gray, align_image_gray, feature_retention=0.7
# Find homography # Find homography
h, _ = cv2.findHomography(points_image, points_align_image, cv2.RANSAC) h, _ = cv2.findHomography(points_image, points_align_image, cv2.RANSAC)
if downscale > 0:
return h * (np.array([[1,1,2],[1,1,2],[0.5,0.5,1]], dtype=np.float32) ** downscale)
else:
return h return h
def gradient(im, ksize=5): def gradient(im, ksize=5):

Wyświetl plik

@ -29,14 +29,14 @@ class ODMOpenSfMStage(types.ODM_Stage):
raise system.ExitException('Not enough photos in photos array to start OpenSfM') raise system.ExitException('Not enough photos in photos array to start OpenSfM')
octx = OSFMContext(tree.opensfm) octx = OSFMContext(tree.opensfm)
octx.setup(args, tree.dataset_raw, reconstruction=reconstruction, rerun=self.rerun()) # octx.setup(args, tree.dataset_raw, reconstruction=reconstruction, rerun=self.rerun())
octx.photos_to_metadata(photos, args.rolling_shutter, args.rolling_shutter_readout, self.rerun()) # octx.photos_to_metadata(photos, args.rolling_shutter, args.rolling_shutter_readout, self.rerun())
self.update_progress(20) # self.update_progress(20)
octx.feature_matching(self.rerun()) # octx.feature_matching(self.rerun())
self.update_progress(30) # self.update_progress(30)
octx.create_tracks(self.rerun()) # octx.create_tracks(self.rerun())
octx.reconstruct(args.rolling_shutter, reconstruction.is_georeferenced() and (not args.sfm_no_partial), self.rerun()) # octx.reconstruct(args.rolling_shutter, reconstruction.is_georeferenced() and (not args.sfm_no_partial), self.rerun())
octx.extract_cameras(tree.path("cameras.json"), self.rerun()) # octx.extract_cameras(tree.path("cameras.json"), self.rerun())
self.update_progress(70) self.update_progress(70)
def cleanup_disk_space(): def cleanup_disk_space():