Skip to content

Commit

Permalink
Revert M3M RGB dewarp
Browse files Browse the repository at this point in the history
  • Loading branch information
pierotofy committed Jun 28, 2024
1 parent 7b33e33 commit b48a1e8
Show file tree
Hide file tree
Showing 4 changed files with 10 additions and 105 deletions.
68 changes: 0 additions & 68 deletions opendm/multispectral.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@
import numpy as np
from opendm import log
from opendm.concurrency import parallel_map
from opendm.io import related_file_path
from opensfm.io import imread, imwrite

from skimage import exposure
from skimage.morphology import disk
Expand Down Expand Up @@ -647,69 +645,3 @@ def resize_match(image, dimension):
interpolation=(cv2.INTER_AREA if (fx < 1.0 and fy < 1.0) else cv2.INTER_LANCZOS4))

return image

def dewarp_photos(photos, images_path, scale_factor=1.0, size=None, max_concurrency=1):
# Caution! This will make changes to the photo objects' filename

def dewarp_photo(p):
# This should never happen
if os.path.splitext(p.filename)[0].endswith("_dewarped"):
log.ODM_WARNING("Cannot dewarp %s, already dewarped?" % (p.filename))
return

if p.dewarp_data is None:
log.ODM_WARNING("Cannot dewarp %s, dewarp data is missing" % p.filename)
return

if p.dewarp_data.count(";") != 1:
log.ODM_WARNING("Cannot dewarp %s, cannot parse dewarp data" % p.filename)
return

datestamp, params = p.dewarp_data.split(";")
try:
params = [float(p) for p in params.split(",")]
except ValueError as e:
log.ODM_WARNING("Cannot dewarp %s, failed to parse dewarp data" % p.filename)
return

if len(params) != 9:
log.ODM_WARNING("Cannot dewarp %s, invalid dewarp data parameters (expected 9, got: %s)" % (p.filename, len(params)))
return

dewarped_filename = related_file_path(p.filename, postfix="_dewarped")
dewarped_path = os.path.join(images_path, dewarped_filename)
if os.path.isfile(dewarped_path):
# Already dewarped
p.filename = dewarped_filename
else:
image = imread(os.path.join(images_path, p.filename), unchanged=True, anydepth=True)
w, h = image.shape[1], image.shape[0]
fx, fy, cx, cy, k1, k2, p1, p2, k3 = params
cam_m = np.array([[fx, 0, w / 2 - cx], [0, fy, h / 2 + cy], [0, 0, 1]])
dist_c = np.array([k1, k2, p1, p2, k3])
map1, map2 = cv2.initUndistortRectifyMap(cam_m, dist_c, None, cam_m, (w, h), cv2.CV_32FC1)
dewarped_image = cv2.remap(image, map1, map2, cv2.INTER_LINEAR)

if scale_factor > 1.0:
new_w = int(w * (1.0 / scale_factor))
new_h = int(h * (1.0 / scale_factor))
center_x, center_y = w // 2, h // 2
crop_x1 = max(0, center_x - new_w // 2)
crop_y1 = max(0, center_y - new_h // 2)
crop_x2 = min(w, center_x + new_w // 2)
crop_y2 = min(h, center_y + new_h // 2)
cropped = dewarped_image[crop_y1:crop_y2, crop_x1:crop_x2]
dewarp_size = (w, h)
if size is not None:
dewarp_size = size
dewarped_image = cv2.resize(cropped, dewarp_size, interpolation=cv2.INTER_LANCZOS4)
imwrite(dewarped_path, dewarped_image)
log.ODM_INFO("Dewarped %s --> %s" % (p.filename, dewarped_filename))
p.filename = dewarped_filename

# Disable vignetting correction
p.vignetting_polynomial = None
p.vignetting_center = None


parallel_map(dewarp_photo, photos, max_concurrency)
9 changes: 0 additions & 9 deletions opendm/photo.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,9 +159,6 @@ def __init__(self, path_file):
self.gps_xy_stddev = None # Dilution of Precision X/Y
self.gps_z_stddev = None # Dilution of Precision Z

# DJI
self.dewarp_data = None

# Misc SFM
self.camera_projection = 'brown'
self.focal_ratio = 0.85
Expand Down Expand Up @@ -417,12 +414,6 @@ def parse_exif_values(self, _path_file):
'@drone-dji:FlightZSpeed',
], float)

# DJI dewarp data
if '@drone-dji:DewarpData' in xtags:
self.set_attr_from_xmp_tag('dewarp_data', xtags, [
'@drone-dji:DewarpData'
])

# Account for over-estimation
if self.gps_xy_stddev is not None:
self.gps_xy_stddev *= 2.0
Expand Down
30 changes: 8 additions & 22 deletions opendm/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,12 @@
warnings.filterwarnings("ignore")

class ODM_Reconstruction(object):
def __init__(self, photos, images_path, max_concurrency=1):
def __init__(self, photos):
self.photos = photos
self.georef = None
self.gcp = None
self.multi_camera = self.detect_multi_camera()
self.filter_photos()
self.dewarp_photos(images_path, max_concurrency)

def detect_multi_camera(self):
"""
Expand Down Expand Up @@ -149,7 +148,13 @@ def filter_photos(self):

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'])
bands_to_remove.append(bands['rgb'] if 'rgb' in bands else bands['redgreenblue'])

# Mavic 3M's RGB camera lens are too different than the multispectral ones
# so we drop the RGB channel instead
elif self.photos[0].is_make_model("DJI", "M3M") and 'red' in bands and 'green' 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:
Expand Down Expand Up @@ -280,25 +285,6 @@ def get_photo(self, filename):
if p.filename == filename:
return p

def dewarp_photos(self, images_path, max_concurrency):
if not self.multi_camera:
return # Nothing to do
else:
bands = {}
for b in self.multi_camera:
bands[b['name'].lower()] = b['photos']

# Mavic 3M's RGB camera lens are too different than the multispectral ones
# so we unwarp them before reconstruction when needed
if self.photos[0].is_make_model("DJI", "M3M") and 'nir' in bands and ('rgb' in bands or 'redgreenblue' in bands):
log.ODM_INFO("Dewarping RGB photos before processing")
rgb = 'rgb' if 'rgb' in bands else 'redgreenblue'
upscale = max(1.0, bands['nir'][0].focal_ratio / bands[rgb][0].focal_ratio)
if upscale != 1.0:
log.ODM_INFO("Adjusting focal distance of RGB images by %s" % upscale)
size = (bands['nir'][0].width, bands['nir'][0].height)
multispectral.dewarp_photos(bands['rgb'] if 'rgb' in bands else bands['redgreenblue'], images_path, upscale, size, max_concurrency)

class ODM_GeoRef(object):
@staticmethod
def FromCoordsFile(coords_file):
Expand Down
8 changes: 2 additions & 6 deletions stages/dataset.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ def process(self, args, outputs):

def valid_filename(filename, supported_extensions):
(pathfn, ext) = os.path.splitext(filename)
return ext.lower() in supported_extensions and pathfn[-5:] != "_mask" and pathfn[-9:] != "_dewarped"
return ext.lower() in supported_extensions and pathfn[-5:] != "_mask"

# Get supported images from dir
def get_images(in_dir):
Expand Down Expand Up @@ -163,10 +163,6 @@ def find_mask(photo_path, masks):
if p[-5:] == "_mask" and ext.lower() in context.supported_extensions:
masks[p] = r

# Remove dewarped images on re-run
if p[-9:] == "_dewarped" and self.rerun():
os.unlink(os.path.join(images_dir, p + ext))

photos = []
with open(tree.dataset_list, 'w') as dataset_list:
log.ODM_INFO("Loading %s images" % len(path_files))
Expand Down Expand Up @@ -302,7 +298,7 @@ def parallel_bg_filter(item):
log.logger.log_json_images(len(photos))

# Create reconstruction object
reconstruction = types.ODM_Reconstruction(photos, tree.dataset_raw, args.max_concurrency)
reconstruction = types.ODM_Reconstruction(photos)

if tree.odm_georeferencing_gcp and not args.use_exif:
reconstruction.georeference_with_gcp(tree.odm_georeferencing_gcp,
Expand Down

0 comments on commit b48a1e8

Please sign in to comment.