Better support for AV Quantix drones

pull/1590/head
Piero Toffanin 2023-01-28 17:38:13 -05:00
rodzic de4bd062ec
commit 89ea21284a
4 zmienionych plików z 52 dodań i 15 usunięć

Wyświetl plik

@ -421,6 +421,18 @@ def compute_homography(image_filename, align_image_filename):
def find_ecc_homography(image_gray, align_image_gray, number_of_iterations=1000, termination_eps=1e-8, start_eps=1e-4):
pyramid_levels = 0
h,w = image_gray.shape
max_dim = max(h, w)
max_size = 1280
if max_dim > max_size:
if max_dim == w:
f = max_size / w
else:
f = max_size / h
image_gray = cv2.resize(image_gray, None, fx=f, fy=f, interpolation=cv2.INTER_AREA)
h,w = image_gray.shape
min_dim = min(h, w)
while min_dim > 300:
@ -434,10 +446,10 @@ def find_ecc_homography(image_gray, align_image_gray, number_of_iterations=1000,
align_image_gray = to_8bit(align_image_gray)
image_gray = to_8bit(image_gray)
fx = align_image_gray.shape[1]/image_gray.shape[1]
fy = align_image_gray.shape[0]/image_gray.shape[0]
fx = image_gray.shape[1]/align_image_gray.shape[1]
fy = image_gray.shape[0]/align_image_gray.shape[0]
image_gray = cv2.resize(image_gray, None,
align_image_gray = cv2.resize(align_image_gray, None,
fx=fx,
fy=fy,
interpolation=(cv2.INTER_AREA if (fx < 1.0 and fy < 1.0) else cv2.INTER_LANCZOS4))

Wyświetl plik

@ -459,6 +459,21 @@ class ODM_Photo:
# self.set_attr_from_xmp_tag('bandwidth', xtags, [
# 'Camera:WavelengthFWHM'
# ], float)
# Special case band handling for AeroVironment Quantix images
# for some reason, they don't store band information in EXIFs
if self.camera_make.lower() == 'aerovironment' and \
self.camera_model.lower() == 'quantix':
matches = re.match("IMG_(\d+)_(\w+)\.\w+", self.filename, re.IGNORECASE)
if matches:
band_aliases = {
'GRN': 'Green',
'NIR': 'Nir',
'RED': 'Red',
'RGB': 'RedGreenBlue',
}
self.capture_uuid = matches.group(1)
self.band_name = band_aliases.get(matches.group(2), matches.group(2))
# Sanitize band name since we use it in folder paths
self.band_name = re.sub('[^A-Za-z0-9]+', '', self.band_name)

Wyświetl plik

@ -76,17 +76,27 @@ class ODM_Reconstruction(object):
bands = {}
for b in self.multi_camera:
bands[b['name'].lower()] = b['name']
bands_to_remove = []
if ('rgb' in bands or 'redgreenblue' in bands) and \
('red' in bands and 'green' in bands and 'blue' in bands):
band_to_remove = bands['rgb'] if 'rgb' in bands else bands['redgreenblue']
if 'rgb' in bands or 'redgreenblue' in bands:
if 'red' in bands and 'green' in bands and 'blue' in bands:
bands_to_remove.append(bands['rgb'] if 'rgb' in bands else bands['redgreenblue'])
else:
for b in ['red', 'green', 'blue']:
if b in bands:
bands_to_remove.append(bands[b])
self.multi_camera = [b for b in self.multi_camera if b['name'] != band_to_remove]
photos_before = len(self.photos)
self.photos = [p for p in self.photos if p.band_name != band_to_remove]
photos_after = len(self.photos)
if len(bands_to_remove) > 0:
log.ODM_WARNING("Redundant bands detected, probably because RGB images are mixed with single band images. We will trim some bands as needed")
log.ODM_WARNING("RGB images detected alongside individual Red/Green/Blue images, we will use individual bands (skipping %s images)" % (photos_before - photos_after))
for band_to_remove in bands_to_remove:
self.multi_camera = [b for b in self.multi_camera if b['name'] != band_to_remove]
photos_before = len(self.photos)
self.photos = [p for p in self.photos if p.band_name != band_to_remove]
photos_after = len(self.photos)
log.ODM_WARNING("Skipping %s band (%s images)" % (band_to_remove, photos_before - photos_after))
def is_georeferenced(self):
return self.georef is not None

Wyświetl plik

@ -104,9 +104,9 @@ class ODMOpenSfMStage(types.ODM_Stage):
image = func(shot_id, image)
return image
def resize_thermal_images(shot_id, image):
def resize_secondary_images(shot_id, image):
photo = reconstruction.get_photo(shot_id)
if photo.is_thermal():
if photo.band_name != primary_band_name:
return thermal.resize_to_match(image, largest_photo)
else:
return image
@ -138,8 +138,8 @@ class ODMOpenSfMStage(types.ODM_Stage):
return image
if reconstruction.multi_camera:
largest_photo = find_largest_photo(photos)
undistort_pipeline.append(resize_thermal_images)
largest_photo = find_largest_photo([p for p in photos if p.band_name == primary_band_name])
undistort_pipeline.append(resize_secondary_images)
if args.radiometric_calibration != "none":
undistort_pipeline.append(radiometric_calibrate)