Source code for cars.pipelines.parameters.depth_map_inputs

#!/usr/bin/env python
# coding: utf8
#
# Copyright (c) 2020 Centre National d'Etudes Spatiales (CNES).
#
# This file is part of CARS
# (see https://github.com/CNES/cars).
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
"""
CARS depth map inputs
"""

import logging

from json_checker import Checker, Or

import cars.pipelines.parameters.depth_map_inputs_constants as depth_map_cst

# CARS imports
from cars.core import constants as cst
from cars.core import inputs
from cars.core.geometry.abstract_geometry import AbstractGeometry
from cars.core.utils import make_relative_path_absolute
from cars.pipelines.parameters import sensor_inputs as sens_inp
from cars.pipelines.parameters import sensor_inputs_constants as sens_cst


[docs]def check_depth_maps_inputs(conf, config_json_dir=None): """ Check the inputs given :param conf: configuration of inputs :type conf: dict :param config_json_dir: directory of used json, if user filled paths with relative paths :type config_json_dir: str :return: overloader inputs :rtype: dict """ overloaded_conf = {} # Overload some optional parameters overloaded_conf[sens_cst.ROI] = conf.get(sens_cst.ROI, None) overloaded_conf[depth_map_cst.DEPTH_MAPS] = {} overloaded_conf[sens_cst.INITIAL_ELEVATION] = ( sens_inp.get_initial_elevation( conf.get(sens_cst.INITIAL_ELEVATION, None) ) ) overloaded_conf[sens_cst.SENSORS] = conf.get(sens_cst.SENSORS, None) overloaded_conf[sens_cst.PAIRING] = conf.get(sens_cst.PAIRING, None) # Validate inputs inputs_schema = { depth_map_cst.DEPTH_MAPS: dict, sens_cst.ROI: Or(str, dict, None), sens_cst.INITIAL_ELEVATION: Or(dict, None), sens_cst.SENSORS: Or(dict, None), sens_cst.PAIRING: Or([[str]], None), } checker_inputs = Checker(inputs_schema) checker_inputs.validate(overloaded_conf) # Validate depth maps pc_schema = { cst.X: str, cst.Y: str, cst.Z: str, cst.EPI_Z_INF: Or(str, None), cst.EPI_Z_SUP: Or(str, None), cst.POINT_CLOUD_CLASSIF_KEY_ROOT: Or(str, None), cst.POINT_CLOUD_CONFIDENCE_KEY_ROOT: Or(dict, None), cst.POINT_CLOUD_CLR_KEY_ROOT: str, cst.POINT_CLOUD_FILLING_KEY_ROOT: Or(str, None), cst.POINT_CLOUD_MSK: Or(str, None), cst.POINT_CLOUD_PERFORMANCE_MAP_ROOT: Or(str, None), cst.PC_EPSG: Or(str, int, None), } checker_pc = Checker(pc_schema) confidence_conf_ref = None for depth_map_key in conf[depth_map_cst.DEPTH_MAPS]: # Get depth maps with default overloaded_conf[depth_map_cst.DEPTH_MAPS][depth_map_key] = {} overloaded_conf[depth_map_cst.DEPTH_MAPS][depth_map_key][cst.X] = conf[ depth_map_cst.DEPTH_MAPS ][depth_map_key].get("x", None) overloaded_conf[depth_map_cst.DEPTH_MAPS][depth_map_key][cst.Y] = conf[ depth_map_cst.DEPTH_MAPS ][depth_map_key].get("y", None) overloaded_conf[depth_map_cst.DEPTH_MAPS][depth_map_key][cst.Z] = conf[ depth_map_cst.DEPTH_MAPS ][depth_map_key].get("z", None) overloaded_conf[depth_map_cst.DEPTH_MAPS][depth_map_key][ cst.EPI_Z_INF ] = conf[depth_map_cst.DEPTH_MAPS][depth_map_key].get( cst.EPI_Z_INF, None ) overloaded_conf[depth_map_cst.DEPTH_MAPS][depth_map_key][ cst.EPI_Z_SUP ] = conf[depth_map_cst.DEPTH_MAPS][depth_map_key].get( cst.EPI_Z_SUP, None ) overloaded_conf[depth_map_cst.DEPTH_MAPS][depth_map_key][ cst.POINT_CLOUD_CLR_KEY_ROOT ] = conf[depth_map_cst.DEPTH_MAPS][depth_map_key].get("color", None) overloaded_conf[depth_map_cst.DEPTH_MAPS][depth_map_key][ cst.POINT_CLOUD_MSK ] = conf[depth_map_cst.DEPTH_MAPS][depth_map_key].get("mask", None) overloaded_conf[depth_map_cst.DEPTH_MAPS][depth_map_key][ cst.POINT_CLOUD_CLASSIF_KEY_ROOT ] = conf[depth_map_cst.DEPTH_MAPS][depth_map_key].get( "classification", None ) overloaded_conf[depth_map_cst.DEPTH_MAPS][depth_map_key][ cst.POINT_CLOUD_PERFORMANCE_MAP_ROOT ] = conf[depth_map_cst.DEPTH_MAPS][depth_map_key].get( "performance_map", None ) overloaded_conf[depth_map_cst.DEPTH_MAPS][depth_map_key][ cst.POINT_CLOUD_FILLING_KEY_ROOT ] = conf[depth_map_cst.DEPTH_MAPS][depth_map_key].get("filling", None) confidence_conf = conf[depth_map_cst.DEPTH_MAPS][depth_map_key].get( "confidence", None ) if confidence_conf: overloaded_conf[depth_map_cst.DEPTH_MAPS][depth_map_key][ cst.POINT_CLOUD_CONFIDENCE_KEY_ROOT ] = {} if ( confidence_conf_ref and confidence_conf.keys() != confidence_conf_ref ): raise KeyError( "The confidence keys are not the same: \n", confidence_conf.keys(), "\n", confidence_conf_ref, ) confidence_conf_ref = confidence_conf.keys() for confidence_name in confidence_conf: output_confidence_name = confidence_name if ( cst.POINT_CLOUD_CONFIDENCE_KEY_ROOT not in output_confidence_name ): output_confidence_name = ( cst.POINT_CLOUD_CONFIDENCE_KEY_ROOT + "_" + output_confidence_name ) overloaded_conf[depth_map_cst.DEPTH_MAPS][depth_map_key][ cst.POINT_CLOUD_CONFIDENCE_KEY_ROOT ][output_confidence_name] = confidence_conf[confidence_name] else: overloaded_conf[depth_map_cst.DEPTH_MAPS][depth_map_key][ cst.POINT_CLOUD_CONFIDENCE_KEY_ROOT ] = None overloaded_conf[depth_map_cst.DEPTH_MAPS][depth_map_key][ cst.PC_EPSG ] = conf[depth_map_cst.DEPTH_MAPS][depth_map_key].get("epsg", 4326) # validate checker_pc.validate( overloaded_conf[depth_map_cst.DEPTH_MAPS][depth_map_key] ) # Modify to absolute path if config_json_dir is not None: modify_to_absolute_path(config_json_dir, overloaded_conf) else: logging.debug( "path of config file was not given," "relative path are not transformed to absolute paths" ) for depth_map_key in conf[depth_map_cst.DEPTH_MAPS]: # check sizes check_input_size( overloaded_conf[depth_map_cst.DEPTH_MAPS][depth_map_key][cst.X], overloaded_conf[depth_map_cst.DEPTH_MAPS][depth_map_key][cst.Y], overloaded_conf[depth_map_cst.DEPTH_MAPS][depth_map_key][cst.Z], overloaded_conf[depth_map_cst.DEPTH_MAPS][depth_map_key][ cst.POINT_CLOUD_MSK ], overloaded_conf[depth_map_cst.DEPTH_MAPS][depth_map_key][ cst.POINT_CLOUD_CLR_KEY_ROOT ], overloaded_conf[depth_map_cst.DEPTH_MAPS][depth_map_key][ cst.POINT_CLOUD_CLASSIF_KEY_ROOT ], overloaded_conf[depth_map_cst.DEPTH_MAPS][depth_map_key][ cst.POINT_CLOUD_FILLING_KEY_ROOT ], overloaded_conf[depth_map_cst.DEPTH_MAPS][depth_map_key][ cst.POINT_CLOUD_CONFIDENCE_KEY_ROOT ], ) # Check srtm dir sens_inp.check_srtm( overloaded_conf[sens_cst.INITIAL_ELEVATION][sens_cst.DEM_PATH] ) if sens_cst.SENSORS in conf and conf[sens_cst.SENSORS] is not None: sens_inp.check_sensors(conf, overloaded_conf, config_json_dir) return overloaded_conf
[docs]def check_geometry_plugin(conf_inputs, conf_geom_plugin): """ Check the geometry plugin with inputs :param conf_geom_plugin: name of geometry plugin :type conf_geom_plugin: str :param conf_inputs: checked configuration of inputs :type conf_inputs: type :return: geometry plugin with dem """ if conf_geom_plugin is None: conf_geom_plugin = "SharelocGeometry" dem_path = conf_inputs[sens_cst.INITIAL_ELEVATION][sens_cst.DEM_PATH] if dem_path is None: return conf_geom_plugin, None # Initialize a geometry plugin with elevation information geom_plugin_with_dem_and_geoid = ( AbstractGeometry( # pylint: disable=abstract-class-instantiated conf_geom_plugin, dem=dem_path, geoid=conf_inputs[sens_cst.INITIAL_ELEVATION][sens_cst.GEOID], default_alt=sens_cst.CARS_DEFAULT_ALT, ) ) return conf_geom_plugin, geom_plugin_with_dem_and_geoid
[docs]def check_input_size( x_path, y_path, z_path, mask, color, classif, filling, confidence ): """ Check x, y, z, mask, color, classif and confidence given Images must have same size :param x_path: x path :type x_path: str :param y_path: y path :type y_path: str :param z_path: z path :type z_path: str :param mask: mask path :type mask: str :param color: color path :type color: str :param classif: classif path :type classif: str :param filling: filling path :type filling: str :param confidence: confidence dict path :type confidence: dict[str] """ for path in [x_path, y_path, z_path]: if inputs.rasterio_get_nb_bands(path) != 1: raise RuntimeError("{} is not mono-band image".format(path)) for path in [mask, color, classif, filling]: if path is not None: if inputs.rasterio_get_size(x_path) != inputs.rasterio_get_size( path ): raise RuntimeError( "The image {} and {} " "do not have the same size".format(x_path, path) ) if confidence: for key in confidence: path = confidence[key] if path is not None: if inputs.rasterio_get_size(x_path) != inputs.rasterio_get_size( path ): raise RuntimeError( "The image {} and {} " "do not have the same size".format(x_path, path) )
[docs]def modify_to_absolute_path(config_json_dir, overloaded_conf): """ Modify input file path to absolute path :param config_json_dir: directory of the json configuration :type config_json_dir: str :param overloaded_conf: overloaded configuration json :dict overloaded_conf: dict """ for depth_map_key in overloaded_conf[depth_map_cst.DEPTH_MAPS]: depth_map = overloaded_conf[depth_map_cst.DEPTH_MAPS][depth_map_key] for tag in [ cst.X, cst.Y, cst.Z, cst.POINT_CLOUD_CLR_KEY_ROOT, cst.POINT_CLOUD_MSK, cst.POINT_CLOUD_CLASSIF_KEY_ROOT, cst.POINT_CLOUD_FILLING_KEY_ROOT, cst.POINT_CLOUD_CONFIDENCE_KEY_ROOT, ]: if tag != cst.POINT_CLOUD_CONFIDENCE_KEY_ROOT: if depth_map[tag] is not None: depth_map[tag] = make_relative_path_absolute( depth_map[tag], config_json_dir ) else: if depth_map[tag] is not None: for confidence_name in depth_map[tag]: if depth_map[tag][confidence_name] is not None: depth_map[tag][confidence_name] = ( make_relative_path_absolute( depth_map[tag][confidence_name], config_json_dir, ) ) if overloaded_conf[sens_cst.ROI] is not None: if isinstance(overloaded_conf[sens_cst.ROI], str): overloaded_conf[sens_cst.ROI] = make_relative_path_absolute( overloaded_conf[sens_cst.ROI], config_json_dir )