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,597 @@
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 wrapper used in disparity grid computation.
23
+ """
24
+
25
+ # Standard imports
26
+ import itertools
27
+ import logging
28
+
29
+ # Third party imports
30
+ import numpy as np
31
+ import rasterio
32
+ import xarray as xr
33
+ from scipy.ndimage import maximum_filter, minimum_filter
34
+ from shareloc.proj_utils import transform_physical_point_to_index
35
+
36
+ # CARS imports
37
+ import cars.applications.dense_matching.dense_matching_constants as dm_cst
38
+ import cars.orchestrator.orchestrator as ocht
39
+ from cars.applications.dense_matching.dense_matching_algo import (
40
+ LinearInterpNearestExtrap,
41
+ )
42
+ from cars.core import inputs, projection
43
+ from cars.core.projection import point_cloud_conversion
44
+ from cars.data_structures import cars_dataset, cars_dict
45
+
46
+
47
+ # pylint: disable=too-many-positional-arguments
48
+ def generate_disp_grids_dataset(
49
+ grid_min,
50
+ grid_max,
51
+ saving_info,
52
+ raster_profile,
53
+ window=None,
54
+ row_coords=None,
55
+ col_coords=None,
56
+ ):
57
+ """
58
+ Generate disparity grids xarray dataset
59
+
60
+ :param grid_min: disp grid min
61
+ :type grid_min: np.ndarray
62
+ :param grid_max: disp grid max
63
+ :type grid_max: np.ndarray
64
+ :param saving_info: saving infos
65
+ :type saving_info: dict
66
+ :param raster_profile: raster_profile
67
+ :type raster_profile: dict
68
+ :param row_coords: row cooordinates
69
+ :type row_coords: np.ndarray, optional
70
+ :param col_coords: col coordinates
71
+ :type col_coords: np.ndarray, optional
72
+
73
+ :return: disp range dataset
74
+ :rtype: xarray.Dataset
75
+ """
76
+
77
+ if row_coords is None:
78
+ row_coords = np.arange(0, grid_min.shape[0])
79
+
80
+ if col_coords is None:
81
+ col_coords = np.arange(0, grid_min.shape[1])
82
+
83
+ disp_range_tile = xr.Dataset(
84
+ data_vars={
85
+ dm_cst.DISP_MIN_GRID: (["row", "col"], grid_min),
86
+ dm_cst.DISP_MAX_GRID: (["row", "col"], grid_max),
87
+ },
88
+ coords={
89
+ "row": row_coords,
90
+ "col": col_coords,
91
+ },
92
+ )
93
+
94
+ cars_dataset.fill_dataset(
95
+ disp_range_tile,
96
+ saving_info=saving_info,
97
+ window=window,
98
+ profile=raster_profile,
99
+ attributes=None,
100
+ overlaps=None,
101
+ )
102
+
103
+ return disp_range_tile
104
+
105
+
106
+ # pylint: disable=too-many-positional-arguments
107
+ def generate_disp_range_const_tile_wrapper(
108
+ row_range,
109
+ col_range,
110
+ dmin,
111
+ dmax,
112
+ raster_profile,
113
+ saving_info,
114
+ saving_info_global_infos,
115
+ ):
116
+ """
117
+ Generate disparity range dataset from constant dmin and dmax
118
+
119
+ :param row_range: Row range
120
+ :type row_range: list
121
+ :param col_range: Column range.
122
+ :type col_range: list
123
+ :param dmin: disparity minimum.
124
+ :type dmin: float
125
+ :param dmax: disparity maximum.
126
+ :type dmax: float
127
+ :param raster_profile: The raster profile.
128
+ :type raster_profile: dict
129
+ :param saving_info: The disp range grid saving information.
130
+ :type saving_info: dict
131
+ :param saving_info_global_infos: Global info saving infos.
132
+ :type saving_info_global_infos: dict
133
+
134
+ :return: Disparity range grid
135
+ :rtype: dict
136
+ """
137
+ grid_min = np.empty((len(row_range), len(col_range)))
138
+ grid_max = np.empty((len(row_range), len(col_range)))
139
+ grid_min[:, :] = dmin
140
+ grid_max[:, :] = dmax
141
+
142
+ mono_tile_saving_info = ocht.update_saving_infos(saving_info, row=0, col=0)
143
+ disp_range = generate_disp_grids_dataset(
144
+ grid_min, grid_max, mono_tile_saving_info, raster_profile, window=None
145
+ )
146
+
147
+ # Generate infos on global min and max
148
+ global_infos = cars_dict.CarsDict(
149
+ {"global_min": np.nanmin(dmin), "global_max": np.nanmin(dmax)}
150
+ )
151
+ cars_dataset.fill_dict(global_infos, saving_info=saving_info_global_infos)
152
+
153
+ return disp_range, global_infos
154
+
155
+
156
+ # pylint: disable=too-many-positional-arguments
157
+ def generate_disp_range_from_dem_wrapper(
158
+ epipolar_grid_array_window,
159
+ full_epi_row_range,
160
+ full_epi_col_range,
161
+ sensor_image_right,
162
+ grid_right,
163
+ geom_plugin_with_dem_and_geoid,
164
+ dem_min,
165
+ dem_max,
166
+ raster_profile,
167
+ saving_info,
168
+ saving_info_global_infos,
169
+ filter_overlap,
170
+ disp_to_alt_ratio,
171
+ disp_min_threshold=None,
172
+ disp_max_threshold=None,
173
+ ):
174
+ """
175
+ Generate disparity range dataset from dems
176
+
177
+ :param epipolar_grid_array_window: The window of the epipolar grid array.
178
+ :type epipolar_grid_array_window: dict
179
+ :param full_epi_row_range: The full range of rows in the epipolar grid.
180
+ :type full_epi_row_range: list
181
+ :param full_epi_col_range: The full range of columns in the epipolar grid.
182
+ :type full_epi_col_range: list
183
+ :param sensor_image_right: The right sensor image.
184
+ :type sensor_image_right: dict
185
+ :param grid_right: The right epipolar grid.
186
+ :type grid_right: dict
187
+ :param geom_plugin_with_dem_and_geoid: The geometry plugin with DEM.
188
+ :type geom_plugin_with_dem_and_geoid: object
189
+ :param dem_min: Path of dem min.
190
+ :type dem_min: str
191
+ :param dem_max: Path of dem max.
192
+ :type dem_max: srt
193
+ :param raster_profile: The raster profile.
194
+ :type raster_profile: dict
195
+ :param saving_info: The disp range grid saving information.
196
+ :type saving_info: dict
197
+ :param saving_info_global_infos: Global info saving infos.
198
+ :type saving_info_global_infos: dict
199
+ :param filter_overlap: The overlap to use for filtering.
200
+ :type filter_overlap: int
201
+ :param disp_to_alt_ratio: disparity to altitude ratio
202
+ :type disp_to_alt_ratio: float
203
+ :param disp_min_threshold: The minimum disparity threshold.
204
+ :type disp_min_threshold: float, optional
205
+ :param disp_max_threshold: The maximum disparity threshold.
206
+ :type disp_max_threshold: float, optional
207
+
208
+ :return: Disparity range grid
209
+ :rtype: dict
210
+ """
211
+
212
+ # compute reverse matrix
213
+ transform_sensor = inputs.rasterio_get_transform(
214
+ sensor_image_right["image"]["bands"]["b0"]["path"], convention="north"
215
+ )
216
+
217
+ trans_inv_sensor = ~transform_sensor
218
+
219
+ # Geometry plugin
220
+ geo_plugin = geom_plugin_with_dem_and_geoid
221
+ dem_median = geo_plugin.dem
222
+
223
+ # get epsg
224
+ terrain_epsg = inputs.rasterio_get_epsg(dem_median)
225
+
226
+ # Get epipolar position of all dem mean
227
+ transform_dem_median = inputs.rasterio_get_transform(dem_median)
228
+
229
+ # use local disparity
230
+
231
+ # Get associated alti mean / min / max values
232
+ dem_median_shape = inputs.rasterio_get_size(dem_median)
233
+ dem_median_width, dem_median_height = dem_median_shape
234
+
235
+ # get corresponding window from epipolar_array_window
236
+ epi_grid_margin = filter_overlap + 1
237
+ epi_grid_row_min = epipolar_grid_array_window["row_min"]
238
+ epi_grid_row_max = epipolar_grid_array_window["row_max"]
239
+ epi_grid_col_min = epipolar_grid_array_window["col_min"]
240
+ epi_grid_col_max = epipolar_grid_array_window["col_max"]
241
+
242
+ def clip(value, min_value, max_value):
243
+ """
244
+ Clip a value inside bounds
245
+ """
246
+ return int(max(min_value, min(value, max_value)))
247
+
248
+ # Epi grid tile coordinate to use, with and without margins
249
+ epi_grid_row_min_with_margin = clip(
250
+ epi_grid_row_min - epi_grid_margin, 0, len(full_epi_row_range)
251
+ )
252
+ epi_grid_row_max_with_margin = clip(
253
+ epi_grid_row_max + epi_grid_margin, 0, len(full_epi_row_range)
254
+ )
255
+ epi_grid_col_min_with_margin = clip(
256
+ epi_grid_col_min - epi_grid_margin, 0, len(full_epi_col_range)
257
+ )
258
+ epi_grid_col_max_with_margin = clip(
259
+ epi_grid_col_max + epi_grid_margin, 0, len(full_epi_col_range)
260
+ )
261
+
262
+ # range to use for epipolar interpolation
263
+ row_range_with_margin = full_epi_row_range[
264
+ epi_grid_row_min_with_margin:epi_grid_row_max_with_margin
265
+ ]
266
+ row_range_no_margin = full_epi_row_range[epi_grid_row_min:epi_grid_row_max]
267
+ col_range_with_margin = full_epi_col_range[
268
+ epi_grid_col_min_with_margin:epi_grid_col_max_with_margin
269
+ ]
270
+ col_range_no_margin = full_epi_col_range[epi_grid_col_min:epi_grid_col_max]
271
+
272
+ # Loc on dem median
273
+ epi_bbox = [
274
+ (np.min(col_range_with_margin), np.min(row_range_with_margin)),
275
+ (np.min(col_range_with_margin), np.max(row_range_with_margin)),
276
+ (np.max(col_range_with_margin), np.min(row_range_with_margin)),
277
+ (np.max(col_range_with_margin), np.max(row_range_with_margin)),
278
+ ]
279
+ sensor_bbox = geo_plugin.sensor_position_from_grid(
280
+ grid_right, epi_bbox, interpolation_method="linear"
281
+ )
282
+ row_sensor_bbox, col_sensor_bbox = transform_physical_point_to_index(
283
+ trans_inv_sensor, sensor_bbox[:, 1], sensor_bbox[:, 0]
284
+ )
285
+
286
+ terrain_bbox = geo_plugin.safe_direct_loc(
287
+ sensor_image_right["image"]["bands"]["b0"]["path"],
288
+ sensor_image_right["geomodel"],
289
+ col_sensor_bbox,
290
+ row_sensor_bbox,
291
+ )
292
+
293
+ # reshape terrain bbox
294
+ terrain_bbox = terrain_bbox[0:2].T
295
+ terrain_bbox[:, [1, 0]] = terrain_bbox[:, [0, 1]]
296
+
297
+ # get pixel location on dem median
298
+ pixel_roi_dem_mean = inputs.rasterio_get_pixel_points(
299
+ dem_median, terrain_bbox
300
+ )
301
+
302
+ # Add margins (for interpolation) and clip
303
+ dem_margin = 10 # arbitrary
304
+ roi_lower_row = np.floor(np.min(pixel_roi_dem_mean[:, 0])) - dem_margin
305
+ roi_upper_row = np.ceil(np.max(pixel_roi_dem_mean[:, 0])) + dem_margin
306
+ roi_lower_col = np.floor(np.min(pixel_roi_dem_mean[:, 1])) - dem_margin
307
+ roi_upper_col = np.ceil(np.max(pixel_roi_dem_mean[:, 1])) + dem_margin
308
+
309
+ min_row = clip(roi_lower_row, 0, dem_median_height)
310
+ max_row = clip(roi_upper_row, 0, dem_median_height)
311
+ min_col = clip(roi_lower_col, 0, dem_median_width)
312
+ max_col = clip(roi_upper_col, 0, dem_median_width)
313
+
314
+ # compute terrain positions to use (all dem min and max)
315
+ row_indexes = range(min_row, max_row)
316
+ col_indexes = range(min_col, max_col)
317
+ transformer = rasterio.transform.AffineTransformer(transform_dem_median)
318
+
319
+ if len(row_indexes) == 0 or len(col_indexes) == 0:
320
+ disp_range, global_infos = empty_disparity_grids(
321
+ row_range_no_margin,
322
+ col_range_no_margin,
323
+ epipolar_grid_array_window,
324
+ raster_profile,
325
+ saving_info,
326
+ saving_info_global_infos,
327
+ )
328
+ return disp_range, global_infos
329
+
330
+ indexes = np.array(list(itertools.product(row_indexes, col_indexes)))
331
+
332
+ row = indexes[:, 0]
333
+ col = indexes[:, 1]
334
+ x_mean, y_mean = transformer.xy(row, col)
335
+ terrain_positions = np.transpose(np.array([x_mean, y_mean]))
336
+
337
+ # dem mean in terrain_epsg
338
+ x_mean = terrain_positions[:, 0]
339
+ y_mean = terrain_positions[:, 1]
340
+
341
+ dem_median_list = inputs.rasterio_get_values(
342
+ dem_median, x_mean, y_mean, point_cloud_conversion
343
+ )
344
+
345
+ nan_mask = ~np.isnan(dem_median_list)
346
+
347
+ # transform to lon lat
348
+ terrain_position_lon_lat = projection.point_cloud_conversion(
349
+ terrain_positions, terrain_epsg, 4326
350
+ )
351
+ lon_mean = terrain_position_lon_lat[:, 0]
352
+ lat_mean = terrain_position_lon_lat[:, 1]
353
+
354
+ # dem min and max are in 4326
355
+ dem_min_list = inputs.rasterio_get_values(
356
+ dem_min, lon_mean, lat_mean, point_cloud_conversion
357
+ )
358
+ dem_max_list = inputs.rasterio_get_values(
359
+ dem_max, lon_mean, lat_mean, point_cloud_conversion
360
+ )
361
+ if dem_min_list is None or dem_max_list is None:
362
+ logging.warning("DEM min and DEM max does not cover this tile")
363
+ disp_range, global_infos = empty_disparity_grids(
364
+ row_range_no_margin,
365
+ col_range_no_margin,
366
+ epipolar_grid_array_window,
367
+ raster_profile,
368
+ saving_info,
369
+ saving_info_global_infos,
370
+ )
371
+ return disp_range, global_infos
372
+
373
+ nan_mask = nan_mask & ~np.isnan(dem_min_list) & ~np.isnan(dem_max_list)
374
+
375
+ # filter nan value from input points
376
+ lon_mean = lon_mean[nan_mask]
377
+ lat_mean = lat_mean[nan_mask]
378
+ dem_median_list = dem_median_list[nan_mask]
379
+ dem_min_list = dem_min_list[nan_mask]
380
+ dem_max_list = dem_max_list[nan_mask]
381
+
382
+ # sensors physical positions
383
+ (
384
+ ind_cols_sensor,
385
+ ind_rows_sensor,
386
+ _,
387
+ ) = geom_plugin_with_dem_and_geoid.safe_inverse_loc(
388
+ sensor_image_right["image"]["bands"]["b0"]["path"],
389
+ sensor_image_right["geomodel"],
390
+ lat_mean,
391
+ lon_mean,
392
+ z_coord=dem_median_list,
393
+ )
394
+
395
+ # Generate epipolar disp grids
396
+ # Get epipolar positions
397
+ epipolar_positions_row, epipolar_positions_col = np.meshgrid(
398
+ col_range_with_margin,
399
+ row_range_with_margin,
400
+ )
401
+ epipolar_positions = np.stack(
402
+ [epipolar_positions_row, epipolar_positions_col], axis=2
403
+ )
404
+
405
+ # Get sensor position
406
+ sensors_positions = (
407
+ geom_plugin_with_dem_and_geoid.sensor_position_from_grid(
408
+ grid_right,
409
+ np.reshape(
410
+ epipolar_positions,
411
+ (
412
+ epipolar_positions.shape[0] * epipolar_positions.shape[1],
413
+ 2,
414
+ ),
415
+ ),
416
+ interpolation_method="linear",
417
+ )
418
+ )
419
+
420
+ # Transform physical position to index
421
+ ind_rows_sensor_grid, ind_cols_sensor_grid = (
422
+ transform_physical_point_to_index(
423
+ trans_inv_sensor, sensors_positions[:, 1], sensors_positions[:, 0]
424
+ )
425
+ )
426
+
427
+ if len(ind_rows_sensor) < 5:
428
+ # QH6214 needs at least 4 points for interpolation
429
+ disp_range, global_infos = empty_disparity_grids(
430
+ row_range_no_margin,
431
+ col_range_no_margin,
432
+ epipolar_grid_array_window,
433
+ raster_profile,
434
+ saving_info,
435
+ saving_info_global_infos,
436
+ )
437
+ return disp_range, global_infos
438
+
439
+ # Interpolate disparity
440
+ disp_min_points = -(dem_max_list - dem_median_list) / disp_to_alt_ratio
441
+ disp_max_points = -(dem_min_list - dem_median_list) / disp_to_alt_ratio
442
+
443
+ interp_min_linear = LinearInterpNearestExtrap(
444
+ list(zip(ind_rows_sensor, ind_cols_sensor)), # noqa: B905
445
+ disp_min_points,
446
+ )
447
+ interp_max_linear = LinearInterpNearestExtrap(
448
+ list(zip(ind_rows_sensor, ind_cols_sensor)), # noqa: B905
449
+ disp_max_points,
450
+ )
451
+
452
+ grid_min = np.reshape(
453
+ interp_min_linear(ind_rows_sensor_grid, ind_cols_sensor_grid),
454
+ (
455
+ epipolar_positions.shape[0],
456
+ epipolar_positions.shape[1],
457
+ ),
458
+ )
459
+
460
+ grid_max = np.reshape(
461
+ interp_max_linear(ind_rows_sensor_grid, ind_cols_sensor_grid),
462
+ (
463
+ epipolar_positions.shape[0],
464
+ epipolar_positions.shape[1],
465
+ ),
466
+ )
467
+
468
+ # Add margin
469
+ diff = grid_max - grid_min
470
+ logging.info("Max grid max - grid min : {} disp ".format(np.max(diff)))
471
+
472
+ if disp_min_threshold is not None:
473
+ if np.any(grid_min < disp_min_threshold):
474
+ logging.warning(
475
+ "Override disp_min with disp_min_threshold {}".format(
476
+ disp_min_threshold
477
+ )
478
+ )
479
+ grid_min[grid_min < disp_min_threshold] = disp_min_threshold
480
+ if disp_max_threshold is not None:
481
+ if np.any(grid_max > disp_max_threshold):
482
+ logging.warning(
483
+ "Override disp_max with disp_max_threshold {}".format(
484
+ disp_max_threshold
485
+ )
486
+ )
487
+ grid_max[grid_max > disp_max_threshold] = disp_max_threshold
488
+
489
+ # generate footprint
490
+ footprint_mask = create_circular_mask(filter_overlap, filter_overlap)
491
+ grid_min = minimum_filter(
492
+ grid_min, footprint=footprint_mask, mode="nearest"
493
+ )
494
+ grid_max = maximum_filter(
495
+ grid_max, footprint=footprint_mask, mode="nearest"
496
+ )
497
+
498
+ # Create xarray dataset
499
+ disp_range = generate_disp_grids_dataset(
500
+ grid_min,
501
+ grid_max,
502
+ saving_info,
503
+ raster_profile,
504
+ window=epipolar_grid_array_window,
505
+ row_coords=row_range_with_margin,
506
+ col_coords=col_range_with_margin,
507
+ )
508
+
509
+ # crop epipolar grid from margin added for propagation filter
510
+ disp_range = disp_range.sel(
511
+ row=list(row_range_no_margin), col=list(col_range_no_margin)
512
+ )
513
+
514
+ # Generate infos on global min and max
515
+ global_infos = cars_dict.CarsDict(
516
+ {
517
+ "global_min": np.floor(np.nanmin(grid_min)),
518
+ "global_max": np.ceil(np.nanmax(grid_max)),
519
+ }
520
+ )
521
+ cars_dataset.fill_dict(global_infos, saving_info=saving_info_global_infos)
522
+
523
+ return disp_range, global_infos
524
+
525
+
526
+ def empty_disparity_grids( # pylint: disable=too-many-positional-arguments
527
+ row_range_no_margin,
528
+ col_range_no_margin,
529
+ epipolar_grid_array_window,
530
+ raster_profile,
531
+ saving_info,
532
+ saving_info_global_infos,
533
+ ):
534
+ """
535
+ Return empty disparity grids
536
+ :param row_range_no_margin: Rows id in grid
537
+ :type row_range_no_margin: int
538
+ :param col_range_no_margin: Cols id in grid
539
+ :type col_range_no_margin: int
540
+ :param epipolar_grid_array_window: ROI of grid
541
+ :type epipolar_grid_array_window: dict
542
+ :param raster_profile: The raster profile.
543
+ :type raster_profile: dict
544
+ :param saving_info: The disp range grid saving information.
545
+ :type saving_info: dict
546
+ :param saving_info_global_infos: Global info saving infos.
547
+ :type saving_info_global_infos: dict
548
+ """
549
+ grid_min = np.empty((len(row_range_no_margin), len(col_range_no_margin)))
550
+ grid_max = np.empty((len(row_range_no_margin), len(col_range_no_margin)))
551
+ grid_min[:, :] = 0
552
+ grid_max[:, :] = 0
553
+
554
+ disp_range = generate_disp_grids_dataset(
555
+ grid_min,
556
+ grid_max,
557
+ saving_info,
558
+ raster_profile,
559
+ window=epipolar_grid_array_window,
560
+ row_coords=row_range_no_margin,
561
+ col_coords=col_range_no_margin,
562
+ )
563
+
564
+ # Generate infos on global min and max
565
+ global_infos = cars_dict.CarsDict(
566
+ {
567
+ "global_min": 0,
568
+ "global_max": 0,
569
+ }
570
+ )
571
+ cars_dataset.fill_dict(global_infos, saving_info=saving_info_global_infos)
572
+
573
+ return disp_range, global_infos
574
+
575
+
576
+ def create_circular_mask(height, width):
577
+ """
578
+ Create a circular mask for footprint around pixel
579
+
580
+ :param height: height of footprint
581
+ :type height: int
582
+ :param width: width of footprint
583
+ :type width: int
584
+
585
+ :return: mask representing circular footprint
586
+ :rtype: np.ndarray
587
+ """
588
+ center = (int(width / 2), int(height / 2))
589
+ radius = min(center[0], center[1], width - center[0], height - center[1])
590
+
591
+ y_grid, x_grid = np.ogrid[:height, :width]
592
+ dist_from_center = np.sqrt(
593
+ (x_grid - center[0]) ** 2 + (y_grid - center[1]) ** 2
594
+ )
595
+
596
+ mask = dist_from_center <= radius
597
+ return mask.astype(bool)
@@ -0,0 +1,23 @@
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
+ CARS core dense matching module init file
23
+ """
@@ -0,0 +1,31 @@
1
+ {
2
+ "input": {},
3
+ "pipeline": {
4
+ "matching_cost": {
5
+ "matching_cost_method": "census",
6
+ "window_size": 5,
7
+ "subpix": 1
8
+ },
9
+ "optimization": {
10
+ "optimization_method": "sgm",
11
+ "overcounting": false,
12
+ "penalty": {
13
+ "P1": 8,
14
+ "P2": 32,
15
+ "p2_method": "constant",
16
+ "penalty_method": "sgm_penalty"
17
+ }
18
+ },
19
+ "disparity": {
20
+ "disparity_method": "wta",
21
+ "invalid_disparity": "NaN"
22
+ },
23
+ "refinement": {
24
+ "refinement_method": "vfit"
25
+ },
26
+ "filter": {
27
+ "filter_method": "median",
28
+ "filter_size": 3
29
+ }
30
+ }
31
+ }
@@ -0,0 +1,30 @@
1
+ {
2
+ "input": {},
3
+ "pipeline": {
4
+ "matching_cost": {
5
+ "matching_cost_method": "census",
6
+ "window_size": 11,
7
+ "subpix": 1
8
+ },
9
+ "optimization": {
10
+ "optimization_method": "sgm",
11
+ "overcounting": true,
12
+ "penalty": {
13
+ "P1": 72,
14
+ "P2": 309,
15
+ "penalty_method": "sgm_penalty"
16
+ }
17
+ },
18
+ "disparity": {
19
+ "disparity_method": "wta",
20
+ "invalid_disparity": "NaN"
21
+ },
22
+ "refinement": {
23
+ "refinement_method": "vfit"
24
+ },
25
+ "filter": {
26
+ "filter_method": "median",
27
+ "filter_size": 3
28
+ }
29
+ }
30
+ }