cars 1.0.0rc3__cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.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.
- cars/__init__.py +74 -0
- cars/applications/__init__.py +40 -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 +105 -0
- cars/applications/auxiliary_filling/auxiliary_filling_algo.py +475 -0
- cars/applications/auxiliary_filling/auxiliary_filling_from_sensors_app.py +632 -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 +46 -0
- cars/applications/dem_generation/bulldozer_dem_app.py +641 -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 +1461 -0
- cars/applications/dense_matching/cpp/__init__.py +0 -0
- cars/applications/dense_matching/cpp/dense_matching_cpp.cpython-313-x86_64-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 +597 -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 +278 -0
- cars/applications/dsm_filling/bulldozer_config/base_config.yaml +44 -0
- cars/applications/dsm_filling/bulldozer_filling_app.py +288 -0
- cars/applications/dsm_filling/exogenous_filling_app.py +341 -0
- cars/applications/dsm_merging/__init__.py +28 -0
- cars/applications/dsm_merging/abstract_dsm_merging_app.py +101 -0
- cars/applications/dsm_merging/weighted_fusion_app.py +639 -0
- cars/applications/grid_correction/__init__.py +30 -0
- cars/applications/grid_correction/abstract_grid_correction_app.py +103 -0
- cars/applications/grid_correction/grid_correction_app.py +557 -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_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 +522 -0
- cars/applications/point_cloud_outlier_removal/statistical_app.py +528 -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 +639 -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 +760 -0
- cars/applications/resampling/resampling_algo.py +590 -0
- cars/applications/resampling/resampling_constants.py +36 -0
- cars/applications/resampling/resampling_wrappers.py +309 -0
- cars/applications/sensors_subsampling/__init__.py +32 -0
- cars/applications/sensors_subsampling/abstract_subsampling_app.py +109 -0
- cars/applications/sensors_subsampling/rasterio_subsampling_app.py +420 -0
- cars/applications/sensors_subsampling/subsampling_algo.py +108 -0
- cars/applications/sparse_matching/__init__.py +30 -0
- cars/applications/sparse_matching/abstract_sparse_matching_app.py +599 -0
- cars/applications/sparse_matching/sift_app.py +724 -0
- cars/applications/sparse_matching/sparse_matching_algo.py +360 -0
- cars/applications/sparse_matching/sparse_matching_constants.py +66 -0
- cars/applications/sparse_matching/sparse_matching_wrappers.py +282 -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 +750 -0
- cars/cars.py +179 -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 +1130 -0
- cars/core/geometry/shareloc_geometry.py +604 -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 +1544 -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 +250 -0
- cars/orchestrator/cluster/abstract_dask_cluster.py +381 -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 +728 -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 +986 -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/memory_tools.py +47 -0
- cars/orchestrator/orchestrator.py +755 -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 +4 -0
- cars/pipelines/conf_resolution/conf_intermediate_resolution.yaml +2 -0
- cars/pipelines/default/__init__.py +26 -0
- cars/pipelines/default/default_pipeline.py +1095 -0
- cars/pipelines/filling/__init__.py +26 -0
- cars/pipelines/filling/filling.py +981 -0
- cars/pipelines/formatting/__init__.py +26 -0
- cars/pipelines/formatting/formatting.py +190 -0
- cars/pipelines/merging/__init__.py +26 -0
- cars/pipelines/merging/merging.py +439 -0
- cars/pipelines/parameters/__init__.py +0 -0
- cars/pipelines/parameters/advanced_parameters.py +256 -0
- cars/pipelines/parameters/advanced_parameters_constants.py +68 -0
- cars/pipelines/parameters/application_parameters.py +72 -0
- cars/pipelines/parameters/depth_map_inputs.py +0 -0
- cars/pipelines/parameters/dsm_inputs.py +349 -0
- cars/pipelines/parameters/dsm_inputs_constants.py +25 -0
- cars/pipelines/parameters/output_constants.py +52 -0
- cars/pipelines/parameters/output_parameters.py +435 -0
- cars/pipelines/parameters/sensor_inputs.py +859 -0
- cars/pipelines/parameters/sensor_inputs_constants.py +51 -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 +38 -0
- cars/pipelines/pipeline_template.py +135 -0
- cars/pipelines/subsampling/__init__.py +26 -0
- cars/pipelines/subsampling/subsampling.py +358 -0
- cars/pipelines/surface_modeling/__init__.py +26 -0
- cars/pipelines/surface_modeling/surface_modeling.py +2098 -0
- cars/pipelines/tie_points/__init__.py +26 -0
- cars/pipelines/tie_points/tie_points.py +536 -0
- cars/starter.py +167 -0
- cars-1.0.0rc3.dist-info/METADATA +289 -0
- cars-1.0.0rc3.dist-info/RECORD +220 -0
- cars-1.0.0rc3.dist-info/WHEEL +6 -0
- cars-1.0.0rc3.dist-info/entry_points.txt +8 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
# coding: utf8
|
|
3
|
+
#
|
|
4
|
+
# Copyright (c) 2025 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
|
+
CARS tie points pipeline module init file
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
# Cars imports
|
|
26
|
+
from cars.pipelines.tie_points import tie_points # noqa: F401
|
|
@@ -0,0 +1,536 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
# coding: utf8
|
|
3
|
+
#
|
|
4
|
+
# Copyright (c) 2025 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
|
+
CARS tie points pipeline class file
|
|
23
|
+
"""
|
|
24
|
+
import logging
|
|
25
|
+
import os
|
|
26
|
+
|
|
27
|
+
from json_checker import Checker, Or
|
|
28
|
+
|
|
29
|
+
from cars.applications.application import Application
|
|
30
|
+
from cars.core.utils import safe_makedirs
|
|
31
|
+
from cars.orchestrator import orchestrator
|
|
32
|
+
from cars.pipelines.parameters import advanced_parameters_constants as adv_cst
|
|
33
|
+
from cars.pipelines.parameters import output_constants as out_cst
|
|
34
|
+
from cars.pipelines.parameters import sensor_inputs
|
|
35
|
+
from cars.pipelines.parameters import sensor_inputs_constants as sens_cst
|
|
36
|
+
from cars.pipelines.pipeline import Pipeline
|
|
37
|
+
from cars.pipelines.pipeline_constants import (
|
|
38
|
+
ADVANCED,
|
|
39
|
+
APPLICATIONS,
|
|
40
|
+
INPUT,
|
|
41
|
+
ORCHESTRATOR,
|
|
42
|
+
OUTPUT,
|
|
43
|
+
)
|
|
44
|
+
from cars.pipelines.pipeline_template import PipelineTemplate
|
|
45
|
+
|
|
46
|
+
PIPELINE = "tie_points"
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
@Pipeline.register(
|
|
50
|
+
PIPELINE,
|
|
51
|
+
)
|
|
52
|
+
class TiePointsPipeline(PipelineTemplate):
|
|
53
|
+
"""
|
|
54
|
+
Tie points pipeline
|
|
55
|
+
"""
|
|
56
|
+
|
|
57
|
+
def __init__(self, conf, config_dir=None):
|
|
58
|
+
"""
|
|
59
|
+
Creates pipeline
|
|
60
|
+
|
|
61
|
+
Directly creates class attributes:
|
|
62
|
+
used_conf
|
|
63
|
+
geom_plugin_without_dem_and_geoid
|
|
64
|
+
geom_plugin_with_dem_and_geoid
|
|
65
|
+
|
|
66
|
+
:param conf: configuration
|
|
67
|
+
:type conf: dictionary
|
|
68
|
+
:param config_dir: path to dir containing json/yaml
|
|
69
|
+
:type config_dir: str
|
|
70
|
+
"""
|
|
71
|
+
|
|
72
|
+
# Used conf
|
|
73
|
+
self.used_conf = {}
|
|
74
|
+
|
|
75
|
+
# Transform relative path to absolute path
|
|
76
|
+
if config_dir is not None:
|
|
77
|
+
config_dir = os.path.abspath(config_dir)
|
|
78
|
+
|
|
79
|
+
# Check global conf
|
|
80
|
+
self.check_global_schema(conf)
|
|
81
|
+
|
|
82
|
+
# Check conf orchestrator
|
|
83
|
+
self.used_conf[ORCHESTRATOR] = self.check_orchestrator(
|
|
84
|
+
conf.get(ORCHESTRATOR, None)
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
# Check conf inputs
|
|
88
|
+
inputs = self.check_inputs(conf[INPUT], config_dir=config_dir)
|
|
89
|
+
self.used_conf[INPUT] = inputs
|
|
90
|
+
|
|
91
|
+
# Check conf output
|
|
92
|
+
output = self.check_output(conf[OUTPUT])
|
|
93
|
+
|
|
94
|
+
self.used_conf[OUTPUT] = output
|
|
95
|
+
self.out_dir = self.used_conf[OUTPUT][out_cst.OUT_DIRECTORY]
|
|
96
|
+
self.dump_dir = os.path.join(self.out_dir, "dump_dir")
|
|
97
|
+
|
|
98
|
+
# Check advanced parameters
|
|
99
|
+
output_dem_dir = os.path.join(self.dump_dir, "initial_elevation")
|
|
100
|
+
safe_makedirs(output_dem_dir)
|
|
101
|
+
pipeline_conf = conf.get(PIPELINE, {})
|
|
102
|
+
self.used_conf[PIPELINE] = {}
|
|
103
|
+
(
|
|
104
|
+
inputs,
|
|
105
|
+
advanced,
|
|
106
|
+
self.geometry_plugin,
|
|
107
|
+
self.geom_plugin_without_dem_and_geoid,
|
|
108
|
+
self.geom_plugin_with_dem_and_geoid,
|
|
109
|
+
) = self.check_advanced_parameters(
|
|
110
|
+
inputs,
|
|
111
|
+
pipeline_conf.get(ADVANCED, {}),
|
|
112
|
+
output_dem_dir=output_dem_dir,
|
|
113
|
+
)
|
|
114
|
+
self.used_conf[PIPELINE][ADVANCED] = advanced
|
|
115
|
+
self.resampling_tile_width = advanced["resampling_tile_width"]
|
|
116
|
+
self.resampling_tile_height = advanced["resampling_tile_height"]
|
|
117
|
+
|
|
118
|
+
# Check conf output
|
|
119
|
+
output = self.check_output(conf[OUTPUT])
|
|
120
|
+
|
|
121
|
+
self.used_conf[OUTPUT] = output
|
|
122
|
+
self.out_dir = self.used_conf[OUTPUT][out_cst.OUT_DIRECTORY]
|
|
123
|
+
self.dump_dir = os.path.join(self.out_dir, "dump_dir")
|
|
124
|
+
|
|
125
|
+
self.save_all_intermediate_data = self.used_conf[PIPELINE][ADVANCED][
|
|
126
|
+
adv_cst.SAVE_INTERMEDIATE_DATA
|
|
127
|
+
]
|
|
128
|
+
|
|
129
|
+
# Check conf application
|
|
130
|
+
application_conf = self.check_applications(
|
|
131
|
+
pipeline_conf.get(APPLICATIONS, {})
|
|
132
|
+
)
|
|
133
|
+
|
|
134
|
+
# Check conf application vs inputs application
|
|
135
|
+
application_conf = self.check_applications_with_inputs(
|
|
136
|
+
self.used_conf[INPUT], application_conf
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
self.used_conf[PIPELINE][APPLICATIONS] = application_conf
|
|
140
|
+
|
|
141
|
+
self.out_dir = self.used_conf[OUTPUT][out_cst.OUT_DIRECTORY]
|
|
142
|
+
|
|
143
|
+
@staticmethod
|
|
144
|
+
def check_inputs(conf, config_dir=None):
|
|
145
|
+
"""
|
|
146
|
+
Check the inputs given
|
|
147
|
+
|
|
148
|
+
:param conf: configuration of inputs
|
|
149
|
+
:type conf: dict
|
|
150
|
+
:param config_dir: directory of used json/yaml, if
|
|
151
|
+
user filled paths with relative paths
|
|
152
|
+
:type config_dir: str
|
|
153
|
+
|
|
154
|
+
:return: overloaded inputs
|
|
155
|
+
:rtype: dict
|
|
156
|
+
"""
|
|
157
|
+
overloaded_conf = conf.copy()
|
|
158
|
+
|
|
159
|
+
overloaded_conf[sens_cst.RECTIFICATION_GRIDS] = conf.get(
|
|
160
|
+
sens_cst.RECTIFICATION_GRIDS, None
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
overloaded_conf[sens_cst.PAIRING] = conf.get(sens_cst.PAIRING, None)
|
|
164
|
+
|
|
165
|
+
overloaded_conf[sens_cst.ROI] = conf.get(sens_cst.ROI, None)
|
|
166
|
+
|
|
167
|
+
overloaded_conf[sens_cst.INITIAL_ELEVATION] = (
|
|
168
|
+
sensor_inputs.get_initial_elevation(
|
|
169
|
+
conf.get(sens_cst.INITIAL_ELEVATION, None)
|
|
170
|
+
)
|
|
171
|
+
)
|
|
172
|
+
overloaded_conf[sens_cst.LOADERS] = sensor_inputs.check_loaders(
|
|
173
|
+
conf.get(sens_cst.LOADERS, {})
|
|
174
|
+
)
|
|
175
|
+
|
|
176
|
+
classif_loader = overloaded_conf[sens_cst.LOADERS][
|
|
177
|
+
sens_cst.INPUT_CLASSIFICATION
|
|
178
|
+
]
|
|
179
|
+
|
|
180
|
+
overloaded_conf[sens_cst.FILLING] = sensor_inputs.check_filling(
|
|
181
|
+
conf.get(sens_cst.FILLING, {}), classif_loader
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
# Validate inputs
|
|
185
|
+
inputs_schema = {
|
|
186
|
+
sens_cst.SENSORS: dict,
|
|
187
|
+
sens_cst.PAIRING: Or([[str]], None),
|
|
188
|
+
sens_cst.RECTIFICATION_GRIDS: Or(dict, None),
|
|
189
|
+
sens_cst.INITIAL_ELEVATION: Or(str, dict, None),
|
|
190
|
+
sens_cst.ROI: Or(str, dict, None),
|
|
191
|
+
sens_cst.LOADERS: dict,
|
|
192
|
+
sens_cst.FILLING: dict,
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
checker_inputs = Checker(inputs_schema)
|
|
196
|
+
checker_inputs.validate(overloaded_conf)
|
|
197
|
+
|
|
198
|
+
sensor_inputs.check_sensors(conf, overloaded_conf, config_dir)
|
|
199
|
+
|
|
200
|
+
# Check srtm dir
|
|
201
|
+
sensor_inputs.check_srtm(
|
|
202
|
+
overloaded_conf[sens_cst.INITIAL_ELEVATION][sens_cst.DEM_PATH]
|
|
203
|
+
)
|
|
204
|
+
|
|
205
|
+
return overloaded_conf
|
|
206
|
+
|
|
207
|
+
def check_applications_with_inputs(self, inputs_conf, application_conf):
|
|
208
|
+
"""
|
|
209
|
+
Check for each application the input and output configuration
|
|
210
|
+
consistency
|
|
211
|
+
|
|
212
|
+
:param inputs_conf: inputs checked configuration
|
|
213
|
+
:type inputs_conf: dict
|
|
214
|
+
:param application_conf: application checked configuration
|
|
215
|
+
:type application_conf: dict
|
|
216
|
+
"""
|
|
217
|
+
initial_elevation = (
|
|
218
|
+
inputs_conf[sens_cst.INITIAL_ELEVATION]["dem"] is not None
|
|
219
|
+
)
|
|
220
|
+
if self.sparse_matching_app.elevation_delta_lower_bound is None:
|
|
221
|
+
self.sparse_matching_app.used_config[
|
|
222
|
+
"elevation_delta_lower_bound"
|
|
223
|
+
] = (-500 if initial_elevation else -1000)
|
|
224
|
+
self.sparse_matching_app.elevation_delta_lower_bound = (
|
|
225
|
+
self.sparse_matching_app.used_config[
|
|
226
|
+
"elevation_delta_lower_bound"
|
|
227
|
+
]
|
|
228
|
+
)
|
|
229
|
+
if self.sparse_matching_app.elevation_delta_upper_bound is None:
|
|
230
|
+
self.sparse_matching_app.used_config[
|
|
231
|
+
"elevation_delta_upper_bound"
|
|
232
|
+
] = (1000 if initial_elevation else 9000)
|
|
233
|
+
self.sparse_matching_app.elevation_delta_upper_bound = (
|
|
234
|
+
self.sparse_matching_app.used_config[
|
|
235
|
+
"elevation_delta_upper_bound"
|
|
236
|
+
]
|
|
237
|
+
)
|
|
238
|
+
application_conf["sparse_matching"] = (
|
|
239
|
+
self.sparse_matching_app.get_conf()
|
|
240
|
+
)
|
|
241
|
+
|
|
242
|
+
return application_conf
|
|
243
|
+
|
|
244
|
+
@staticmethod
|
|
245
|
+
def check_advanced_parameters(inputs, conf, output_dem_dir=None):
|
|
246
|
+
"""
|
|
247
|
+
Check the advanced parameters consistency
|
|
248
|
+
|
|
249
|
+
:param conf: configuration of inputs
|
|
250
|
+
:type conf: dict
|
|
251
|
+
:param config_dir: directory of used json/yaml, if
|
|
252
|
+
user filled paths with relative paths
|
|
253
|
+
:type config_dir: str
|
|
254
|
+
|
|
255
|
+
:return: overloaded inputs
|
|
256
|
+
:rtype: dict
|
|
257
|
+
"""
|
|
258
|
+
|
|
259
|
+
overloaded_conf = conf.copy()
|
|
260
|
+
|
|
261
|
+
overloaded_conf["resampling_tile_width"] = conf.get(
|
|
262
|
+
"resampling_tile_width", 5000
|
|
263
|
+
)
|
|
264
|
+
overloaded_conf["resampling_tile_height"] = conf.get(
|
|
265
|
+
"resampling_tile_height", 60
|
|
266
|
+
)
|
|
267
|
+
|
|
268
|
+
overloaded_conf[adv_cst.SAVE_INTERMEDIATE_DATA] = conf.get(
|
|
269
|
+
adv_cst.SAVE_INTERMEDIATE_DATA, False
|
|
270
|
+
)
|
|
271
|
+
|
|
272
|
+
# Check geometry plugin and overwrite geomodel in conf inputs
|
|
273
|
+
(
|
|
274
|
+
inputs,
|
|
275
|
+
overloaded_conf[adv_cst.GEOMETRY_PLUGIN],
|
|
276
|
+
geom_plugin_without_dem_and_geoid,
|
|
277
|
+
geom_plugin_with_dem_and_geoid,
|
|
278
|
+
_,
|
|
279
|
+
) = sensor_inputs.check_geometry_plugin(
|
|
280
|
+
inputs,
|
|
281
|
+
conf.get(adv_cst.GEOMETRY_PLUGIN, None),
|
|
282
|
+
output_dem_dir,
|
|
283
|
+
)
|
|
284
|
+
|
|
285
|
+
# Validate inputs
|
|
286
|
+
schema = {
|
|
287
|
+
adv_cst.SAVE_INTERMEDIATE_DATA: Or(dict, bool),
|
|
288
|
+
adv_cst.GEOMETRY_PLUGIN: Or(str, dict),
|
|
289
|
+
"resampling_tile_width": int,
|
|
290
|
+
"resampling_tile_height": int,
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
checker_advanced_parameters = Checker(schema)
|
|
294
|
+
checker_advanced_parameters.validate(overloaded_conf)
|
|
295
|
+
|
|
296
|
+
return (
|
|
297
|
+
inputs,
|
|
298
|
+
overloaded_conf,
|
|
299
|
+
overloaded_conf[adv_cst.GEOMETRY_PLUGIN],
|
|
300
|
+
geom_plugin_without_dem_and_geoid,
|
|
301
|
+
geom_plugin_with_dem_and_geoid,
|
|
302
|
+
)
|
|
303
|
+
|
|
304
|
+
@staticmethod
|
|
305
|
+
def check_output(conf):
|
|
306
|
+
"""
|
|
307
|
+
Check the output given
|
|
308
|
+
|
|
309
|
+
:param conf: configuration of output
|
|
310
|
+
:type conf: dict
|
|
311
|
+
:return: overloader output
|
|
312
|
+
:rtype: dict
|
|
313
|
+
"""
|
|
314
|
+
overloaded_conf = conf.copy()
|
|
315
|
+
out_dir = conf[out_cst.OUT_DIRECTORY]
|
|
316
|
+
out_dir = os.path.abspath(out_dir)
|
|
317
|
+
# Ensure that output directory and its subdirectories exist
|
|
318
|
+
safe_makedirs(out_dir)
|
|
319
|
+
|
|
320
|
+
# Overload some parameters
|
|
321
|
+
overloaded_conf[out_cst.OUT_DIRECTORY] = out_dir
|
|
322
|
+
|
|
323
|
+
# Check schema
|
|
324
|
+
output_schema = {out_cst.OUT_DIRECTORY: str}
|
|
325
|
+
checker_output = Checker(output_schema)
|
|
326
|
+
checker_output.validate(overloaded_conf)
|
|
327
|
+
|
|
328
|
+
return overloaded_conf
|
|
329
|
+
|
|
330
|
+
def check_applications(self, conf):
|
|
331
|
+
"""
|
|
332
|
+
Check the given configuration for applications,
|
|
333
|
+
and generates needed applications for pipeline.
|
|
334
|
+
|
|
335
|
+
:param conf: configuration of applications
|
|
336
|
+
:type conf: dict
|
|
337
|
+
"""
|
|
338
|
+
|
|
339
|
+
# Initialize used config
|
|
340
|
+
used_conf = {}
|
|
341
|
+
|
|
342
|
+
needed_applications = [
|
|
343
|
+
"grid_generation",
|
|
344
|
+
"resampling",
|
|
345
|
+
"sparse_matching",
|
|
346
|
+
]
|
|
347
|
+
|
|
348
|
+
for app_key in needed_applications:
|
|
349
|
+
used_conf[app_key] = conf.get(app_key, {})
|
|
350
|
+
if used_conf[app_key] is not None:
|
|
351
|
+
used_conf[app_key]["save_intermediate_data"] = (
|
|
352
|
+
self.save_all_intermediate_data
|
|
353
|
+
or used_conf[app_key].get("save_intermediate_data", False)
|
|
354
|
+
)
|
|
355
|
+
|
|
356
|
+
# Epipolar grid generation
|
|
357
|
+
self.epipolar_grid_generation_application = Application(
|
|
358
|
+
"grid_generation",
|
|
359
|
+
cfg=used_conf.get("grid_generation", {}),
|
|
360
|
+
)
|
|
361
|
+
used_conf["grid_generation"] = (
|
|
362
|
+
self.epipolar_grid_generation_application.get_conf()
|
|
363
|
+
)
|
|
364
|
+
|
|
365
|
+
# Image resampling
|
|
366
|
+
self.resampling_application = Application(
|
|
367
|
+
"resampling",
|
|
368
|
+
cfg=used_conf.get("resampling", {}),
|
|
369
|
+
)
|
|
370
|
+
used_conf["resampling"] = self.resampling_application.get_conf()
|
|
371
|
+
|
|
372
|
+
# Sparse Matching
|
|
373
|
+
self.sparse_matching_app = Application(
|
|
374
|
+
"sparse_matching",
|
|
375
|
+
cfg=used_conf.get("sparse_matching", {}),
|
|
376
|
+
)
|
|
377
|
+
used_conf["sparse_matching"] = self.sparse_matching_app.get_conf()
|
|
378
|
+
|
|
379
|
+
return used_conf
|
|
380
|
+
|
|
381
|
+
def run(self, log_dir=None, disp_range_grid=None, cars_orchestrator=None):
|
|
382
|
+
"""
|
|
383
|
+
Run pipeline
|
|
384
|
+
|
|
385
|
+
"""
|
|
386
|
+
if log_dir is None:
|
|
387
|
+
log_dir = os.path.join(self.out_dir, "logs")
|
|
388
|
+
|
|
389
|
+
# Load geomodels directly on conf object
|
|
390
|
+
sensor_inputs.load_geomodels(
|
|
391
|
+
self.used_conf[INPUT], self.geom_plugin_without_dem_and_geoid
|
|
392
|
+
)
|
|
393
|
+
list_sensor_pairs = sensor_inputs.generate_pairs(self.used_conf[INPUT])
|
|
394
|
+
|
|
395
|
+
inherent_orchestrator = False
|
|
396
|
+
if cars_orchestrator is None:
|
|
397
|
+
cars_orchestrator = orchestrator.Orchestrator(
|
|
398
|
+
orchestrator_conf=self.used_conf[ORCHESTRATOR],
|
|
399
|
+
out_dir=self.out_dir,
|
|
400
|
+
log_dir=log_dir,
|
|
401
|
+
out_yaml_path=os.path.join(
|
|
402
|
+
self.out_dir,
|
|
403
|
+
out_cst.INFO_FILENAME,
|
|
404
|
+
),
|
|
405
|
+
)
|
|
406
|
+
inherent_orchestrator = True
|
|
407
|
+
|
|
408
|
+
# Run applications
|
|
409
|
+
|
|
410
|
+
# Run grid generation
|
|
411
|
+
# We generate grids with dem if it is provided.
|
|
412
|
+
if self.geom_plugin_with_dem_and_geoid.dem is None:
|
|
413
|
+
geom_plugin = self.geom_plugin_without_dem_and_geoid
|
|
414
|
+
else:
|
|
415
|
+
geom_plugin = self.geom_plugin_with_dem_and_geoid
|
|
416
|
+
|
|
417
|
+
for (
|
|
418
|
+
pair_key,
|
|
419
|
+
sensor_image_left,
|
|
420
|
+
sensor_image_right,
|
|
421
|
+
) in list_sensor_pairs:
|
|
422
|
+
|
|
423
|
+
if self.used_conf[INPUT][sens_cst.RECTIFICATION_GRIDS] is None:
|
|
424
|
+
# Generate rectification grids
|
|
425
|
+
(
|
|
426
|
+
grid_left,
|
|
427
|
+
grid_right,
|
|
428
|
+
) = self.epipolar_grid_generation_application.run(
|
|
429
|
+
sensor_image_left,
|
|
430
|
+
sensor_image_right,
|
|
431
|
+
geom_plugin,
|
|
432
|
+
orchestrator=cars_orchestrator,
|
|
433
|
+
pair_folder=os.path.join(
|
|
434
|
+
self.dump_dir,
|
|
435
|
+
"epipolar_grid_generation",
|
|
436
|
+
"initial",
|
|
437
|
+
pair_key,
|
|
438
|
+
),
|
|
439
|
+
pair_key=pair_key,
|
|
440
|
+
)
|
|
441
|
+
else:
|
|
442
|
+
image_keys = list(self.used_conf[INPUT][sens_cst.SENSORS])
|
|
443
|
+
grid_left = self.used_conf[INPUT][sens_cst.RECTIFICATION_GRIDS][
|
|
444
|
+
image_keys[0]
|
|
445
|
+
]
|
|
446
|
+
grid_right = self.used_conf[INPUT][
|
|
447
|
+
sens_cst.RECTIFICATION_GRIDS
|
|
448
|
+
][image_keys[1]]
|
|
449
|
+
|
|
450
|
+
# Get required bands of resampling
|
|
451
|
+
required_bands = self.sparse_matching_app.get_required_bands()
|
|
452
|
+
|
|
453
|
+
if disp_range_grid is not None:
|
|
454
|
+
tile_width = self.resampling_tile_width
|
|
455
|
+
tile_height = self.resampling_tile_height
|
|
456
|
+
margins_fun = self.sparse_matching_app.get_margins_tile_fun(
|
|
457
|
+
grid_left, disp_range_grid
|
|
458
|
+
)
|
|
459
|
+
|
|
460
|
+
disp_min = disp_range_grid["global_min"]
|
|
461
|
+
disp_max = disp_range_grid["global_max"]
|
|
462
|
+
logging.info(
|
|
463
|
+
"Global disparity range for sparse matching : "
|
|
464
|
+
"[{} pix, {} pix]".format(disp_min, disp_max)
|
|
465
|
+
)
|
|
466
|
+
|
|
467
|
+
disp_to_alt_ratio = grid_left["disp_to_alt_ratio"]
|
|
468
|
+
self.sparse_matching_app.elevation_delta_lower_bound = (
|
|
469
|
+
-disp_max * disp_to_alt_ratio
|
|
470
|
+
)
|
|
471
|
+
self.sparse_matching_app.elevation_delta_upper_bound = (
|
|
472
|
+
-disp_min * disp_to_alt_ratio
|
|
473
|
+
)
|
|
474
|
+
|
|
475
|
+
else:
|
|
476
|
+
|
|
477
|
+
tile_width = None
|
|
478
|
+
tile_height = None
|
|
479
|
+
margins_fun = self.sparse_matching_app.get_margins_strip_fun()
|
|
480
|
+
|
|
481
|
+
(
|
|
482
|
+
epipolar_image_left,
|
|
483
|
+
epipolar_image_right,
|
|
484
|
+
) = self.resampling_application.run(
|
|
485
|
+
sensor_image_left,
|
|
486
|
+
sensor_image_right,
|
|
487
|
+
grid_left,
|
|
488
|
+
grid_right,
|
|
489
|
+
geom_plugin,
|
|
490
|
+
orchestrator=cars_orchestrator,
|
|
491
|
+
pair_folder=os.path.join(
|
|
492
|
+
self.dump_dir, "resampling", "initial", pair_key
|
|
493
|
+
),
|
|
494
|
+
pair_key=pair_key,
|
|
495
|
+
margins_fun=margins_fun,
|
|
496
|
+
tile_width=tile_width,
|
|
497
|
+
tile_height=tile_height,
|
|
498
|
+
required_bands=required_bands,
|
|
499
|
+
)
|
|
500
|
+
|
|
501
|
+
# Compute sparse matching
|
|
502
|
+
(
|
|
503
|
+
epipolar_matches_left,
|
|
504
|
+
_,
|
|
505
|
+
) = self.sparse_matching_app.run(
|
|
506
|
+
epipolar_image_left,
|
|
507
|
+
epipolar_image_right,
|
|
508
|
+
grid_left["disp_to_alt_ratio"],
|
|
509
|
+
orchestrator=cars_orchestrator,
|
|
510
|
+
pair_folder=os.path.join(
|
|
511
|
+
self.dump_dir,
|
|
512
|
+
"sparse_matching",
|
|
513
|
+
pair_key,
|
|
514
|
+
),
|
|
515
|
+
pair_key=pair_key,
|
|
516
|
+
)
|
|
517
|
+
|
|
518
|
+
cars_orchestrator.breakpoint()
|
|
519
|
+
|
|
520
|
+
# Filter and save matches
|
|
521
|
+
_ = self.sparse_matching_app.filter_matches(
|
|
522
|
+
epipolar_matches_left,
|
|
523
|
+
grid_left,
|
|
524
|
+
grid_right,
|
|
525
|
+
geom_plugin,
|
|
526
|
+
orchestrator=cars_orchestrator,
|
|
527
|
+
pair_folder=os.path.join(
|
|
528
|
+
self.out_dir,
|
|
529
|
+
pair_key,
|
|
530
|
+
),
|
|
531
|
+
pair_key=pair_key,
|
|
532
|
+
save_matches=True,
|
|
533
|
+
)
|
|
534
|
+
|
|
535
|
+
if inherent_orchestrator:
|
|
536
|
+
cars_orchestrator.cleanup()
|