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,760 @@
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
+ this module contains the bicubic_resampling application class.
23
+ """
24
+ # pylint: disable=too-many-lines
25
+ # TODO refacto: factorize disributed code, and remove too-many-lines
26
+
27
+ # Standard imports
28
+ import logging
29
+ import os
30
+ from typing import Dict, Tuple
31
+
32
+ # Third party imports
33
+ import numpy as np
34
+ import xarray as xr
35
+ from json_checker import And, Checker, Or
36
+ from shapely.geometry import Polygon
37
+
38
+ # CARS imports
39
+ import cars.orchestrator.orchestrator as ocht
40
+ from cars.applications import application_constants
41
+ from cars.applications.resampling import (
42
+ resampling_algo,
43
+ resampling_constants,
44
+ resampling_wrappers,
45
+ )
46
+ from cars.applications.resampling.abstract_resampling_app import Resampling
47
+ from cars.core import constants as cst
48
+ from cars.core import inputs, tiling
49
+ from cars.core.utils import safe_makedirs
50
+ from cars.data_structures import cars_dataset, format_transformation
51
+ from cars.data_structures.cars_dict import CarsDict
52
+ from cars.pipelines.parameters import sensor_inputs_constants as sens_cst
53
+
54
+
55
+ class BicubicResampling(Resampling, short_name="bicubic"):
56
+ """
57
+ BicubicResampling
58
+ """
59
+
60
+ # pylint: disable=too-many-instance-attributes
61
+
62
+ def __init__(self, conf=None):
63
+ """
64
+ Init function of BicubicResampling
65
+
66
+ :param conf: configuration for resampling
67
+ :return: an application_to_use object
68
+ """
69
+ super().__init__(conf=conf)
70
+
71
+ # check conf
72
+ self.used_method = self.used_config["method"]
73
+ self.strip_height = self.used_config["strip_height"]
74
+ self.step = self.used_config["step"]
75
+
76
+ # Saving bools
77
+ self.save_intermediate_data = self.used_config["save_intermediate_data"]
78
+
79
+ self.interpolator_image = self.used_config["interpolator_image"]
80
+ self.interpolator_classif = self.used_config["interpolator_classif"]
81
+ self.interpolator_mask = self.used_config["interpolator_mask"]
82
+
83
+ # Init orchestrator
84
+ self.orchestrator = None
85
+
86
+ def check_conf(self, conf):
87
+ """
88
+ Check configuration
89
+
90
+ :param conf: configuration to check
91
+ :type conf: dict
92
+
93
+ :return: overloaded configuration
94
+ :rtype: dict
95
+
96
+ """
97
+
98
+ # init conf
99
+ if conf is not None:
100
+ overloaded_conf = conf.copy()
101
+ else:
102
+ conf = {}
103
+ overloaded_conf = {}
104
+
105
+ # Overload conf
106
+
107
+ # get rasterization parameter
108
+ overloaded_conf["method"] = conf.get("method", "bicubic")
109
+ overloaded_conf["strip_height"] = conf.get("strip_height", 60)
110
+ overloaded_conf["interpolator_image"] = conf.get(
111
+ "interpolator_image", "bicubic"
112
+ )
113
+ overloaded_conf["interpolator_classif"] = conf.get(
114
+ "interpolator_classif", "nearest"
115
+ )
116
+ overloaded_conf["interpolator_mask"] = conf.get(
117
+ "interpolator_mask", "nearest"
118
+ )
119
+ overloaded_conf["step"] = conf.get("step", 500)
120
+
121
+ # Saving bools
122
+ overloaded_conf["save_intermediate_data"] = conf.get(
123
+ "save_intermediate_data", False
124
+ )
125
+
126
+ rectification_schema = {
127
+ "method": str,
128
+ "strip_height": And(int, lambda x: x > 0),
129
+ "interpolator_image": str,
130
+ "interpolator_classif": str,
131
+ "interpolator_mask": str,
132
+ "step": Or(None, int),
133
+ "save_intermediate_data": bool,
134
+ }
135
+
136
+ # Check conf
137
+ checker = Checker(rectification_schema)
138
+ checker.validate(overloaded_conf)
139
+
140
+ return overloaded_conf
141
+
142
+ def pre_run(
143
+ self,
144
+ grid_left,
145
+ tile_width,
146
+ tile_height,
147
+ ):
148
+ """
149
+ Pre run some computations : tiling grid
150
+
151
+ :param grid_left: left grid
152
+ :type grid_left: dict
153
+ :param optimum_tile_size: optimum tile size
154
+ :type optimum_tile_size: int
155
+
156
+
157
+ :return: epipolar_regions_grid, epipolar_regions,
158
+ opt_epipolar_tile_size, largest_epipolar_region,
159
+ """
160
+
161
+ # Get largest epipolar regions from configuration file
162
+ largest_epipolar_region = [
163
+ 0,
164
+ 0,
165
+ grid_left["epipolar_size_x"],
166
+ grid_left["epipolar_size_y"],
167
+ ]
168
+
169
+ origin = grid_left["grid_origin"]
170
+ spacing = grid_left["grid_spacing"]
171
+
172
+ logging.info(
173
+ "Size of epipolar image: {}".format(largest_epipolar_region)
174
+ )
175
+ logging.debug("Origin of epipolar grid: {}".format(origin))
176
+ logging.debug("Spacing of epipolar grid: {}".format(spacing))
177
+
178
+ if tile_width is None:
179
+ tile_width = grid_left["epipolar_size_x"]
180
+ if tile_height is None:
181
+ tile_height = self.strip_height
182
+
183
+ logging.info(
184
+ "Tile size for epipolar regions: "
185
+ "{width}x{height} pixels".format(
186
+ width=tile_width, height=tile_height
187
+ )
188
+ )
189
+
190
+ epipolar_regions_grid = tiling.generate_tiling_grid(
191
+ 0,
192
+ 0,
193
+ grid_left["epipolar_size_y"],
194
+ grid_left["epipolar_size_x"],
195
+ tile_height,
196
+ tile_width,
197
+ )
198
+
199
+ logging.info(
200
+ "Epipolar image will be processed in {} splits".format(
201
+ epipolar_regions_grid.shape[0] * epipolar_regions_grid.shape[1]
202
+ )
203
+ )
204
+
205
+ return (
206
+ epipolar_regions_grid,
207
+ tile_width,
208
+ tile_height,
209
+ largest_epipolar_region,
210
+ )
211
+
212
+ def run( # pylint: disable=too-many-positional-arguments # noqa: C901
213
+ self,
214
+ sensor_image_left,
215
+ sensor_image_right,
216
+ grid_left,
217
+ grid_right,
218
+ geom_plugin,
219
+ orchestrator=None,
220
+ pair_folder=None,
221
+ pair_key="PAIR_0",
222
+ margins_fun=None,
223
+ tile_width=None,
224
+ tile_height=None,
225
+ add_classif=True,
226
+ epipolar_roi=None,
227
+ required_bands=None,
228
+ texture_bands=None,
229
+ ):
230
+ """
231
+ Run resampling application.
232
+
233
+ Creates left and right CarsDataset filled with xarray.Dataset,
234
+ corresponding to sensor images resampled in epipolar geometry.
235
+
236
+ :param sensor_images_left: tiled sensor left image
237
+ Dict Must contain keys : "image", "geomodel",
238
+ "no_data", "mask", "classification". Paths must be absolutes
239
+ :type sensor_images_left: CarsDataset
240
+ :param sensor_images_right: tiled sensor right image
241
+ Dict Must contain keys : "image", "geomodel",
242
+ "no_data", "mask", "classification". Paths must be absolutes
243
+ :type sensor_images_right: CarsDataset
244
+ :param grid_left: left epipolar grid
245
+ Grid dict contains :
246
+ - "grid_spacing", "grid_origin", \
247
+ "epipolar_size_x", "epipolar_size_y", "epipolar_origin_x",\
248
+ "epipolar_origin_y", epipolar_spacing_x",\
249
+ "epipolar_spacing", "disp_to_alt_ratio", "path"
250
+ :type grid_left: dict
251
+ :param grid_right: right epipolar grid. Grid dict contains :
252
+ - "grid_spacing", "grid_origin",\
253
+ "epipolar_size_x", "epipolar_size_y", "epipolar_origin_x",\
254
+ "epipolar_origin_y", epipolar_spacing_x",\
255
+ "epipolar_spacing", "disp_to_alt_ratio", "path"
256
+ :type grid_right: dict
257
+ :param orchestrator: orchestrator used
258
+ :param pair_folder: folder used for current pair
259
+ :type pair_folder: directory to save files to
260
+ :param pair_key: pair id
261
+ :type pair_key: str
262
+ :param margins_fun: margins function to use
263
+ :type margins_fun: fun
264
+ :param optimum_tile_size: optimum tile size to use
265
+ :type optimum_tile_size: int
266
+ :param tile_width: width of tile
267
+ :type tile_width: int
268
+ :param tile_height: height of tile
269
+ :type tile_height: int
270
+ :param add_classif: add classif to dataset
271
+ :type add_classif: bool
272
+ :param epipolar_roi: Epipolar roi to use if set.
273
+ Set None tiles outsize roi
274
+ :type epipolar_roi: list(int), [row_min, row_max, col_min, col_max]
275
+ :param required_bands: bands to resample on left and right image
276
+ :type required_bands: dict
277
+ :param texture_bands: name of bands used for output texture
278
+ :type texture_bands: list
279
+
280
+ :return: left epipolar image, right epipolar image. \
281
+ Each CarsDataset contains:
282
+
283
+ - N x M Delayed tiles. \
284
+ Each tile will be a future xarray Dataset containing:
285
+
286
+ - data with keys : "im", "msk", "classif"
287
+ - attrs with keys: "margins" with "disp_min" and "disp_max"\
288
+ "transform", "crs", "valid_pixels", "no_data_mask",
289
+ "no_data_img"
290
+ - attributes containing: \
291
+ "largest_epipolar_region","opt_epipolar_tile_size",
292
+ "disp_min_tiling", "disp_max_tiling"
293
+
294
+ :rtype: Tuple(CarsDataset, CarsDataset)
295
+ """
296
+
297
+ # Default orchestrator
298
+ if orchestrator is None:
299
+ # Create default sequential orchestrator for current application
300
+ # be aware, no out_json will be shared between orchestrators
301
+ # No files saved
302
+ self.orchestrator = ocht.Orchestrator(
303
+ orchestrator_conf={"mode": "sequential"}
304
+ )
305
+ else:
306
+ self.orchestrator = orchestrator
307
+
308
+ if pair_folder is None:
309
+ pair_folder = os.path.join(self.orchestrator.out_dir, "tmp")
310
+
311
+ # Create zeros margins if not provided
312
+ if margins_fun is None:
313
+
314
+ def margins_fun( # pylint: disable=unused-argument
315
+ row_min, row_max, col_min, col_max
316
+ ):
317
+ """
318
+ Default margin function, returning zeros
319
+ """
320
+ corner = ["left", "up", "right", "down"]
321
+ data = np.zeros(len(corner))
322
+ col = np.arange(len(corner))
323
+ margins = xr.Dataset(
324
+ {"left_margin": (["col"], data)}, coords={"col": col}
325
+ )
326
+ margins["right_margin"] = xr.DataArray(data, dims=["col"])
327
+ return margins
328
+
329
+ # Get grids and regions for current pair
330
+ (
331
+ epipolar_regions_grid,
332
+ tile_width,
333
+ tile_height,
334
+ largest_epipolar_region,
335
+ ) = self.pre_run(
336
+ grid_left,
337
+ tile_width,
338
+ tile_height,
339
+ )
340
+
341
+ # Create CarsDataset
342
+ # Epipolar_images
343
+ epipolar_images_left = cars_dataset.CarsDataset(
344
+ "arrays", name="resampling_left_" + pair_key
345
+ )
346
+ epipolar_images_right = cars_dataset.CarsDataset(
347
+ "arrays", name="resampling_" + pair_key
348
+ )
349
+
350
+ # Compute tiling grid
351
+ epipolar_images_left.tiling_grid = epipolar_regions_grid
352
+
353
+ # Generate tiling grid
354
+ epipolar_images_right.tiling_grid = epipolar_regions_grid
355
+
356
+ # Compute overlaps
357
+ (
358
+ epipolar_images_left.overlaps,
359
+ epipolar_images_right.overlaps,
360
+ used_disp_min,
361
+ used_disp_max,
362
+ ) = format_transformation.grid_margins_2_overlaps(
363
+ epipolar_images_left.tiling_grid, margins_fun
364
+ )
365
+
366
+ # add image type in attributes for future checking
367
+ if texture_bands is not None:
368
+ im_type = inputs.rasterio_get_image_type(
369
+ sensor_image_left[sens_cst.INPUT_IMG]["bands"][
370
+ texture_bands[0]
371
+ ]["path"]
372
+ )
373
+ else:
374
+ im_type = inputs.rasterio_get_image_type(
375
+ sensor_image_left[sens_cst.INPUT_IMG]["bands"]["b0"]["path"]
376
+ )
377
+
378
+ # update attributes
379
+ epipolar_images_attributes = {
380
+ "largest_epipolar_region": largest_epipolar_region,
381
+ "tile_width": tile_width,
382
+ "tile_height": tile_height,
383
+ "disp_min_tiling": used_disp_min,
384
+ "disp_max_tiling": used_disp_max,
385
+ "image_type": im_type,
386
+ }
387
+
388
+ epipolar_images_left.attributes.update(epipolar_images_attributes)
389
+ epipolar_images_right.attributes.update(epipolar_images_attributes)
390
+
391
+ # Save objects
392
+ if self.save_intermediate_data:
393
+ safe_makedirs(pair_folder)
394
+
395
+ self.orchestrator.add_to_save_lists(
396
+ os.path.join(pair_folder, "epi_img_left.tif"),
397
+ cst.EPI_IMAGE,
398
+ epipolar_images_left,
399
+ cars_ds_name="epi_img_left",
400
+ )
401
+ self.orchestrator.add_to_save_lists(
402
+ os.path.join(pair_folder, "epi_img_right.tif"),
403
+ cst.EPI_IMAGE,
404
+ epipolar_images_right,
405
+ cars_ds_name="epi_img_right",
406
+ )
407
+
408
+ self.orchestrator.add_to_save_lists(
409
+ os.path.join(pair_folder, "epi_img_left_mask.tif"),
410
+ cst.EPI_MSK,
411
+ epipolar_images_left,
412
+ cars_ds_name="epi_img_left_mask",
413
+ dtype=np.uint8,
414
+ )
415
+
416
+ self.orchestrator.add_to_save_lists(
417
+ os.path.join(pair_folder, "epi_img_right_mask.tif"),
418
+ cst.EPI_MSK,
419
+ epipolar_images_right,
420
+ cars_ds_name="epi_img_right_mask",
421
+ dtype=np.uint8,
422
+ )
423
+
424
+ if self.save_intermediate_data and add_classif:
425
+ self.orchestrator.add_to_save_lists(
426
+ os.path.join(pair_folder, "epi_img_left_classif.tif"),
427
+ cst.EPI_CLASSIFICATION,
428
+ epipolar_images_left,
429
+ cars_ds_name="epi_img_left_classif",
430
+ dtype=np.uint8,
431
+ optional_data=True,
432
+ )
433
+
434
+ self.orchestrator.add_to_save_lists(
435
+ os.path.join(pair_folder, "epi_img_right_classif.tif"),
436
+ cst.EPI_CLASSIFICATION,
437
+ epipolar_images_right,
438
+ cars_ds_name="epi_img_right_classif",
439
+ dtype=np.uint8,
440
+ optional_data=True,
441
+ )
442
+
443
+ # Get saving infos in order to save tiles when they are computed
444
+ [
445
+ saving_info_left,
446
+ saving_info_right,
447
+ ] = self.orchestrator.get_saving_infos(
448
+ [epipolar_images_left, epipolar_images_right]
449
+ )
450
+
451
+ logging.info(
452
+ "Number of tiles in epipolar resampling: "
453
+ "row: {} "
454
+ "col: {}".format(
455
+ epipolar_images_left.tiling_grid.shape[0],
456
+ epipolar_images_left.tiling_grid.shape[1],
457
+ )
458
+ )
459
+
460
+ # Add infos to orchestrator.out_json
461
+ updating_dict = {
462
+ application_constants.APPLICATION_TAG: {
463
+ resampling_constants.RESAMPLING_RUN_TAG: {
464
+ pair_key: {resampling_constants.METHOD: self.used_method},
465
+ }
466
+ }
467
+ }
468
+ self.orchestrator.update_out_info(updating_dict)
469
+
470
+ # retrieve data
471
+ epipolar_size_x = grid_left["epipolar_size_x"]
472
+ epipolar_size_y = grid_left["epipolar_size_y"]
473
+ left_images = resampling_wrappers.get_paths_and_bands_from_image(
474
+ sensor_image_left[sens_cst.INPUT_IMG],
475
+ required_bands["left"],
476
+ )
477
+ right_images = resampling_wrappers.get_paths_and_bands_from_image(
478
+ sensor_image_right[sens_cst.INPUT_IMG],
479
+ required_bands["right"],
480
+ )
481
+ grid1 = grid_left
482
+ grid2 = grid_right
483
+ nodata1 = sensor_image_left[sens_cst.INPUT_IMG].get(
484
+ sens_cst.INPUT_NODATA, None
485
+ )
486
+ nodata2 = sensor_image_right[sens_cst.INPUT_IMG].get(
487
+ sens_cst.INPUT_NODATA, None
488
+ )
489
+ mask1 = sensor_image_left.get(sens_cst.INPUT_MSK, None)
490
+ mask2 = sensor_image_right.get(sens_cst.INPUT_MSK, None)
491
+ left_classifs = sensor_image_left.get(
492
+ sens_cst.INPUT_CLASSIFICATION, None
493
+ )
494
+ if left_classifs is not None:
495
+ left_classifs = (
496
+ resampling_wrappers.get_path_and_values_from_classif(
497
+ left_classifs
498
+ )
499
+ )
500
+ right_classifs = sensor_image_right.get(
501
+ sens_cst.INPUT_CLASSIFICATION, None
502
+ )
503
+ if right_classifs is not None:
504
+ right_classifs = (
505
+ resampling_wrappers.get_path_and_values_from_classif(
506
+ right_classifs
507
+ )
508
+ )
509
+
510
+ # Set Epipolar roi
511
+ epi_tilling_grid = epipolar_images_left.tiling_grid
512
+ if epipolar_roi is None:
513
+ epipolar_roi = [
514
+ np.min(epi_tilling_grid[:, :, 0]),
515
+ np.max(epi_tilling_grid[:, :, 1]),
516
+ np.min(epi_tilling_grid[:, :, 2]),
517
+ np.max(epi_tilling_grid[:, :, 3]),
518
+ ]
519
+ # Convert roi to polygon
520
+ epipolar_roi_poly = Polygon(
521
+ [
522
+ [epipolar_roi[0], epipolar_roi[2]],
523
+ [epipolar_roi[0], epipolar_roi[3]],
524
+ [epipolar_roi[1], epipolar_roi[3]],
525
+ [epipolar_roi[1], epipolar_roi[2]],
526
+ [epipolar_roi[0], epipolar_roi[2]],
527
+ ]
528
+ )
529
+
530
+ # Check if tiles are in sensors
531
+ in_sensor_left_array, in_sensor_right_array = (
532
+ resampling_wrappers.check_tiles_in_sensor(
533
+ sensor_image_left,
534
+ sensor_image_right,
535
+ epi_tilling_grid,
536
+ grid_left,
537
+ grid_right,
538
+ geom_plugin,
539
+ )
540
+ )
541
+
542
+ # broadcast grids
543
+ # Transform grids to CarsDict for broadcasting
544
+ # due to Dask issue https://github.com/dask/dask/issues/9969
545
+ broadcasted_grid1 = self.orchestrator.cluster.scatter(CarsDict(grid1))
546
+ broadcasted_grid2 = self.orchestrator.cluster.scatter(CarsDict(grid2))
547
+
548
+ # Generate Image pair
549
+ for col in range(epipolar_images_left.shape[1]):
550
+ for row in range(epipolar_images_left.shape[0]):
551
+ # Create polygon corresponding to tile
552
+ tile = epi_tilling_grid[row, col]
553
+ tile_roi_poly = Polygon(
554
+ [
555
+ [tile[0], tile[2]],
556
+ [tile[0], tile[3]],
557
+ [tile[1], tile[3]],
558
+ [tile[1], tile[2]],
559
+ [tile[0], tile[2]],
560
+ ]
561
+ )
562
+
563
+ if epipolar_roi_poly.intersects(tile_roi_poly) and (
564
+ in_sensor_left_array[row, col]
565
+ or in_sensor_right_array[row, col]
566
+ ):
567
+ # get overlaps
568
+ left_overlap = cars_dataset.overlap_array_to_dict(
569
+ epipolar_images_left.overlaps[row, col]
570
+ )
571
+ right_overlap = cars_dataset.overlap_array_to_dict(
572
+ epipolar_images_right.overlaps[row, col]
573
+ )
574
+ # get window
575
+ left_window = epipolar_images_left.get_window_as_dict(
576
+ row, col
577
+ )
578
+
579
+ # update saving infos for potential replacement
580
+ full_saving_info_left = ocht.update_saving_infos(
581
+ saving_info_left, row=row, col=col
582
+ )
583
+ full_saving_info_right = ocht.update_saving_infos(
584
+ saving_info_right, row=row, col=col
585
+ )
586
+
587
+ # Compute images
588
+ (
589
+ epipolar_images_left[row, col],
590
+ epipolar_images_right[row, col],
591
+ ) = self.orchestrator.cluster.create_task(
592
+ generate_epipolar_images_wrapper, nout=2
593
+ )(
594
+ left_overlap,
595
+ right_overlap,
596
+ left_window,
597
+ epipolar_size_x,
598
+ epipolar_size_y,
599
+ left_images,
600
+ right_images,
601
+ broadcasted_grid1,
602
+ broadcasted_grid2,
603
+ self.interpolator_image,
604
+ self.interpolator_classif,
605
+ self.interpolator_mask,
606
+ self.step,
607
+ used_disp_min=used_disp_min[row, col],
608
+ used_disp_max=used_disp_max[row, col],
609
+ add_classif=add_classif,
610
+ mask1=mask1,
611
+ mask2=mask2,
612
+ left_classifs=left_classifs,
613
+ right_classifs=right_classifs,
614
+ nodata1=nodata1,
615
+ nodata2=nodata2,
616
+ saving_info_left=full_saving_info_left,
617
+ saving_info_right=full_saving_info_right,
618
+ )
619
+
620
+ # Remove tile with all nan
621
+ if not in_sensor_left_array[row, col]:
622
+ epipolar_images_left[row, col] = None
623
+ if not in_sensor_right_array[row, col]:
624
+ epipolar_images_right[row, col] = None
625
+
626
+ return epipolar_images_left, epipolar_images_right
627
+
628
+
629
+ # pylint: disable=too-many-positional-arguments
630
+ def generate_epipolar_images_wrapper(
631
+ left_overlaps,
632
+ right_overlaps,
633
+ window,
634
+ epipolar_size_x,
635
+ epipolar_size_y,
636
+ left_imgs,
637
+ right_imgs,
638
+ grid1,
639
+ grid2,
640
+ interpolator_image,
641
+ interpolator_classif,
642
+ interpolator_mask,
643
+ step=None,
644
+ used_disp_min=None,
645
+ used_disp_max=None,
646
+ add_classif=True,
647
+ mask1=None,
648
+ mask2=None,
649
+ left_classifs=None,
650
+ right_classifs=None,
651
+ nodata1=0,
652
+ nodata2=0,
653
+ saving_info_left=None,
654
+ saving_info_right=None,
655
+ ) -> Dict[str, Tuple[xr.Dataset, xr.Dataset]]:
656
+ """
657
+ Compute disparity maps from image objects. This function will be run
658
+ as a delayed task. If user want to correctly save dataset, the user must
659
+ provide saving_info_left and right. See cars_dataset.fill_dataset.
660
+
661
+
662
+ :param left_overlaps: Overlaps of left image, with row_min, row_max,
663
+ col_min and col_max keys.
664
+ :type left_overlaps: dict
665
+ :param right_overlaps: Overlaps of right image, with row_min, row_max,
666
+ col_min and col_max keys.
667
+ :type right_overlaps: dict
668
+ :param window: Window considered in generation, with row_min, row_max,
669
+ col_min and col_max keys.
670
+ :type window: dict
671
+
672
+ :return: Left image object, Right image object (if exists)
673
+
674
+ Returned objects are composed of dataset with :
675
+
676
+ - cst.EPI_IMAGE
677
+ - cst.EPI_MSK (if given)
678
+ - cst.EPI_TEXTURE (for left, if given)
679
+ """
680
+ # Transform CarsDict back to dict
681
+ grid1 = grid1.data
682
+ grid2 = grid2.data
683
+
684
+ region, margins = format_transformation.region_margins_from_window(
685
+ window,
686
+ left_overlaps,
687
+ right_overlaps,
688
+ used_disp_min=used_disp_min,
689
+ used_disp_max=used_disp_max,
690
+ )
691
+ # Rectify images
692
+ (
693
+ left_dataset,
694
+ right_dataset,
695
+ left_classif_dataset,
696
+ right_classif_dataset,
697
+ ) = resampling_algo.epipolar_rectify_images(
698
+ left_imgs,
699
+ right_imgs,
700
+ grid1,
701
+ grid2,
702
+ region,
703
+ margins,
704
+ epipolar_size_x,
705
+ epipolar_size_y,
706
+ interpolator_image,
707
+ interpolator_classif,
708
+ interpolator_mask,
709
+ step=step,
710
+ mask1=mask1,
711
+ mask2=mask2,
712
+ left_classifs=left_classifs,
713
+ right_classifs=right_classifs,
714
+ nodata1=nodata1,
715
+ nodata2=nodata2,
716
+ add_classif=add_classif,
717
+ )
718
+
719
+ # Add classification layers to dataset
720
+ if add_classif:
721
+ if left_classif_dataset:
722
+ left_dataset.coords[cst.BAND_CLASSIF] = left_classif_dataset.attrs[
723
+ cst.BAND_NAMES
724
+ ]
725
+ left_dataset[cst.EPI_CLASSIFICATION] = xr.DataArray(
726
+ left_classif_dataset[cst.EPI_IMAGE].values,
727
+ dims=[cst.BAND_CLASSIF, cst.ROW, cst.COL],
728
+ ).astype(bool)
729
+ if right_classif_dataset:
730
+ right_dataset.coords[cst.BAND_CLASSIF] = (
731
+ right_classif_dataset.attrs[cst.BAND_NAMES]
732
+ )
733
+ right_dataset[cst.EPI_CLASSIFICATION] = xr.DataArray(
734
+ right_classif_dataset[cst.EPI_IMAGE].values,
735
+ dims=[cst.BAND_CLASSIF, cst.ROW, cst.COL],
736
+ ).astype(bool)
737
+
738
+ # Add attributes info
739
+ attributes = {}
740
+ # fill datasets with saving info, window, profile, overlaps for correct
741
+ # saving
742
+ cars_dataset.fill_dataset(
743
+ left_dataset,
744
+ saving_info=saving_info_left,
745
+ window=window,
746
+ profile=None,
747
+ attributes=attributes,
748
+ overlaps=left_overlaps,
749
+ )
750
+
751
+ cars_dataset.fill_dataset(
752
+ right_dataset,
753
+ saving_info=saving_info_right,
754
+ window=window,
755
+ profile=None,
756
+ attributes=attributes,
757
+ overlaps=right_overlaps,
758
+ )
759
+
760
+ return left_dataset, right_dataset