kopia lustrzana https://github.com/OpenDroneMap/ODM
Better support for AV Quantix drones
rodzic
de4bd062ec
commit
89ea21284a
|
@ -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))
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
Ładowanie…
Reference in New Issue