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,401 @@
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
+ This module is responsible for the dense matching algorithms:
22
+ - thus it creates a disparity map from a pair of images
23
+ """
24
+ import copy
25
+
26
+ # Standard imports
27
+ import logging
28
+ from typing import Dict
29
+
30
+ import numpy as np
31
+ import pandora
32
+ import xarray as xr
33
+
34
+ # Third party imports
35
+ from pandora.check_configuration import check_datasets
36
+ from pandora.state_machine import PandoraMachine
37
+ from scipy.interpolate import (
38
+ LinearNDInterpolator,
39
+ NearestNDInterpolator,
40
+ RegularGridInterpolator,
41
+ )
42
+
43
+ from cars.applications.dense_matching import dense_matching_wrappers as dm_wrap
44
+
45
+ # CARS imports
46
+ from cars.core import constants as cst
47
+ from cars.core import inputs
48
+
49
+ # pylint: disable=too-many-lines
50
+
51
+
52
+ def compute_disparity_grid(
53
+ disp_range_grid,
54
+ left_image_object,
55
+ right_image_object,
56
+ used_band,
57
+ threshold_disp_range_to_borders,
58
+ ):
59
+ """
60
+ Compute dense disparity grids min and max for pandora
61
+ superposable to left image
62
+
63
+ :param disp_range_grid: disp range grid with min and max grids
64
+ :type disp_range_grid: CarsDataset
65
+ :param left_image_object: left image
66
+ :type left_image_object: xr.Dataset
67
+
68
+ :return disp min map, disp_max_map
69
+ :rtype np.ndarray, np.ndarray
70
+ """
71
+
72
+ disp_min_grid_arr, _ = inputs.rasterio_read_as_array(
73
+ disp_range_grid["grid_min_path"]
74
+ )
75
+ disp_max_grid_arr, _ = inputs.rasterio_read_as_array(
76
+ disp_range_grid["grid_max_path"]
77
+ )
78
+ row_range = disp_range_grid["row_range"]
79
+ col_range = disp_range_grid["col_range"]
80
+
81
+ # Create interpolators
82
+ interp_min = RegularGridInterpolator(
83
+ (
84
+ row_range,
85
+ col_range,
86
+ ),
87
+ disp_min_grid_arr,
88
+ )
89
+ interp_max = RegularGridInterpolator(
90
+ (
91
+ row_range,
92
+ col_range,
93
+ ),
94
+ disp_max_grid_arr,
95
+ )
96
+
97
+ # Interpolate disp on grid
98
+ roi_with_margins = left_image_object.attrs["roi_with_margins"]
99
+
100
+ row_range = np.arange(roi_with_margins[1], roi_with_margins[3])
101
+ col_range = np.arange(roi_with_margins[0], roi_with_margins[2])
102
+
103
+ row_grid, col_grid = np.meshgrid(row_range, col_range, indexing="ij")
104
+
105
+ disp_min_grid = interp_min((row_grid, col_grid)).astype("float32")
106
+ disp_max_grid = interp_max((row_grid, col_grid)).astype("float32")
107
+
108
+ # Compute extremums of disparity considering left image borders
109
+ if threshold_disp_range_to_borders:
110
+ disp_min_from_borders = np.zeros_like(disp_min_grid)
111
+ disp_max_from_borders = np.zeros_like(disp_max_grid)
112
+ right_msk = (
113
+ np.array(right_image_object[cst.EPI_MSK].loc[used_band]) == 0
114
+ )
115
+ index_of_first_valid_pixel = np.argmax(right_msk, axis=1)
116
+ index_of_last_valid_pixel = np.argmax(
117
+ np.flip(right_msk, axis=1), axis=1
118
+ )
119
+ index_of_last_valid_pixel = (
120
+ right_msk.shape[1] - index_of_last_valid_pixel
121
+ )
122
+ any_valid_pixel_exists = np.any(right_msk, axis=1)
123
+ right_msk_indices = zip( # noqa: B905
124
+ index_of_first_valid_pixel,
125
+ index_of_last_valid_pixel,
126
+ any_valid_pixel_exists,
127
+ )
128
+ for row_id, (first, last, exists) in enumerate(right_msk_indices):
129
+ if exists:
130
+ disp_min_from_borders[row_id, first:last] = np.flip(
131
+ np.arange(first - last, 0)
132
+ )
133
+ disp_max_from_borders[row_id, first:last] = np.flip(
134
+ np.arange(0, last - first)
135
+ )
136
+ disp_min_from_borders = np.minimum(disp_max_grid, disp_min_from_borders)
137
+ disp_max_from_borders = np.maximum(disp_min_grid, disp_max_from_borders)
138
+ disp_min_grid = np.maximum(disp_min_from_borders, disp_min_grid)
139
+ disp_max_grid = np.minimum(disp_max_from_borders, disp_max_grid)
140
+
141
+ # Interpolation might create min > max
142
+ disp_min_grid, disp_max_grid = dm_wrap.to_safe_disp_grid(
143
+ disp_min_grid, disp_max_grid
144
+ )
145
+
146
+ return disp_min_grid, disp_max_grid
147
+
148
+
149
+ def compute_disparity( # pylint: disable=too-many-positional-arguments
150
+ left_dataset,
151
+ right_dataset,
152
+ corr_cfg,
153
+ used_band=None,
154
+ disp_min_grid=None,
155
+ disp_max_grid=None,
156
+ compute_disparity_masks=False,
157
+ cropped_range=None,
158
+ margins_to_keep=0,
159
+ classification_fusion_margin=-1,
160
+ texture_bands=None,
161
+ filter_incomplete_disparity_range=True,
162
+ classif_bands_to_mask=None,
163
+ ) -> Dict[str, xr.Dataset]:
164
+ """
165
+ This function will compute disparity.
166
+
167
+ :param left_dataset: Dataset containing left image and mask
168
+ :type left_dataset: xarray.Dataset
169
+ :param right_dataset: Dataset containing right image and mask
170
+ :type right_dataset: xarray.Dataset
171
+ :param corr_cfg: Correlator configuration
172
+ :type corr_cfg: dict
173
+ :param used_band: name of band used for correlation
174
+ :type used_band: str
175
+ :param disp_min_grid: Minimum disparity grid
176
+ (if None, value is taken from left dataset)
177
+ :type disp_min_grid: np ndarray
178
+ :param disp_max_grid: Maximum disparity grid
179
+ (if None, value is taken from left dataset)
180
+ :type disp_max_grid: np ndarray
181
+ :param compute_disparity_masks: Activation of compute_disparity_masks mode
182
+ :type compute_disparity_masks: Boolean
183
+ :param cropped_range: true if disparity range was cropped
184
+ :type cropped_range: numpy array
185
+ :param margins_to_keep: margin to keep after dense matching
186
+ :type margins_to_keep: int
187
+ :param classification_fusion_margin: the margin to add for the fusion
188
+ :type classification_fusion_margin: int
189
+ :param classif_bands_to_mask: bands from classif to mask
190
+ :type classif_bands_to_mask: list of str / int
191
+
192
+
193
+ :return: Disparity dataset
194
+ """
195
+
196
+ # Save dataset
197
+ saved_left_dataset = copy.deepcopy(left_dataset)
198
+ saved_right_dataset = copy.deepcopy(right_dataset)
199
+
200
+ # Check disp min and max bounds with respect to margin used for
201
+ # rectification
202
+
203
+ # Get tile global disp
204
+ disp_min = np.floor(np.min(disp_min_grid))
205
+ disp_max = np.ceil(np.max(disp_max_grid))
206
+
207
+ if disp_min < left_dataset.attrs[cst.EPI_DISP_MIN]:
208
+ logging.error(
209
+ "disp_min ({}) is lower than disp_min used to determine "
210
+ "margin during rectification ({})".format(
211
+ disp_min, left_dataset.attrs["disp_min"]
212
+ )
213
+ )
214
+
215
+ if disp_max > left_dataset.attrs[cst.EPI_DISP_MAX]:
216
+ logging.error(
217
+ "disp_max ({}) is greater than disp_max used to determine "
218
+ "margin during rectification ({})".format(
219
+ disp_max, left_dataset.attrs["disp_max"]
220
+ )
221
+ )
222
+
223
+ # Load pandora plugin
224
+ pandora.import_plugin()
225
+
226
+ # Update nodata values
227
+ left_dataset.attrs[cst.EPI_NO_DATA_IMG] = corr_cfg["input"]["nodata_left"]
228
+ right_dataset.attrs[cst.EPI_NO_DATA_IMG] = corr_cfg["input"]["nodata_right"]
229
+
230
+ # Put disparity in datasets
231
+ left_disparity = xr.DataArray(
232
+ data=np.array(
233
+ [disp_min_grid, disp_max_grid],
234
+ ),
235
+ dims=["band_disp", "row", "col"],
236
+ coords={"band_disp": ["min", "max"]},
237
+ )
238
+
239
+ (disp_min_right_grid, disp_max_right_grid) = (
240
+ dm_wrap.estimate_right_grid_disp(disp_min_grid, disp_max_grid)
241
+ )
242
+ # estimation might create max < min
243
+ disp_min_right_grid, disp_max_right_grid = dm_wrap.to_safe_disp_grid(
244
+ disp_min_right_grid, disp_max_right_grid
245
+ )
246
+
247
+ right_disparity = xr.DataArray(
248
+ data=np.array(
249
+ [disp_min_right_grid, disp_max_right_grid],
250
+ ),
251
+ dims=["band_disp", "row", "col"],
252
+ coords={"band_disp": ["min", "max"]},
253
+ )
254
+
255
+ left_dataset["disparity"] = left_disparity
256
+ right_dataset["disparity"] = right_disparity
257
+
258
+ # Update invalidity masks: all classes in classification should be 0
259
+ if (
260
+ cst.EPI_CLASSIFICATION in left_dataset
261
+ and classif_bands_to_mask not in (None, [])
262
+ ):
263
+ classif_values = (
264
+ left_dataset[cst.EPI_CLASSIFICATION]
265
+ .sel(band_classif=classif_bands_to_mask)
266
+ .values
267
+ )
268
+ left_dataset[cst.EPI_MSK] = np.logical_or(
269
+ left_dataset[cst.EPI_MSK],
270
+ np.repeat(
271
+ np.any(classif_values != 0, axis=0)[np.newaxis, ...],
272
+ left_dataset.sizes["band_im"],
273
+ axis=0,
274
+ ),
275
+ )
276
+ if (
277
+ cst.EPI_CLASSIFICATION in right_dataset
278
+ and classif_bands_to_mask not in (None, [])
279
+ ):
280
+ classif_values = (
281
+ right_dataset[cst.EPI_CLASSIFICATION]
282
+ .sel(band_classif=classif_bands_to_mask)
283
+ .values
284
+ )
285
+ right_dataset[cst.EPI_MSK] = np.logical_or(
286
+ right_dataset[cst.EPI_MSK],
287
+ np.repeat(
288
+ np.any(classif_values != 0, axis=0)[np.newaxis, ...],
289
+ right_dataset.sizes["band_im"],
290
+ axis=0,
291
+ ),
292
+ )
293
+
294
+ if used_band is not None:
295
+
296
+ def remove_band(current_dataset, used_band):
297
+ """
298
+ Remove band_im dimension from mask
299
+ """
300
+ current_mask = current_dataset[cst.EPI_MSK]
301
+ current_mask = current_mask.loc[used_band]
302
+ current_dataset = current_dataset.drop_vars([cst.EPI_MSK])
303
+ current_dataset[cst.EPI_MSK] = current_mask
304
+ return current_dataset
305
+
306
+ # remove band_im in masks
307
+ [
308
+ left_dataset,
309
+ saved_left_dataset,
310
+ right_dataset,
311
+ saved_right_dataset,
312
+ ] = [
313
+ remove_band(current_dataset, used_band)
314
+ for current_dataset in [
315
+ left_dataset,
316
+ saved_left_dataset,
317
+ right_dataset,
318
+ saved_right_dataset,
319
+ ]
320
+ ]
321
+
322
+ # Check that the datasets are not full of nan (would crash later)
323
+ if left_dataset["msk"].all() or right_dataset["msk"].all():
324
+ height = left_dataset.sizes["row"]
325
+ width = left_dataset.sizes["col"]
326
+ ref = xr.Dataset(
327
+ coords={
328
+ "row": left_dataset.coords["row"],
329
+ "col": left_dataset.coords["col"],
330
+ "indicator": [
331
+ "confidence_from_ambiguity.cars_1",
332
+ "confidence_from_risk_max.cars_2",
333
+ "confidence_from_risk_min.cars_2",
334
+ "confidence_from_disp_sup_from_risk.cars_2",
335
+ "confidence_from_disp_inf_from_risk.cars_2",
336
+ "confidence_from_interval_bounds_inf.cars_3",
337
+ "confidence_from_interval_bounds_sup.cars_3",
338
+ "confidence_from_left_right_consistency",
339
+ ],
340
+ },
341
+ data_vars={
342
+ "disparity_map": (
343
+ ("row", "col"),
344
+ np.full((height, width), np.nan, dtype=np.float32),
345
+ ),
346
+ "validity_mask": (
347
+ ("row", "col"),
348
+ np.ones((height, width), dtype=np.int64),
349
+ ),
350
+ "confidence_measure": (
351
+ ("row", "col", "indicator"),
352
+ np.full((height, width, 8), np.nan, dtype=np.float32),
353
+ ),
354
+ },
355
+ )
356
+ else:
357
+ # Instantiate pandora state machine
358
+ pandora_machine = PandoraMachine()
359
+ # check datasets
360
+ check_datasets(left_dataset, right_dataset)
361
+
362
+ # Run the Pandora pipeline
363
+ ref, _ = pandora.run(
364
+ pandora_machine,
365
+ left_dataset,
366
+ right_dataset,
367
+ corr_cfg,
368
+ )
369
+
370
+ disp_dataset = dm_wrap.create_disp_dataset(
371
+ ref,
372
+ saved_left_dataset,
373
+ saved_right_dataset,
374
+ compute_disparity_masks=compute_disparity_masks,
375
+ disp_min_grid=disp_min_grid,
376
+ disp_max_grid=disp_max_grid,
377
+ cropped_range=cropped_range,
378
+ margins_to_keep=margins_to_keep,
379
+ classification_fusion_margin=classification_fusion_margin,
380
+ texture_bands=texture_bands,
381
+ filter_incomplete_disparity_range=filter_incomplete_disparity_range,
382
+ )
383
+
384
+ return disp_dataset
385
+
386
+
387
+ class LinearInterpNearestExtrap: # pylint: disable=too-few-public-methods
388
+ """
389
+ Linear interpolation and nearest neighbour extrapolation
390
+ """
391
+
392
+ def __init__(self, points, values):
393
+ self.interp = LinearNDInterpolator(points, values)
394
+ self.extrap = NearestNDInterpolator(points, values)
395
+
396
+ def __call__(self, *args):
397
+ z_values = self.interp(*args)
398
+ nan_mask = np.isnan(z_values)
399
+ if nan_mask.any():
400
+ return np.where(nan_mask, self.extrap(*args), z_values)
401
+ return z_values
@@ -0,0 +1,89 @@
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 constants of dense_matching.
23
+ """
24
+ from pandora import constants as pandora_cst
25
+
26
+ from cars.core import constants_disparity as disp_cst
27
+
28
+ # USED VARIABLES
29
+
30
+
31
+ DENSE_MATCHING_RUN_TAG = "dense_matching"
32
+
33
+ # grids disp
34
+ DISP_MIN_GRID = "disp_min_grid"
35
+ DISP_MAX_GRID = "disp_max_grid"
36
+
37
+
38
+ # PARAMS
39
+ METHOD = "method"
40
+ MIN_EPI_TILE_SIZE = "min_epi_tile_size"
41
+ MAX_EPI_TILE_SIZE = "max_epi_tile_size"
42
+ EPI_TILE_MARGIN_IN_PERCENT = "epipolar_tile_margin_in_percent"
43
+ MIN_ELEVATION_OFFSET = "min_elevation_offset"
44
+ MAX_ELEVATION_OFFSET = "max_elevation_offset"
45
+
46
+ # ABRIDGED PANDORA CONSTANTS
47
+ IN_VALIDITY_MASK_LEFT = "IN_VALIDITY_MASK_LEFT"
48
+ IN_VALIDITY_MASK_RIGHT = "IN_VALIDITY_MASK_RIGHT"
49
+ RIGHT_INCOMPLETE_DISPARITY_RANGE = "RIGHT_INCOMPLETE_DISPARITY_RANGE"
50
+ STOPPED_INTERPOLATION = "STOPPED_INTERPOLATION"
51
+ FILLED_OCCLUSION = "FILLED_OCCLUSION"
52
+ FILLED_MISMATCH = "FILLED_MISMATCH"
53
+ LEFT_NODATA_OR_BORDER = "LEFT_NODATA_OR_BORDER"
54
+ RIGHT_NODATA_OR_DISPARITY_RANGE_MISSING = (
55
+ "RIGHT_NODATA_OR_DISPARITY_RANGE_MISSING"
56
+ )
57
+ OCCLUSION = "OCCLUSION"
58
+ MISMATCH = "MISMATCH"
59
+ INCOMPLETE_VARIABLE_DISPARITY_RANGE = "INCOMPLETE_VARIABLE_DISPARITY_RANGE"
60
+
61
+
62
+ def get_cst(key):
63
+ """
64
+ get pandora constant from abridged key
65
+
66
+ :param key: abridged key of pandora mask
67
+
68
+ Returns:
69
+ _type_: pandora mask constant
70
+ """
71
+ return pandora_cst.__dict__.get("PANDORA_MSK_PIXEL_" + key)
72
+
73
+
74
+ # CORRESPONDING MSK TABLE PANDORA CARS
75
+ MASK_HASH_TABLE = {
76
+ disp_cst.MASKED_REF: get_cst(IN_VALIDITY_MASK_LEFT),
77
+ disp_cst.MASKED_SEC: get_cst(IN_VALIDITY_MASK_RIGHT),
78
+ disp_cst.INCOMPLETE_DISP: get_cst(RIGHT_INCOMPLETE_DISPARITY_RANGE),
79
+ disp_cst.STOPPED_INTERP: get_cst(STOPPED_INTERPOLATION),
80
+ disp_cst.FILLED_OCCLUSION: get_cst(FILLED_OCCLUSION),
81
+ disp_cst.FILLED_FALSE_MATCH: get_cst(FILLED_MISMATCH),
82
+ disp_cst.INVALID_REF: get_cst(LEFT_NODATA_OR_BORDER),
83
+ disp_cst.INVALID_SEC: get_cst(RIGHT_NODATA_OR_DISPARITY_RANGE_MISSING),
84
+ disp_cst.OCCLUSION: get_cst(OCCLUSION),
85
+ disp_cst.FALSE_MATCH: get_cst(MISMATCH),
86
+ disp_cst.INCOMPLETE_VARIABLE_DISP: get_cst(
87
+ INCOMPLETE_VARIABLE_DISPARITY_RANGE
88
+ ),
89
+ }