cars 1.0.0rc2__cp312-cp312-win_amd64.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.

Files changed (225) hide show
  1. cars/__init__.py +86 -0
  2. cars/applications/__init__.py +40 -0
  3. cars/applications/application.py +117 -0
  4. cars/applications/application_constants.py +29 -0
  5. cars/applications/application_template.py +146 -0
  6. cars/applications/auxiliary_filling/__init__.py +29 -0
  7. cars/applications/auxiliary_filling/abstract_auxiliary_filling_app.py +105 -0
  8. cars/applications/auxiliary_filling/auxiliary_filling_algo.py +475 -0
  9. cars/applications/auxiliary_filling/auxiliary_filling_from_sensors_app.py +632 -0
  10. cars/applications/auxiliary_filling/auxiliary_filling_wrappers.py +90 -0
  11. cars/applications/dem_generation/__init__.py +30 -0
  12. cars/applications/dem_generation/abstract_dem_generation_app.py +116 -0
  13. cars/applications/dem_generation/bulldozer_config/base_config.yaml +42 -0
  14. cars/applications/dem_generation/bulldozer_dem_app.py +641 -0
  15. cars/applications/dem_generation/bulldozer_memory.py +55 -0
  16. cars/applications/dem_generation/dem_generation_algo.py +107 -0
  17. cars/applications/dem_generation/dem_generation_constants.py +32 -0
  18. cars/applications/dem_generation/dem_generation_wrappers.py +323 -0
  19. cars/applications/dense_match_filling/__init__.py +30 -0
  20. cars/applications/dense_match_filling/abstract_dense_match_filling_app.py +242 -0
  21. cars/applications/dense_match_filling/fill_disp_algo.py +113 -0
  22. cars/applications/dense_match_filling/fill_disp_constants.py +39 -0
  23. cars/applications/dense_match_filling/fill_disp_wrappers.py +83 -0
  24. cars/applications/dense_match_filling/zero_padding_app.py +302 -0
  25. cars/applications/dense_matching/__init__.py +30 -0
  26. cars/applications/dense_matching/abstract_dense_matching_app.py +261 -0
  27. cars/applications/dense_matching/census_mccnn_sgm_app.py +1461 -0
  28. cars/applications/dense_matching/cpp/__init__.py +0 -0
  29. cars/applications/dense_matching/cpp/dense_matching_cpp.cp312-win_amd64.dll.a +0 -0
  30. cars/applications/dense_matching/cpp/dense_matching_cpp.cp312-win_amd64.pyd +0 -0
  31. cars/applications/dense_matching/cpp/dense_matching_cpp.py +94 -0
  32. cars/applications/dense_matching/cpp/includes/dense_matching.hpp +58 -0
  33. cars/applications/dense_matching/cpp/meson.build +9 -0
  34. cars/applications/dense_matching/cpp/src/bindings.cpp +13 -0
  35. cars/applications/dense_matching/cpp/src/dense_matching.cpp +207 -0
  36. cars/applications/dense_matching/dense_matching_algo.py +401 -0
  37. cars/applications/dense_matching/dense_matching_constants.py +89 -0
  38. cars/applications/dense_matching/dense_matching_wrappers.py +951 -0
  39. cars/applications/dense_matching/disparity_grid_algo.py +597 -0
  40. cars/applications/dense_matching/loaders/__init__.py +23 -0
  41. cars/applications/dense_matching/loaders/config_census_sgm_default.json +31 -0
  42. cars/applications/dense_matching/loaders/config_census_sgm_homogeneous.json +30 -0
  43. cars/applications/dense_matching/loaders/config_census_sgm_mountain_and_vegetation.json +30 -0
  44. cars/applications/dense_matching/loaders/config_census_sgm_shadow.json +30 -0
  45. cars/applications/dense_matching/loaders/config_census_sgm_sparse.json +36 -0
  46. cars/applications/dense_matching/loaders/config_census_sgm_urban.json +30 -0
  47. cars/applications/dense_matching/loaders/config_mapping.json +13 -0
  48. cars/applications/dense_matching/loaders/config_mccnn.json +28 -0
  49. cars/applications/dense_matching/loaders/global_land_cover_map.tif +0 -0
  50. cars/applications/dense_matching/loaders/pandora_loader.py +593 -0
  51. cars/applications/dsm_filling/__init__.py +32 -0
  52. cars/applications/dsm_filling/abstract_dsm_filling_app.py +101 -0
  53. cars/applications/dsm_filling/border_interpolation_app.py +278 -0
  54. cars/applications/dsm_filling/bulldozer_config/base_config.yaml +44 -0
  55. cars/applications/dsm_filling/bulldozer_filling_app.py +288 -0
  56. cars/applications/dsm_filling/exogenous_filling_app.py +341 -0
  57. cars/applications/dsm_merging/__init__.py +28 -0
  58. cars/applications/dsm_merging/abstract_dsm_merging_app.py +101 -0
  59. cars/applications/dsm_merging/weighted_fusion_app.py +639 -0
  60. cars/applications/grid_correction/__init__.py +30 -0
  61. cars/applications/grid_correction/abstract_grid_correction_app.py +103 -0
  62. cars/applications/grid_correction/grid_correction_app.py +557 -0
  63. cars/applications/grid_generation/__init__.py +30 -0
  64. cars/applications/grid_generation/abstract_grid_generation_app.py +142 -0
  65. cars/applications/grid_generation/epipolar_grid_generation_app.py +327 -0
  66. cars/applications/grid_generation/grid_generation_algo.py +388 -0
  67. cars/applications/grid_generation/grid_generation_constants.py +46 -0
  68. cars/applications/grid_generation/transform_grid.py +88 -0
  69. cars/applications/ground_truth_reprojection/__init__.py +30 -0
  70. cars/applications/ground_truth_reprojection/abstract_ground_truth_reprojection_app.py +137 -0
  71. cars/applications/ground_truth_reprojection/direct_localization_app.py +629 -0
  72. cars/applications/ground_truth_reprojection/ground_truth_reprojection_algo.py +275 -0
  73. cars/applications/point_cloud_outlier_removal/__init__.py +30 -0
  74. cars/applications/point_cloud_outlier_removal/abstract_outlier_removal_app.py +385 -0
  75. cars/applications/point_cloud_outlier_removal/outlier_removal_algo.py +392 -0
  76. cars/applications/point_cloud_outlier_removal/outlier_removal_constants.py +43 -0
  77. cars/applications/point_cloud_outlier_removal/small_components_app.py +522 -0
  78. cars/applications/point_cloud_outlier_removal/statistical_app.py +528 -0
  79. cars/applications/rasterization/__init__.py +30 -0
  80. cars/applications/rasterization/abstract_pc_rasterization_app.py +183 -0
  81. cars/applications/rasterization/rasterization_algo.py +534 -0
  82. cars/applications/rasterization/rasterization_constants.py +38 -0
  83. cars/applications/rasterization/rasterization_wrappers.py +639 -0
  84. cars/applications/rasterization/simple_gaussian_app.py +1152 -0
  85. cars/applications/resampling/__init__.py +28 -0
  86. cars/applications/resampling/abstract_resampling_app.py +187 -0
  87. cars/applications/resampling/bicubic_resampling_app.py +760 -0
  88. cars/applications/resampling/resampling_algo.py +590 -0
  89. cars/applications/resampling/resampling_constants.py +36 -0
  90. cars/applications/resampling/resampling_wrappers.py +309 -0
  91. cars/applications/sensors_subsampling/__init__.py +32 -0
  92. cars/applications/sensors_subsampling/abstract_subsampling_app.py +109 -0
  93. cars/applications/sensors_subsampling/rasterio_subsampling_app.py +420 -0
  94. cars/applications/sensors_subsampling/subsampling_algo.py +108 -0
  95. cars/applications/sparse_matching/__init__.py +30 -0
  96. cars/applications/sparse_matching/abstract_sparse_matching_app.py +599 -0
  97. cars/applications/sparse_matching/sift_app.py +724 -0
  98. cars/applications/sparse_matching/sparse_matching_algo.py +360 -0
  99. cars/applications/sparse_matching/sparse_matching_constants.py +66 -0
  100. cars/applications/sparse_matching/sparse_matching_wrappers.py +282 -0
  101. cars/applications/triangulation/__init__.py +32 -0
  102. cars/applications/triangulation/abstract_triangulation_app.py +227 -0
  103. cars/applications/triangulation/line_of_sight_intersection_app.py +1243 -0
  104. cars/applications/triangulation/pc_transform.py +552 -0
  105. cars/applications/triangulation/triangulation_algo.py +371 -0
  106. cars/applications/triangulation/triangulation_constants.py +38 -0
  107. cars/applications/triangulation/triangulation_wrappers.py +259 -0
  108. cars/bundleadjustment.py +750 -0
  109. cars/cars.py +179 -0
  110. cars/conf/__init__.py +23 -0
  111. cars/conf/geoid/egm96.grd +0 -0
  112. cars/conf/geoid/egm96.grd.hdr +15 -0
  113. cars/conf/input_parameters.py +156 -0
  114. cars/conf/mask_cst.py +35 -0
  115. cars/core/__init__.py +23 -0
  116. cars/core/cars_logging.py +402 -0
  117. cars/core/constants.py +191 -0
  118. cars/core/constants_disparity.py +50 -0
  119. cars/core/datasets.py +140 -0
  120. cars/core/geometry/__init__.py +27 -0
  121. cars/core/geometry/abstract_geometry.py +1119 -0
  122. cars/core/geometry/shareloc_geometry.py +598 -0
  123. cars/core/inputs.py +568 -0
  124. cars/core/outputs.py +176 -0
  125. cars/core/preprocessing.py +722 -0
  126. cars/core/projection.py +843 -0
  127. cars/core/roi_tools.py +215 -0
  128. cars/core/tiling.py +774 -0
  129. cars/core/utils.py +164 -0
  130. cars/data_structures/__init__.py +23 -0
  131. cars/data_structures/cars_dataset.py +1544 -0
  132. cars/data_structures/cars_dict.py +74 -0
  133. cars/data_structures/corresponding_tiles_tools.py +186 -0
  134. cars/data_structures/dataframe_converter.py +185 -0
  135. cars/data_structures/format_transformation.py +297 -0
  136. cars/devibrate.py +689 -0
  137. cars/extractroi.py +264 -0
  138. cars/orchestrator/__init__.py +23 -0
  139. cars/orchestrator/achievement_tracker.py +125 -0
  140. cars/orchestrator/cluster/__init__.py +37 -0
  141. cars/orchestrator/cluster/abstract_cluster.py +250 -0
  142. cars/orchestrator/cluster/abstract_dask_cluster.py +381 -0
  143. cars/orchestrator/cluster/dask_cluster_tools.py +103 -0
  144. cars/orchestrator/cluster/dask_config/README.md +94 -0
  145. cars/orchestrator/cluster/dask_config/dask.yaml +21 -0
  146. cars/orchestrator/cluster/dask_config/distributed.yaml +70 -0
  147. cars/orchestrator/cluster/dask_config/jobqueue.yaml +26 -0
  148. cars/orchestrator/cluster/dask_config/reference_confs/dask-schema.yaml +137 -0
  149. cars/orchestrator/cluster/dask_config/reference_confs/dask.yaml +26 -0
  150. cars/orchestrator/cluster/dask_config/reference_confs/distributed-schema.yaml +1009 -0
  151. cars/orchestrator/cluster/dask_config/reference_confs/distributed.yaml +273 -0
  152. cars/orchestrator/cluster/dask_config/reference_confs/jobqueue.yaml +212 -0
  153. cars/orchestrator/cluster/dask_jobqueue_utils.py +204 -0
  154. cars/orchestrator/cluster/local_dask_cluster.py +116 -0
  155. cars/orchestrator/cluster/log_wrapper.py +728 -0
  156. cars/orchestrator/cluster/mp_cluster/__init__.py +27 -0
  157. cars/orchestrator/cluster/mp_cluster/mp_factorizer.py +212 -0
  158. cars/orchestrator/cluster/mp_cluster/mp_objects.py +535 -0
  159. cars/orchestrator/cluster/mp_cluster/mp_tools.py +93 -0
  160. cars/orchestrator/cluster/mp_cluster/mp_wrapper.py +505 -0
  161. cars/orchestrator/cluster/mp_cluster/multiprocessing_cluster.py +986 -0
  162. cars/orchestrator/cluster/mp_cluster/multiprocessing_profiler.py +399 -0
  163. cars/orchestrator/cluster/pbs_dask_cluster.py +207 -0
  164. cars/orchestrator/cluster/sequential_cluster.py +139 -0
  165. cars/orchestrator/cluster/slurm_dask_cluster.py +234 -0
  166. cars/orchestrator/memory_tools.py +47 -0
  167. cars/orchestrator/orchestrator.py +755 -0
  168. cars/orchestrator/orchestrator_constants.py +29 -0
  169. cars/orchestrator/registry/__init__.py +23 -0
  170. cars/orchestrator/registry/abstract_registry.py +143 -0
  171. cars/orchestrator/registry/compute_registry.py +106 -0
  172. cars/orchestrator/registry/id_generator.py +116 -0
  173. cars/orchestrator/registry/replacer_registry.py +213 -0
  174. cars/orchestrator/registry/saver_registry.py +363 -0
  175. cars/orchestrator/registry/unseen_registry.py +118 -0
  176. cars/orchestrator/tiles_profiler.py +279 -0
  177. cars/pipelines/__init__.py +26 -0
  178. cars/pipelines/conf_resolution/conf_final_resolution.yaml +5 -0
  179. cars/pipelines/conf_resolution/conf_first_resolution.yaml +4 -0
  180. cars/pipelines/conf_resolution/conf_intermediate_resolution.yaml +2 -0
  181. cars/pipelines/default/__init__.py +26 -0
  182. cars/pipelines/default/default_pipeline.py +1088 -0
  183. cars/pipelines/filling/__init__.py +26 -0
  184. cars/pipelines/filling/filling.py +981 -0
  185. cars/pipelines/formatting/__init__.py +26 -0
  186. cars/pipelines/formatting/formatting.py +186 -0
  187. cars/pipelines/merging/__init__.py +26 -0
  188. cars/pipelines/merging/merging.py +439 -0
  189. cars/pipelines/parameters/__init__.py +0 -0
  190. cars/pipelines/parameters/advanced_parameters.py +256 -0
  191. cars/pipelines/parameters/advanced_parameters_constants.py +68 -0
  192. cars/pipelines/parameters/application_parameters.py +72 -0
  193. cars/pipelines/parameters/depth_map_inputs.py +0 -0
  194. cars/pipelines/parameters/dsm_inputs.py +349 -0
  195. cars/pipelines/parameters/dsm_inputs_constants.py +25 -0
  196. cars/pipelines/parameters/output_constants.py +52 -0
  197. cars/pipelines/parameters/output_parameters.py +438 -0
  198. cars/pipelines/parameters/sensor_inputs.py +859 -0
  199. cars/pipelines/parameters/sensor_inputs_constants.py +51 -0
  200. cars/pipelines/parameters/sensor_loaders/__init__.py +29 -0
  201. cars/pipelines/parameters/sensor_loaders/basic_classif_loader.py +86 -0
  202. cars/pipelines/parameters/sensor_loaders/basic_image_loader.py +98 -0
  203. cars/pipelines/parameters/sensor_loaders/pivot_classif_loader.py +90 -0
  204. cars/pipelines/parameters/sensor_loaders/pivot_image_loader.py +105 -0
  205. cars/pipelines/parameters/sensor_loaders/sensor_loader.py +93 -0
  206. cars/pipelines/parameters/sensor_loaders/sensor_loader_template.py +71 -0
  207. cars/pipelines/parameters/sensor_loaders/slurp_classif_loader.py +86 -0
  208. cars/pipelines/pipeline.py +119 -0
  209. cars/pipelines/pipeline_constants.py +38 -0
  210. cars/pipelines/pipeline_template.py +135 -0
  211. cars/pipelines/subsampling/__init__.py +26 -0
  212. cars/pipelines/subsampling/subsampling.py +358 -0
  213. cars/pipelines/surface_modeling/__init__.py +26 -0
  214. cars/pipelines/surface_modeling/surface_modeling.py +2098 -0
  215. cars/pipelines/tie_points/__init__.py +26 -0
  216. cars/pipelines/tie_points/tie_points.py +536 -0
  217. cars/starter.py +167 -0
  218. cars-1.0.0rc2.dist-info/DELVEWHEEL +2 -0
  219. cars-1.0.0rc2.dist-info/METADATA +289 -0
  220. cars-1.0.0rc2.dist-info/RECORD +225 -0
  221. cars-1.0.0rc2.dist-info/WHEEL +4 -0
  222. cars-1.0.0rc2.dist-info/entry_points.txt +8 -0
  223. cars.libs/libgcc_s_seh-1-b2494fcbd4d80cf2c98fdd5261f6d850.dll +0 -0
  224. cars.libs/libstdc++-6-e9b0d12ae0e9555bbae55e8dfd08c3f7.dll +0 -0
  225. cars.libs/libwinpthread-1-7882d1b093714ccdfaf4e0789a817792.dll +0 -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()