Source code for aws.osml.photogrammetry.composite_sensor_model

#  Copyright 2023-2024 Amazon.com, Inc. or its affiliates.

import math
from typing import Any, Dict, Optional

from .coordinates import GeodeticWorldCoordinate, ImageCoordinate
from .elevation_model import ElevationModel
from .sensor_model import SensorModel, SensorModelOptions


[docs] class CompositeSensorModel(SensorModel): """ A CompositeSensorModel is a SensorModel that combines an approximate but fast model with an accurate but slower model. """ def __init__(self, approximate_sensor_model: SensorModel, precision_sensor_model: SensorModel) -> None: """ Constructs the model given the two models to aggregate. :param approximate_sensor_model: a faster but less accurate model :param precision_sensor_model: a slower but more accurate model :return: None """ super().__init__() self.approximate_sensor_model = approximate_sensor_model self.precision_sensor_model = precision_sensor_model
[docs] def image_to_world( self, image_coordinate: ImageCoordinate, elevation_model: Optional[ElevationModel] = None, options: Optional[Dict[str, Any]] = None, ) -> GeodeticWorldCoordinate: """ This function first calls the approximate model's image_to_world function to get an initial guess and then passes that information to the more accurate model through the options parameter's 'initial_guess' and 'initial_search_distance' options. :param image_coordinate: the x, y image coordinate :param elevation_model: an optional elevation model used to transform the coordinate :param options: the options that will be augmented and then passed along :return: the longitude, latitude, elevation world coordinate """ approximate_coord = self.approximate_sensor_model.image_to_world( image_coordinate, elevation_model=elevation_model, options=options ) updated_options = options.copy() if options is not None else {} updated_options[SensorModelOptions.INITIAL_GUESS] = [ approximate_coord.longitude, approximate_coord.latitude, ] updated_options[SensorModelOptions.INITIAL_SEARCH_DISTANCE] = math.radians(0.005) return self.precision_sensor_model.image_to_world( image_coordinate, elevation_model=elevation_model, options=updated_options )
[docs] def world_to_image(self, world_coordinate: GeodeticWorldCoordinate) -> ImageCoordinate: """ This is just a pass through to the more accurate sensor model's world_to_image. These calculations tend to be quicker so there is no need to involve the approximate model. :param world_coordinate: the longitude, latitude, elevation world coordinate :return: the x, y image coordinate """ return self.precision_sensor_model.world_to_image(world_coordinate)