cars 1.0.0rc1__cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of cars might be problematic. Click here for more details.
- cars/__init__.py +74 -0
- cars/applications/__init__.py +37 -0
- cars/applications/application.py +117 -0
- cars/applications/application_constants.py +29 -0
- cars/applications/application_template.py +146 -0
- cars/applications/auxiliary_filling/__init__.py +29 -0
- cars/applications/auxiliary_filling/abstract_auxiliary_filling_app.py +104 -0
- cars/applications/auxiliary_filling/auxiliary_filling_algo.py +475 -0
- cars/applications/auxiliary_filling/auxiliary_filling_from_sensors_app.py +630 -0
- cars/applications/auxiliary_filling/auxiliary_filling_wrappers.py +90 -0
- cars/applications/dem_generation/__init__.py +30 -0
- cars/applications/dem_generation/abstract_dem_generation_app.py +116 -0
- cars/applications/dem_generation/bulldozer_config/base_config.yaml +42 -0
- cars/applications/dem_generation/bulldozer_dem_app.py +655 -0
- cars/applications/dem_generation/bulldozer_memory.py +55 -0
- cars/applications/dem_generation/dem_generation_algo.py +107 -0
- cars/applications/dem_generation/dem_generation_constants.py +32 -0
- cars/applications/dem_generation/dem_generation_wrappers.py +323 -0
- cars/applications/dense_match_filling/__init__.py +30 -0
- cars/applications/dense_match_filling/abstract_dense_match_filling_app.py +242 -0
- cars/applications/dense_match_filling/fill_disp_algo.py +113 -0
- cars/applications/dense_match_filling/fill_disp_constants.py +39 -0
- cars/applications/dense_match_filling/fill_disp_wrappers.py +83 -0
- cars/applications/dense_match_filling/zero_padding_app.py +302 -0
- cars/applications/dense_matching/__init__.py +30 -0
- cars/applications/dense_matching/abstract_dense_matching_app.py +261 -0
- cars/applications/dense_matching/census_mccnn_sgm_app.py +1460 -0
- cars/applications/dense_matching/cpp/__init__.py +0 -0
- cars/applications/dense_matching/cpp/dense_matching_cpp.cpython-312-i386-linux-gnu.so +0 -0
- cars/applications/dense_matching/cpp/dense_matching_cpp.py +94 -0
- cars/applications/dense_matching/cpp/includes/dense_matching.hpp +58 -0
- cars/applications/dense_matching/cpp/meson.build +9 -0
- cars/applications/dense_matching/cpp/src/bindings.cpp +13 -0
- cars/applications/dense_matching/cpp/src/dense_matching.cpp +207 -0
- cars/applications/dense_matching/dense_matching_algo.py +401 -0
- cars/applications/dense_matching/dense_matching_constants.py +89 -0
- cars/applications/dense_matching/dense_matching_wrappers.py +951 -0
- cars/applications/dense_matching/disparity_grid_algo.py +588 -0
- cars/applications/dense_matching/loaders/__init__.py +23 -0
- cars/applications/dense_matching/loaders/config_census_sgm_default.json +31 -0
- cars/applications/dense_matching/loaders/config_census_sgm_homogeneous.json +30 -0
- cars/applications/dense_matching/loaders/config_census_sgm_mountain_and_vegetation.json +30 -0
- cars/applications/dense_matching/loaders/config_census_sgm_shadow.json +30 -0
- cars/applications/dense_matching/loaders/config_census_sgm_sparse.json +36 -0
- cars/applications/dense_matching/loaders/config_census_sgm_urban.json +30 -0
- cars/applications/dense_matching/loaders/config_mapping.json +13 -0
- cars/applications/dense_matching/loaders/config_mccnn.json +28 -0
- cars/applications/dense_matching/loaders/global_land_cover_map.tif +0 -0
- cars/applications/dense_matching/loaders/pandora_loader.py +593 -0
- cars/applications/dsm_filling/__init__.py +32 -0
- cars/applications/dsm_filling/abstract_dsm_filling_app.py +101 -0
- cars/applications/dsm_filling/border_interpolation_app.py +270 -0
- cars/applications/dsm_filling/bulldozer_config/base_config.yaml +44 -0
- cars/applications/dsm_filling/bulldozer_filling_app.py +279 -0
- cars/applications/dsm_filling/exogenous_filling_app.py +333 -0
- cars/applications/grid_generation/__init__.py +30 -0
- cars/applications/grid_generation/abstract_grid_generation_app.py +142 -0
- cars/applications/grid_generation/epipolar_grid_generation_app.py +327 -0
- cars/applications/grid_generation/grid_correction_app.py +496 -0
- cars/applications/grid_generation/grid_generation_algo.py +388 -0
- cars/applications/grid_generation/grid_generation_constants.py +46 -0
- cars/applications/grid_generation/transform_grid.py +88 -0
- cars/applications/ground_truth_reprojection/__init__.py +30 -0
- cars/applications/ground_truth_reprojection/abstract_ground_truth_reprojection_app.py +137 -0
- cars/applications/ground_truth_reprojection/direct_localization_app.py +629 -0
- cars/applications/ground_truth_reprojection/ground_truth_reprojection_algo.py +275 -0
- cars/applications/point_cloud_outlier_removal/__init__.py +30 -0
- cars/applications/point_cloud_outlier_removal/abstract_outlier_removal_app.py +385 -0
- cars/applications/point_cloud_outlier_removal/outlier_removal_algo.py +392 -0
- cars/applications/point_cloud_outlier_removal/outlier_removal_constants.py +43 -0
- cars/applications/point_cloud_outlier_removal/small_components_app.py +527 -0
- cars/applications/point_cloud_outlier_removal/statistical_app.py +531 -0
- cars/applications/rasterization/__init__.py +30 -0
- cars/applications/rasterization/abstract_pc_rasterization_app.py +183 -0
- cars/applications/rasterization/rasterization_algo.py +534 -0
- cars/applications/rasterization/rasterization_constants.py +38 -0
- cars/applications/rasterization/rasterization_wrappers.py +634 -0
- cars/applications/rasterization/simple_gaussian_app.py +1152 -0
- cars/applications/resampling/__init__.py +28 -0
- cars/applications/resampling/abstract_resampling_app.py +187 -0
- cars/applications/resampling/bicubic_resampling_app.py +762 -0
- cars/applications/resampling/resampling_algo.py +614 -0
- cars/applications/resampling/resampling_constants.py +36 -0
- cars/applications/resampling/resampling_wrappers.py +309 -0
- cars/applications/sparse_matching/__init__.py +30 -0
- cars/applications/sparse_matching/abstract_sparse_matching_app.py +498 -0
- cars/applications/sparse_matching/sift_app.py +735 -0
- cars/applications/sparse_matching/sparse_matching_algo.py +360 -0
- cars/applications/sparse_matching/sparse_matching_constants.py +68 -0
- cars/applications/sparse_matching/sparse_matching_wrappers.py +238 -0
- cars/applications/triangulation/__init__.py +32 -0
- cars/applications/triangulation/abstract_triangulation_app.py +227 -0
- cars/applications/triangulation/line_of_sight_intersection_app.py +1243 -0
- cars/applications/triangulation/pc_transform.py +552 -0
- cars/applications/triangulation/triangulation_algo.py +371 -0
- cars/applications/triangulation/triangulation_constants.py +38 -0
- cars/applications/triangulation/triangulation_wrappers.py +259 -0
- cars/bundleadjustment.py +757 -0
- cars/cars.py +177 -0
- cars/conf/__init__.py +23 -0
- cars/conf/geoid/egm96.grd +0 -0
- cars/conf/geoid/egm96.grd.hdr +15 -0
- cars/conf/input_parameters.py +156 -0
- cars/conf/mask_cst.py +35 -0
- cars/core/__init__.py +23 -0
- cars/core/cars_logging.py +402 -0
- cars/core/constants.py +191 -0
- cars/core/constants_disparity.py +50 -0
- cars/core/datasets.py +140 -0
- cars/core/geometry/__init__.py +27 -0
- cars/core/geometry/abstract_geometry.py +1119 -0
- cars/core/geometry/shareloc_geometry.py +598 -0
- cars/core/inputs.py +568 -0
- cars/core/outputs.py +176 -0
- cars/core/preprocessing.py +722 -0
- cars/core/projection.py +843 -0
- cars/core/roi_tools.py +215 -0
- cars/core/tiling.py +774 -0
- cars/core/utils.py +164 -0
- cars/data_structures/__init__.py +23 -0
- cars/data_structures/cars_dataset.py +1541 -0
- cars/data_structures/cars_dict.py +74 -0
- cars/data_structures/corresponding_tiles_tools.py +186 -0
- cars/data_structures/dataframe_converter.py +185 -0
- cars/data_structures/format_transformation.py +297 -0
- cars/devibrate.py +689 -0
- cars/extractroi.py +264 -0
- cars/orchestrator/__init__.py +23 -0
- cars/orchestrator/achievement_tracker.py +125 -0
- cars/orchestrator/cluster/__init__.py +37 -0
- cars/orchestrator/cluster/abstract_cluster.py +244 -0
- cars/orchestrator/cluster/abstract_dask_cluster.py +375 -0
- cars/orchestrator/cluster/dask_cluster_tools.py +103 -0
- cars/orchestrator/cluster/dask_config/README.md +94 -0
- cars/orchestrator/cluster/dask_config/dask.yaml +21 -0
- cars/orchestrator/cluster/dask_config/distributed.yaml +70 -0
- cars/orchestrator/cluster/dask_config/jobqueue.yaml +26 -0
- cars/orchestrator/cluster/dask_config/reference_confs/dask-schema.yaml +137 -0
- cars/orchestrator/cluster/dask_config/reference_confs/dask.yaml +26 -0
- cars/orchestrator/cluster/dask_config/reference_confs/distributed-schema.yaml +1009 -0
- cars/orchestrator/cluster/dask_config/reference_confs/distributed.yaml +273 -0
- cars/orchestrator/cluster/dask_config/reference_confs/jobqueue.yaml +212 -0
- cars/orchestrator/cluster/dask_jobqueue_utils.py +204 -0
- cars/orchestrator/cluster/local_dask_cluster.py +116 -0
- cars/orchestrator/cluster/log_wrapper.py +1075 -0
- cars/orchestrator/cluster/mp_cluster/__init__.py +27 -0
- cars/orchestrator/cluster/mp_cluster/mp_factorizer.py +212 -0
- cars/orchestrator/cluster/mp_cluster/mp_objects.py +535 -0
- cars/orchestrator/cluster/mp_cluster/mp_tools.py +93 -0
- cars/orchestrator/cluster/mp_cluster/mp_wrapper.py +505 -0
- cars/orchestrator/cluster/mp_cluster/multiprocessing_cluster.py +873 -0
- cars/orchestrator/cluster/mp_cluster/multiprocessing_profiler.py +399 -0
- cars/orchestrator/cluster/pbs_dask_cluster.py +207 -0
- cars/orchestrator/cluster/sequential_cluster.py +139 -0
- cars/orchestrator/cluster/slurm_dask_cluster.py +234 -0
- cars/orchestrator/orchestrator.py +905 -0
- cars/orchestrator/orchestrator_constants.py +29 -0
- cars/orchestrator/registry/__init__.py +23 -0
- cars/orchestrator/registry/abstract_registry.py +143 -0
- cars/orchestrator/registry/compute_registry.py +106 -0
- cars/orchestrator/registry/id_generator.py +116 -0
- cars/orchestrator/registry/replacer_registry.py +213 -0
- cars/orchestrator/registry/saver_registry.py +363 -0
- cars/orchestrator/registry/unseen_registry.py +118 -0
- cars/orchestrator/tiles_profiler.py +279 -0
- cars/pipelines/__init__.py +26 -0
- cars/pipelines/conf_resolution/conf_final_resolution.yaml +5 -0
- cars/pipelines/conf_resolution/conf_first_resolution.yaml +2 -0
- cars/pipelines/conf_resolution/conf_intermediate_resolution.yaml +2 -0
- cars/pipelines/default/__init__.py +26 -0
- cars/pipelines/default/default_pipeline.py +786 -0
- cars/pipelines/parameters/__init__.py +0 -0
- cars/pipelines/parameters/advanced_parameters.py +417 -0
- cars/pipelines/parameters/advanced_parameters_constants.py +69 -0
- cars/pipelines/parameters/application_parameters.py +71 -0
- cars/pipelines/parameters/depth_map_inputs.py +0 -0
- cars/pipelines/parameters/dsm_inputs.py +918 -0
- cars/pipelines/parameters/dsm_inputs_constants.py +25 -0
- cars/pipelines/parameters/output_constants.py +52 -0
- cars/pipelines/parameters/output_parameters.py +454 -0
- cars/pipelines/parameters/sensor_inputs.py +842 -0
- cars/pipelines/parameters/sensor_inputs_constants.py +49 -0
- cars/pipelines/parameters/sensor_loaders/__init__.py +29 -0
- cars/pipelines/parameters/sensor_loaders/basic_classif_loader.py +86 -0
- cars/pipelines/parameters/sensor_loaders/basic_image_loader.py +98 -0
- cars/pipelines/parameters/sensor_loaders/pivot_classif_loader.py +90 -0
- cars/pipelines/parameters/sensor_loaders/pivot_image_loader.py +105 -0
- cars/pipelines/parameters/sensor_loaders/sensor_loader.py +93 -0
- cars/pipelines/parameters/sensor_loaders/sensor_loader_template.py +71 -0
- cars/pipelines/parameters/sensor_loaders/slurp_classif_loader.py +86 -0
- cars/pipelines/pipeline.py +119 -0
- cars/pipelines/pipeline_constants.py +31 -0
- cars/pipelines/pipeline_template.py +139 -0
- cars/pipelines/unit/__init__.py +26 -0
- cars/pipelines/unit/unit_pipeline.py +2850 -0
- cars/starter.py +167 -0
- cars-1.0.0rc1.dist-info/METADATA +292 -0
- cars-1.0.0rc1.dist-info/RECORD +200 -0
- cars-1.0.0rc1.dist-info/WHEEL +6 -0
- cars-1.0.0rc1.dist-info/entry_points.txt +8 -0
|
File without changes
|
|
@@ -0,0 +1,417 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
# coding: utf8
|
|
3
|
+
#
|
|
4
|
+
# Copyright (c) 2020 Centre National d'Etudes Spatiales (CNES).
|
|
5
|
+
#
|
|
6
|
+
# This file is part of CARS
|
|
7
|
+
# (see https://github.com/CNES/cars).
|
|
8
|
+
#
|
|
9
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
10
|
+
# you may not use this file except in compliance with the License.
|
|
11
|
+
# You may obtain a copy of the License at
|
|
12
|
+
#
|
|
13
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
14
|
+
#
|
|
15
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
16
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
17
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
18
|
+
# See the License for the specific language governing permissions and
|
|
19
|
+
# limitations under the License.
|
|
20
|
+
#
|
|
21
|
+
|
|
22
|
+
"""
|
|
23
|
+
CARS module containing functions to check advanced parameters configuration
|
|
24
|
+
"""
|
|
25
|
+
import logging
|
|
26
|
+
import os
|
|
27
|
+
|
|
28
|
+
import numpy as np
|
|
29
|
+
import rasterio as rio
|
|
30
|
+
from json_checker import And, Checker, OptionalKey, Or
|
|
31
|
+
|
|
32
|
+
from cars.pipelines.parameters import advanced_parameters_constants as adv_cst
|
|
33
|
+
from cars.pipelines.parameters import dsm_inputs
|
|
34
|
+
from cars.pipelines.parameters import dsm_inputs_constants as dsm_cst
|
|
35
|
+
from cars.pipelines.parameters import sensor_inputs
|
|
36
|
+
from cars.pipelines.parameters import sensor_inputs_constants as sens_cst
|
|
37
|
+
from cars.pipelines.parameters.sensor_inputs import CARS_GEOID_PATH
|
|
38
|
+
from cars.pipelines.pipeline_constants import ADVANCED
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def get_epipolar_resolutions(conf):
|
|
42
|
+
"""
|
|
43
|
+
Get the epipolar resolutions from the configuration
|
|
44
|
+
|
|
45
|
+
:param conf: configuration of advanced parameters
|
|
46
|
+
:type conf: dict
|
|
47
|
+
|
|
48
|
+
:return: list of epipolar resolutions
|
|
49
|
+
:rtype: list
|
|
50
|
+
"""
|
|
51
|
+
if adv_cst.EPIPOLAR_RESOLUTIONS in conf:
|
|
52
|
+
return conf[adv_cst.EPIPOLAR_RESOLUTIONS]
|
|
53
|
+
|
|
54
|
+
return [16, 4, 1]
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def check_advanced_parameters(
|
|
58
|
+
inputs, conf, check_epipolar_a_priori=True, output_dem_dir=None
|
|
59
|
+
):
|
|
60
|
+
"""
|
|
61
|
+
Check the advanced parameters consistency
|
|
62
|
+
|
|
63
|
+
:param inputs: configuration of inputs
|
|
64
|
+
:type inputs: dict
|
|
65
|
+
:param conf: configuration of advanced parameters
|
|
66
|
+
:type conf: dict
|
|
67
|
+
:param check_epipolar_a_priori: use epipolar a priori parameters
|
|
68
|
+
:type check_epipolar_a_priori: bool
|
|
69
|
+
|
|
70
|
+
:return: overloaded configuration
|
|
71
|
+
:rtype: dict
|
|
72
|
+
"""
|
|
73
|
+
|
|
74
|
+
overloaded_conf = conf.copy()
|
|
75
|
+
|
|
76
|
+
overloaded_conf[adv_cst.SAVE_INTERMEDIATE_DATA] = conf.get(
|
|
77
|
+
adv_cst.SAVE_INTERMEDIATE_DATA, False
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
overloaded_conf[adv_cst.LAND_COVER_MAP] = conf.get(
|
|
81
|
+
adv_cst.LAND_COVER_MAP, "global_land_cover_map.tif"
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
overloaded_conf[adv_cst.KEEP_LOW_RES_DIR] = conf.get(
|
|
85
|
+
adv_cst.KEEP_LOW_RES_DIR,
|
|
86
|
+
bool(overloaded_conf[adv_cst.SAVE_INTERMEDIATE_DATA]),
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
overloaded_conf[adv_cst.DEBUG_WITH_ROI] = conf.get(
|
|
90
|
+
adv_cst.DEBUG_WITH_ROI, False
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
overloaded_conf[adv_cst.CLASSIFICATION_TO_CONFIGURATION_MAPPING] = conf.get(
|
|
94
|
+
adv_cst.CLASSIFICATION_TO_CONFIGURATION_MAPPING, "config_mapping.json"
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
overloaded_conf[adv_cst.PHASING] = conf.get(adv_cst.PHASING, None)
|
|
98
|
+
|
|
99
|
+
overloaded_conf[adv_cst.EPIPOLAR_RESOLUTIONS] = get_epipolar_resolutions(
|
|
100
|
+
conf
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
# use endogenous dm when generated
|
|
104
|
+
overloaded_conf[adv_cst.USE_ENDOGENOUS_DEM] = conf.get(
|
|
105
|
+
adv_cst.USE_ENDOGENOUS_DEM,
|
|
106
|
+
inputs[sens_cst.INITIAL_ELEVATION][sens_cst.DEM_PATH] is None,
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
overloaded_conf[adv_cst.DSM_MERGING_TILE_SIZE] = conf.get(
|
|
110
|
+
adv_cst.DSM_MERGING_TILE_SIZE, 4000
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
overloaded_conf[adv_cst.GROUND_TRUTH_DSM] = conf.get(
|
|
114
|
+
adv_cst.GROUND_TRUTH_DSM, {}
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
# Validate ground truth DSM
|
|
118
|
+
if overloaded_conf[adv_cst.GROUND_TRUTH_DSM]:
|
|
119
|
+
overloaded_conf[adv_cst.GROUND_TRUTH_DSM][adv_cst.INPUT_AUX_PATH] = (
|
|
120
|
+
conf[adv_cst.GROUND_TRUTH_DSM].get(adv_cst.INPUT_AUX_PATH, None)
|
|
121
|
+
)
|
|
122
|
+
overloaded_conf[adv_cst.GROUND_TRUTH_DSM][adv_cst.INPUT_AUX_INTERP] = (
|
|
123
|
+
conf[adv_cst.GROUND_TRUTH_DSM].get(adv_cst.INPUT_AUX_INTERP, None)
|
|
124
|
+
)
|
|
125
|
+
check_ground_truth_dsm_data(overloaded_conf[adv_cst.GROUND_TRUTH_DSM])
|
|
126
|
+
|
|
127
|
+
if check_epipolar_a_priori:
|
|
128
|
+
# Retrieve epipolar_a_priori if it is provided
|
|
129
|
+
overloaded_conf[adv_cst.EPIPOLAR_A_PRIORI] = conf.get(
|
|
130
|
+
adv_cst.EPIPOLAR_A_PRIORI, None
|
|
131
|
+
)
|
|
132
|
+
# Retrieve terrain_a_priori if it is provided
|
|
133
|
+
overloaded_conf[adv_cst.TERRAIN_A_PRIORI] = conf.get(
|
|
134
|
+
adv_cst.TERRAIN_A_PRIORI, None
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
# Check geometry plugin
|
|
138
|
+
geom_plugin_without_dem_and_geoid = None
|
|
139
|
+
geom_plugin_with_dem_and_geoid = None
|
|
140
|
+
|
|
141
|
+
scaling_coeff = None
|
|
142
|
+
# Get last resolution for scaling
|
|
143
|
+
if isinstance(overloaded_conf[adv_cst.EPIPOLAR_RESOLUTIONS], list):
|
|
144
|
+
epipolar_resolution = overloaded_conf[adv_cst.EPIPOLAR_RESOLUTIONS][-1]
|
|
145
|
+
else:
|
|
146
|
+
epipolar_resolution = overloaded_conf[adv_cst.EPIPOLAR_RESOLUTIONS]
|
|
147
|
+
if inputs[sens_cst.SENSORS] is not None:
|
|
148
|
+
# Check geometry plugin and overwrite geomodel in conf inputs
|
|
149
|
+
(
|
|
150
|
+
inputs,
|
|
151
|
+
overloaded_conf[adv_cst.GEOMETRY_PLUGIN],
|
|
152
|
+
geom_plugin_without_dem_and_geoid,
|
|
153
|
+
geom_plugin_with_dem_and_geoid,
|
|
154
|
+
scaling_coeff,
|
|
155
|
+
) = sensor_inputs.check_geometry_plugin(
|
|
156
|
+
inputs,
|
|
157
|
+
conf.get(adv_cst.GEOMETRY_PLUGIN, None),
|
|
158
|
+
epipolar_resolution,
|
|
159
|
+
output_dem_dir,
|
|
160
|
+
)
|
|
161
|
+
elif dsm_cst.DSMS in inputs:
|
|
162
|
+
# assume the input comes from 0.5m sensor images
|
|
163
|
+
scaling_coeff = 1
|
|
164
|
+
# If there's an initial elevation with
|
|
165
|
+
# point clouds as inputs, generate a plugin (used in dsm_filling)
|
|
166
|
+
(
|
|
167
|
+
overloaded_conf[adv_cst.GEOMETRY_PLUGIN],
|
|
168
|
+
geom_plugin_with_dem_and_geoid,
|
|
169
|
+
) = dsm_inputs.check_geometry_plugin(
|
|
170
|
+
inputs, conf.get(adv_cst.GEOMETRY_PLUGIN, None)
|
|
171
|
+
)
|
|
172
|
+
|
|
173
|
+
# Check pipeline
|
|
174
|
+
overloaded_conf[adv_cst.PIPELINE] = conf.get(adv_cst.PIPELINE, "default")
|
|
175
|
+
|
|
176
|
+
# Validate inputs
|
|
177
|
+
schema = {
|
|
178
|
+
adv_cst.DEBUG_WITH_ROI: bool,
|
|
179
|
+
adv_cst.SAVE_INTERMEDIATE_DATA: Or(dict, bool),
|
|
180
|
+
adv_cst.KEEP_LOW_RES_DIR: bool,
|
|
181
|
+
adv_cst.GROUND_TRUTH_DSM: Or(dict, str),
|
|
182
|
+
adv_cst.PHASING: Or(dict, None),
|
|
183
|
+
adv_cst.GEOMETRY_PLUGIN: Or(str, dict),
|
|
184
|
+
adv_cst.PIPELINE: str,
|
|
185
|
+
adv_cst.DSM_MERGING_TILE_SIZE: And(int, lambda x: x > 0),
|
|
186
|
+
adv_cst.EPIPOLAR_RESOLUTIONS: Or(int, list),
|
|
187
|
+
adv_cst.LAND_COVER_MAP: str,
|
|
188
|
+
adv_cst.CLASSIFICATION_TO_CONFIGURATION_MAPPING: str,
|
|
189
|
+
adv_cst.USE_ENDOGENOUS_DEM: bool,
|
|
190
|
+
}
|
|
191
|
+
if check_epipolar_a_priori:
|
|
192
|
+
schema[adv_cst.EPIPOLAR_A_PRIORI] = Or(None, dict)
|
|
193
|
+
schema[adv_cst.TERRAIN_A_PRIORI] = Or(None, dict)
|
|
194
|
+
|
|
195
|
+
checker_advanced_parameters = Checker(schema)
|
|
196
|
+
checker_advanced_parameters.validate(overloaded_conf)
|
|
197
|
+
|
|
198
|
+
# Validate epipolar schema
|
|
199
|
+
epipolar_schema = {
|
|
200
|
+
adv_cst.GRID_CORRECTION: Or(list, None),
|
|
201
|
+
adv_cst.DISPARITY_RANGE: list,
|
|
202
|
+
adv_cst.REFERENCE_DEM: Or(str, None),
|
|
203
|
+
}
|
|
204
|
+
checker_epipolar = Checker(epipolar_schema)
|
|
205
|
+
|
|
206
|
+
# Check terrain a priori
|
|
207
|
+
if check_epipolar_a_priori and overloaded_conf[adv_cst.TERRAIN_A_PRIORI]:
|
|
208
|
+
overloaded_conf[adv_cst.TERRAIN_A_PRIORI][adv_cst.DEM_MEDIAN] = (
|
|
209
|
+
overloaded_conf[adv_cst.TERRAIN_A_PRIORI].get(
|
|
210
|
+
adv_cst.DEM_MEDIAN, None
|
|
211
|
+
)
|
|
212
|
+
)
|
|
213
|
+
overloaded_conf[adv_cst.TERRAIN_A_PRIORI][adv_cst.DEM_MIN] = (
|
|
214
|
+
overloaded_conf[adv_cst.TERRAIN_A_PRIORI].get(adv_cst.DEM_MIN, None)
|
|
215
|
+
)
|
|
216
|
+
overloaded_conf[adv_cst.TERRAIN_A_PRIORI][adv_cst.DEM_MAX] = (
|
|
217
|
+
overloaded_conf[adv_cst.TERRAIN_A_PRIORI].get(adv_cst.DEM_MAX, None)
|
|
218
|
+
)
|
|
219
|
+
terrain_a_priori_schema = {
|
|
220
|
+
adv_cst.DEM_MEDIAN: str,
|
|
221
|
+
adv_cst.DEM_MIN: Or(str, None), # TODO mandatory with local disp
|
|
222
|
+
adv_cst.DEM_MAX: Or(str, None),
|
|
223
|
+
}
|
|
224
|
+
checker_terrain = Checker(terrain_a_priori_schema)
|
|
225
|
+
checker_terrain.validate(overloaded_conf[adv_cst.TERRAIN_A_PRIORI])
|
|
226
|
+
|
|
227
|
+
# check epipolar a priori for each image pair
|
|
228
|
+
if check_epipolar_a_priori and (
|
|
229
|
+
not overloaded_conf[adv_cst.TERRAIN_A_PRIORI] in (None, {})
|
|
230
|
+
or not overloaded_conf[adv_cst.EPIPOLAR_A_PRIORI] in (None, {})
|
|
231
|
+
):
|
|
232
|
+
validate_epipolar_a_priori(overloaded_conf, checker_epipolar)
|
|
233
|
+
|
|
234
|
+
return (
|
|
235
|
+
inputs,
|
|
236
|
+
overloaded_conf,
|
|
237
|
+
overloaded_conf[adv_cst.GEOMETRY_PLUGIN],
|
|
238
|
+
geom_plugin_without_dem_and_geoid,
|
|
239
|
+
geom_plugin_with_dem_and_geoid,
|
|
240
|
+
scaling_coeff,
|
|
241
|
+
overloaded_conf[adv_cst.LAND_COVER_MAP],
|
|
242
|
+
overloaded_conf[adv_cst.CLASSIFICATION_TO_CONFIGURATION_MAPPING],
|
|
243
|
+
)
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
def validate_epipolar_a_priori(
|
|
247
|
+
overloaded_conf,
|
|
248
|
+
checker_epipolar,
|
|
249
|
+
):
|
|
250
|
+
"""
|
|
251
|
+
Validate inner epipolar configuration
|
|
252
|
+
|
|
253
|
+
:param conf : input configuration json
|
|
254
|
+
:type conf: dict
|
|
255
|
+
:param overloaded_conf : overloaded configuration json
|
|
256
|
+
:type overloaded_conf: dict
|
|
257
|
+
:param checker_epipolar : json checker
|
|
258
|
+
:type checker_epipolar: Checker
|
|
259
|
+
"""
|
|
260
|
+
|
|
261
|
+
if overloaded_conf[adv_cst.EPIPOLAR_A_PRIORI] is not None:
|
|
262
|
+
for key_image_pair in overloaded_conf[adv_cst.EPIPOLAR_A_PRIORI]:
|
|
263
|
+
checker_epipolar.validate(
|
|
264
|
+
overloaded_conf[adv_cst.EPIPOLAR_A_PRIORI][key_image_pair]
|
|
265
|
+
)
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
def check_ground_truth_dsm_data(conf):
|
|
269
|
+
"""
|
|
270
|
+
Check data of the image ground truth
|
|
271
|
+
|
|
272
|
+
:param conf: ground truth dsm configuration
|
|
273
|
+
:type conf: str
|
|
274
|
+
"""
|
|
275
|
+
if isinstance(conf, str):
|
|
276
|
+
with rio.open(conf) as img_reader:
|
|
277
|
+
trans = img_reader.transform
|
|
278
|
+
if trans.e < 0:
|
|
279
|
+
logging.warning(
|
|
280
|
+
"{} seems to have an incoherent pixel size. "
|
|
281
|
+
"Input images has to be in sensor geometry.".format(conf)
|
|
282
|
+
)
|
|
283
|
+
|
|
284
|
+
conf[adv_cst.INPUT_GEOID] = conf.get(adv_cst.INPUT_GEOID, None)
|
|
285
|
+
|
|
286
|
+
if isinstance(conf, dict):
|
|
287
|
+
ground_truth_dsm_schema = {
|
|
288
|
+
adv_cst.INPUT_GROUND_TRUTH_DSM: str,
|
|
289
|
+
OptionalKey(adv_cst.INPUT_AUX_PATH): Or(dict, None),
|
|
290
|
+
OptionalKey(adv_cst.INPUT_AUX_INTERP): Or(dict, None),
|
|
291
|
+
adv_cst.INPUT_GEOID: Or(None, str, bool),
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
checker_ground_truth_dsm_schema = Checker(ground_truth_dsm_schema)
|
|
295
|
+
checker_ground_truth_dsm_schema.validate(conf)
|
|
296
|
+
|
|
297
|
+
gt_dsm_path = conf[adv_cst.INPUT_GROUND_TRUTH_DSM]
|
|
298
|
+
with rio.open(gt_dsm_path) as img_reader:
|
|
299
|
+
trans = img_reader.transform
|
|
300
|
+
if trans.e < 0:
|
|
301
|
+
logging.warning(
|
|
302
|
+
"{} seems to have an incoherent pixel size. "
|
|
303
|
+
"Input images has to be in sensor geometry.".format(
|
|
304
|
+
gt_dsm_path
|
|
305
|
+
)
|
|
306
|
+
)
|
|
307
|
+
|
|
308
|
+
# Update geoid
|
|
309
|
+
if isinstance(conf[adv_cst.INPUT_GEOID], bool):
|
|
310
|
+
if conf[adv_cst.INPUT_GEOID]:
|
|
311
|
+
# Use CARS geoid
|
|
312
|
+
logging.info(
|
|
313
|
+
"CARS will use its own internal file as geoid reference"
|
|
314
|
+
)
|
|
315
|
+
package_path = os.path.dirname(__file__)
|
|
316
|
+
geoid_path = os.path.join(
|
|
317
|
+
package_path, "..", "..", "conf", CARS_GEOID_PATH
|
|
318
|
+
)
|
|
319
|
+
conf[adv_cst.INPUT_GEOID] = geoid_path
|
|
320
|
+
else:
|
|
321
|
+
conf[adv_cst.INPUT_GEOID] = None
|
|
322
|
+
|
|
323
|
+
path_dict = conf.get(adv_cst.INPUT_AUX_PATH, None)
|
|
324
|
+
if path_dict is not None:
|
|
325
|
+
for key in path_dict.keys():
|
|
326
|
+
if not isinstance(path_dict[key], str):
|
|
327
|
+
raise RuntimeError("Path should be a string")
|
|
328
|
+
if not os.path.exists(path_dict[key]):
|
|
329
|
+
raise RuntimeError("Path doesn't exist")
|
|
330
|
+
|
|
331
|
+
path_interp = conf.get(adv_cst.INPUT_AUX_INTERP, None)
|
|
332
|
+
if path_interp is not None:
|
|
333
|
+
for key in path_interp.keys():
|
|
334
|
+
if not isinstance(path_interp[key], str):
|
|
335
|
+
raise RuntimeError("interpolator should be a string")
|
|
336
|
+
if path_interp[key] not in (
|
|
337
|
+
"nearest",
|
|
338
|
+
"linear",
|
|
339
|
+
"cubic",
|
|
340
|
+
"slinear",
|
|
341
|
+
"quintic",
|
|
342
|
+
):
|
|
343
|
+
raise RuntimeError("interpolator does not exist")
|
|
344
|
+
|
|
345
|
+
|
|
346
|
+
def update_conf( # pylint: disable=too-many-positional-arguments # noqa: C901
|
|
347
|
+
conf,
|
|
348
|
+
grid_correction_coef=None,
|
|
349
|
+
reference_dem=None,
|
|
350
|
+
dmin=None,
|
|
351
|
+
dmax=None,
|
|
352
|
+
pair_key=None,
|
|
353
|
+
dem_median=None,
|
|
354
|
+
dem_min=None,
|
|
355
|
+
dem_max=None,
|
|
356
|
+
):
|
|
357
|
+
"""
|
|
358
|
+
Update the conf with grid correction and disparity range
|
|
359
|
+
:param grid_correction_coef: grid correction coefficient
|
|
360
|
+
:type grid_correction_coef: list
|
|
361
|
+
:param reference_dem: Dem used to compute epipolar grids
|
|
362
|
+
:type reference_dem: str
|
|
363
|
+
:param dmin: disparity range minimum
|
|
364
|
+
:type dmin: float
|
|
365
|
+
:param dmax: disparity range maximum
|
|
366
|
+
:type dmax: float
|
|
367
|
+
:param pair_key: name of the inputs key pair
|
|
368
|
+
:type pair_key: str
|
|
369
|
+
"""
|
|
370
|
+
|
|
371
|
+
if pair_key is not None:
|
|
372
|
+
if ADVANCED not in conf:
|
|
373
|
+
conf[ADVANCED] = {}
|
|
374
|
+
if adv_cst.EPIPOLAR_A_PRIORI not in conf[ADVANCED]:
|
|
375
|
+
conf[ADVANCED][adv_cst.EPIPOLAR_A_PRIORI] = {}
|
|
376
|
+
if conf[ADVANCED][adv_cst.EPIPOLAR_A_PRIORI] is None:
|
|
377
|
+
conf[ADVANCED][adv_cst.EPIPOLAR_A_PRIORI] = {}
|
|
378
|
+
if pair_key not in conf[ADVANCED][adv_cst.EPIPOLAR_A_PRIORI]:
|
|
379
|
+
conf[ADVANCED][adv_cst.EPIPOLAR_A_PRIORI][pair_key] = {}
|
|
380
|
+
if grid_correction_coef is not None and reference_dem is not None:
|
|
381
|
+
conf[ADVANCED][adv_cst.EPIPOLAR_A_PRIORI][pair_key][
|
|
382
|
+
"reference_dem"
|
|
383
|
+
] = reference_dem
|
|
384
|
+
if len(grid_correction_coef) == 2:
|
|
385
|
+
conf[ADVANCED][adv_cst.EPIPOLAR_A_PRIORI][pair_key][
|
|
386
|
+
"grid_correction"
|
|
387
|
+
] = (
|
|
388
|
+
np.concatenate(grid_correction_coef[0], axis=0).tolist()[
|
|
389
|
+
:-1
|
|
390
|
+
]
|
|
391
|
+
+ np.concatenate(grid_correction_coef[1], axis=0).tolist()[
|
|
392
|
+
:-1
|
|
393
|
+
]
|
|
394
|
+
)
|
|
395
|
+
else:
|
|
396
|
+
conf[ADVANCED][adv_cst.EPIPOLAR_A_PRIORI][pair_key][
|
|
397
|
+
"grid_correction"
|
|
398
|
+
] = list(grid_correction_coef)
|
|
399
|
+
if None not in (dmin, dmax):
|
|
400
|
+
conf[ADVANCED][adv_cst.EPIPOLAR_A_PRIORI][pair_key][
|
|
401
|
+
"disparity_range"
|
|
402
|
+
] = [
|
|
403
|
+
dmin,
|
|
404
|
+
dmax,
|
|
405
|
+
]
|
|
406
|
+
|
|
407
|
+
if adv_cst.TERRAIN_A_PRIORI not in conf[ADVANCED]:
|
|
408
|
+
conf[ADVANCED][adv_cst.TERRAIN_A_PRIORI] = {}
|
|
409
|
+
if conf[ADVANCED][adv_cst.TERRAIN_A_PRIORI] is None:
|
|
410
|
+
conf[ADVANCED][adv_cst.TERRAIN_A_PRIORI] = {}
|
|
411
|
+
|
|
412
|
+
if dem_median is not None:
|
|
413
|
+
conf[ADVANCED][adv_cst.TERRAIN_A_PRIORI]["dem_median"] = dem_median
|
|
414
|
+
if dem_min is not None:
|
|
415
|
+
conf[ADVANCED][adv_cst.TERRAIN_A_PRIORI]["dem_min"] = dem_min
|
|
416
|
+
if dem_max is not None:
|
|
417
|
+
conf[ADVANCED][adv_cst.TERRAIN_A_PRIORI]["dem_max"] = dem_max
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
# coding: utf8
|
|
3
|
+
#
|
|
4
|
+
# Copyright (c) 2020 Centre National d'Etudes Spatiales (CNES).
|
|
5
|
+
#
|
|
6
|
+
# This file is part of CARS
|
|
7
|
+
# (see https://github.com/CNES/cars).
|
|
8
|
+
#
|
|
9
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
10
|
+
# you may not use this file except in compliance with the License.
|
|
11
|
+
# You may obtain a copy of the License at
|
|
12
|
+
#
|
|
13
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
14
|
+
#
|
|
15
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
16
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
17
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
18
|
+
# See the License for the specific language governing permissions and
|
|
19
|
+
# limitations under the License.
|
|
20
|
+
#
|
|
21
|
+
|
|
22
|
+
"""
|
|
23
|
+
This module contains the advanced parameter definitions
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
SAVE_INTERMEDIATE_DATA = "save_intermediate_data"
|
|
27
|
+
KEEP_LOW_RES_DIR = "keep_low_res_dir"
|
|
28
|
+
PHASING = "phasing"
|
|
29
|
+
DEBUG_WITH_ROI = "debug_with_roi"
|
|
30
|
+
LAND_COVER_MAP = "land_cover_map"
|
|
31
|
+
CLASSIFICATION_TO_CONFIGURATION_MAPPING = (
|
|
32
|
+
"classification_to_configuration_mapping"
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
EPIPOLAR_A_PRIORI = "epipolar_a_priori"
|
|
36
|
+
RESOLUTION_A_PRIORI = "resolution_a_priori"
|
|
37
|
+
GROUND_TRUTH_DSM = "ground_truth_dsm"
|
|
38
|
+
|
|
39
|
+
EPIPOLAR_RESOLUTIONS = "epipolar_resolutions"
|
|
40
|
+
|
|
41
|
+
DSM_MERGING_TILE_SIZE = "dsm_merging_tile_size"
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
# inner epipolar a priori constants
|
|
45
|
+
GRID_CORRECTION = "grid_correction"
|
|
46
|
+
DISPARITY_RANGE = "disparity_range"
|
|
47
|
+
REFERENCE_DEM = "reference_dem"
|
|
48
|
+
|
|
49
|
+
TERRAIN_A_PRIORI = "terrain_a_priori"
|
|
50
|
+
USE_ENDOGENOUS_DEM = "use_endogenous_dem"
|
|
51
|
+
DEM_MEDIAN = "dem_median"
|
|
52
|
+
DEM_MIN = "dem_min"
|
|
53
|
+
DEM_MAX = "dem_max"
|
|
54
|
+
|
|
55
|
+
# ground truth dsm
|
|
56
|
+
INPUT_GROUND_TRUTH_DSM = "dsm"
|
|
57
|
+
INPUT_CLASSIFICATION = "classification"
|
|
58
|
+
INPUT_AUX_PATH = "auxiliary_data"
|
|
59
|
+
INPUT_AUX_INTERP = "auxiliary_data_interpolation"
|
|
60
|
+
INPUT_GEOID = "geoid"
|
|
61
|
+
INPUT_EPSG = "epsg"
|
|
62
|
+
|
|
63
|
+
PERFORMANCE_MAP_CLASSES = "performance_map_classes"
|
|
64
|
+
|
|
65
|
+
TEXTURE_BANDS = "texture_bands"
|
|
66
|
+
|
|
67
|
+
GEOMETRY_PLUGIN = "geometry_plugin"
|
|
68
|
+
|
|
69
|
+
PIPELINE = "pipeline"
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
# coding: utf8
|
|
3
|
+
#
|
|
4
|
+
# Copyright (c) 2020 Centre National d'Etudes Spatiales (CNES).
|
|
5
|
+
#
|
|
6
|
+
# This file is part of CARS
|
|
7
|
+
# (see https://github.com/CNES/cars).
|
|
8
|
+
#
|
|
9
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
10
|
+
# you may not use this file except in compliance with the License.
|
|
11
|
+
# You may obtain a copy of the License at
|
|
12
|
+
#
|
|
13
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
14
|
+
#
|
|
15
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
16
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
17
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
18
|
+
# See the License for the specific language governing permissions and
|
|
19
|
+
# limitations under the License.
|
|
20
|
+
#
|
|
21
|
+
"""
|
|
22
|
+
General application configuration module
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def get_needed_apps(
|
|
27
|
+
sensors_in_inputs, save_output_dsm, save_output_point_cloud, conf
|
|
28
|
+
):
|
|
29
|
+
"""
|
|
30
|
+
This function returns the apps needed by the CARS pipeline,
|
|
31
|
+
depending on overall parameters and the user configuration
|
|
32
|
+
"""
|
|
33
|
+
needed_applications = []
|
|
34
|
+
if sensors_in_inputs:
|
|
35
|
+
needed_applications += [
|
|
36
|
+
"grid_generation",
|
|
37
|
+
"resampling",
|
|
38
|
+
"ground_truth_reprojection",
|
|
39
|
+
"dense_match_filling",
|
|
40
|
+
"sparse_matching",
|
|
41
|
+
"dense_matching",
|
|
42
|
+
"triangulation",
|
|
43
|
+
"dem_generation",
|
|
44
|
+
]
|
|
45
|
+
|
|
46
|
+
add_default_pc_outlier_removal = True
|
|
47
|
+
for key in conf:
|
|
48
|
+
if key.startswith("point_cloud_outlier_removal"):
|
|
49
|
+
add_default_pc_outlier_removal = False
|
|
50
|
+
needed_applications += [key]
|
|
51
|
+
|
|
52
|
+
if add_default_pc_outlier_removal:
|
|
53
|
+
needed_applications += [
|
|
54
|
+
"point_cloud_outlier_removal.1",
|
|
55
|
+
"point_cloud_outlier_removal.2",
|
|
56
|
+
]
|
|
57
|
+
|
|
58
|
+
if save_output_dsm or save_output_point_cloud:
|
|
59
|
+
needed_applications += ["pc_denoising"]
|
|
60
|
+
|
|
61
|
+
if save_output_dsm:
|
|
62
|
+
needed_applications += [
|
|
63
|
+
"point_cloud_rasterization",
|
|
64
|
+
"auxiliary_filling",
|
|
65
|
+
]
|
|
66
|
+
|
|
67
|
+
for key in conf:
|
|
68
|
+
if key.startswith("dsm_filling"):
|
|
69
|
+
needed_applications += [key]
|
|
70
|
+
|
|
71
|
+
return needed_applications
|
|
File without changes
|