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,107 @@
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 tools for the dem generation
23
+ """
24
+
25
+ import contextlib
26
+ import logging
27
+
28
+ # Standard imports
29
+ import os
30
+
31
+ # Third party imports
32
+ import yaml
33
+ from bulldozer.pipeline.bulldozer_pipeline import dsm_to_dtm
34
+
35
+
36
+ def launch_bulldozer(
37
+ input_dem,
38
+ output_dir,
39
+ cars_orchestrator,
40
+ max_object_size,
41
+ ):
42
+ """
43
+ Launch bulldozer on a DEM to smooth it
44
+
45
+ :param input_dem: path of DEM to reverse
46
+ :type input_dem: str
47
+ :param output_dir: directory where bulldozer output is dumped
48
+ :type output_dir: str
49
+ :param cars_orchestrator: orchestrator of the whole pipeline
50
+ (used to get number of workers)
51
+ :type cars_orchestrator: Orchestrator
52
+ :param max_object_size: bulldozer parameter "max_object_size"
53
+ :type max_object_size: int
54
+ """
55
+ bull_conf_path = os.path.join(
56
+ os.path.dirname(__file__), "bulldozer_config/base_config.yaml"
57
+ )
58
+ with open(bull_conf_path, "r", encoding="utf8") as bull_conf_file:
59
+ bull_conf = yaml.safe_load(bull_conf_file)
60
+
61
+ bull_conf["dsm_path"] = input_dem
62
+ bull_conf["output_dir"] = output_dir
63
+ if cars_orchestrator is not None:
64
+ if (
65
+ cars_orchestrator.get_conf()["mode"] == "multiprocessing"
66
+ or cars_orchestrator.get_conf()["mode"] == "local_dask"
67
+ ):
68
+ bull_conf["nb_max_workers"] = cars_orchestrator.get_conf()[
69
+ "nb_workers"
70
+ ]
71
+ else:
72
+ bull_conf["nb_max_workers"] = 4
73
+ bull_conf["max_object_size"] = max_object_size
74
+
75
+ os.makedirs(output_dir, exist_ok=True)
76
+ bull_conf_path = os.path.join(output_dir, "bulldozer_config.yaml")
77
+ with open(bull_conf_path, "w", encoding="utf8") as bull_conf_file:
78
+ yaml.dump(bull_conf, bull_conf_file)
79
+
80
+ output_dem = os.path.join(bull_conf["output_dir"], "dtm.tif")
81
+
82
+ try:
83
+ try:
84
+ # suppress prints in bulldozer by redirecting stdout&stderr
85
+ with open(os.devnull, "w", encoding="utf8") as devnull:
86
+ with (
87
+ contextlib.redirect_stdout(devnull),
88
+ contextlib.redirect_stderr(devnull),
89
+ ):
90
+ dsm_to_dtm(bull_conf_path)
91
+ except Exception:
92
+ logging.info("Bulldozer failed on its first execution. Retrying")
93
+ # suppress prints in bulldozer by redirecting stdout&stderr
94
+ with open(os.devnull, "w", encoding="utf8") as devnull:
95
+ with (
96
+ contextlib.redirect_stdout(devnull),
97
+ contextlib.redirect_stderr(devnull),
98
+ ):
99
+ dsm_to_dtm(bull_conf_path)
100
+ except Exception:
101
+ logging.error(
102
+ "Bulldozer failed on its second execution."
103
+ + " The DSM could not be smoothed."
104
+ )
105
+ output_dem = None
106
+
107
+ return output_dem
@@ -0,0 +1,32 @@
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 dem generation constants.
23
+ """
24
+
25
+
26
+ DEM_MEDIAN = "dem_median"
27
+ DEM_MIN = "dem_min"
28
+ DEM_MAX = "dem_max"
29
+
30
+ DEM_MEDIAN_PATH = "dem_median_path"
31
+ DEM_MIN_PATH = "dem_min_path"
32
+ DEM_MAX_PATH = "dem_max_path"
@@ -0,0 +1,323 @@
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 tools for the dem generation
23
+ """
24
+ import contextlib
25
+ import logging
26
+ import os
27
+
28
+ import numpy as np
29
+ import rasterio as rio
30
+ import xdem
31
+
32
+ # Third-party imports
33
+ from affine import Affine
34
+ from rasterio.coords import BoundingBox
35
+ from rasterio.enums import Resampling
36
+ from rasterio.warp import calculate_default_transform, reproject
37
+ from scipy.ndimage import median_filter
38
+
39
+
40
+ def fit_initial_elevation_on_dem_median(
41
+ dem_to_fit_path: str, dem_ref_path: str, dem_out_path: str
42
+ ):
43
+ """
44
+ Coregistrates the two DEMs given then saves the result.
45
+ The initial elevation will be cropped to reduce computation costs.
46
+ Returns the transformation applied.
47
+
48
+ :param dem_to_fit_path: Path to the dem to be fitted
49
+ :type dem_to_fit_path: str
50
+ :param dem_ref_path: Path to the dem to fit onto
51
+ :type dem_ref_path: str
52
+ :param dem_out_path: Path to save the resulting dem into
53
+ :type dem_out_path: str
54
+
55
+ :return: coregistration transformation applied
56
+ :rtype: dict
57
+ """
58
+ # suppress all outputs of xdem
59
+ with open(os.devnull, "w", encoding="utf8") as devnull:
60
+ with (
61
+ contextlib.redirect_stdout(devnull),
62
+ contextlib.redirect_stderr(devnull),
63
+ ):
64
+
65
+ # load DEMs
66
+ dem_to_fit = xdem.DEM(dem_to_fit_path)
67
+ dem_ref = xdem.DEM(dem_ref_path)
68
+
69
+ # get the crs needed to reproject the data
70
+ crs_out = dem_ref.crs
71
+ crs_metric = dem_ref.get_metric_crs()
72
+
73
+ # Crop dem_to_fit with dem_ref to reduce
74
+ # computation costs.
75
+ bbox = dem_ref.bounds
76
+ bbox = add_margin(bbox)
77
+ dem_to_fit = dem_to_fit.crop(bbox).reproject(crs=crs_metric)
78
+ # Reproject dem_ref to dem_to_fit resolution to reduce
79
+ # computation costs
80
+ dem_ref = dem_ref.reproject(dem_to_fit)
81
+ bbox = dem_ref.bounds
82
+ bbox = add_margin(bbox)
83
+
84
+ coreg_pipeline = xdem.coreg.NuthKaab()
85
+
86
+ try:
87
+ # fit dem_to_fit onto dem_ref, crop it, then reproject it
88
+ # set a random state to always get the same results
89
+ fit_dem = (
90
+ coreg_pipeline.fit_and_apply(
91
+ dem_ref, dem_to_fit, random_state=0
92
+ )
93
+ .crop(bbox)
94
+ .reproject(crs=crs_out)
95
+ )
96
+ # save the results
97
+ fit_dem.save(dem_out_path)
98
+ coreg_offsets = coreg_pipeline.meta["outputs"]["affine"]
99
+ except (ValueError, AssertionError, TypeError):
100
+ logging.warning(
101
+ "xDEM coregistration failed. This can happen when sensor "
102
+ "images are too small. No shift will be applied on DEM"
103
+ )
104
+ coreg_offsets = None
105
+
106
+ return coreg_offsets
107
+
108
+
109
+ def add_margin(bbox, ratio=1):
110
+ """
111
+ Add margin to a bounding box
112
+ :param bbox: input bounding box
113
+ :type bbox: rasterio.coords.BoundingBox
114
+ :param ratio: factor of bbox size to add to each side of bbox
115
+ :type ratio: float
116
+
117
+ :return: bounding box with margins
118
+ :rtype: rasterio.coords.BoundingBox
119
+ """
120
+ try:
121
+ assert bbox.left < bbox.right
122
+ assert bbox.bottom < bbox.top
123
+ width = bbox.right - bbox.left
124
+ height = bbox.top - bbox.bottom
125
+ new_left = bbox.left - ratio * width
126
+ new_right = bbox.right + ratio * width
127
+ new_bottom = bbox.bottom - ratio * height
128
+ new_top = bbox.top + ratio * height
129
+ new_bbox = BoundingBox(new_left, new_bottom, new_right, new_top)
130
+ except AssertionError:
131
+ logging.warning("Bounding box {} cannot be read".format(bbox))
132
+ new_bbox = bbox
133
+ return new_bbox
134
+
135
+
136
+ def compute_stats(diff):
137
+ """
138
+ Compute and display statistics of difference between two DEM :
139
+ Minimum, median, percentiles and maximum
140
+
141
+ :param diff: altimetric difference between two DEM
142
+ :type diff: numpy.array
143
+
144
+ """
145
+ mini = ("Min", np.nanmin(diff))
146
+ median = ("Median", np.nanmedian(diff))
147
+ p90 = ("p90", np.nanpercentile(diff, 90))
148
+ p95 = ("p95", np.nanpercentile(diff, 95))
149
+ p99 = ("p99", np.nanpercentile(diff, 99))
150
+ maxi = ("Max", np.nanmax(diff))
151
+ logging.info( # pylint: disable=logging-fstring-interpolation
152
+ f"| {mini[0]:6} | {median[0]:6} | {p90[0]:6} | "
153
+ f"{p95[0]:6} | {p99[0]:6} | {maxi[0]:6} |"
154
+ )
155
+ logging.info( # pylint: disable=logging-fstring-interpolation
156
+ f"| {mini[1]:6.2f} | {median[1]:6.2f} | {p90[1]:6.2f} | "
157
+ f"{p95[1]:6.2f} | {p99[1]:6.2f} | {maxi[1]:6.2f} |"
158
+ )
159
+
160
+
161
+ def edit_transform(input_dem, resolution=None, transform=None):
162
+ """
163
+ Change transform of an image
164
+ :param input_res: path of image
165
+ :type input_dem: str
166
+ :param resolution: image resolution for new transform to apply
167
+ :type resolution: float
168
+ :param transform: new transform to apply if resolution is not given
169
+ :type transform: affine.Affine
170
+ """
171
+ if resolution is not None:
172
+ if transform is None:
173
+ transform = Affine.from_gdal(0, resolution, 0, 0, 0, resolution)
174
+ else:
175
+ raise ValueError(
176
+ "Function edit_transform take resolution or "
177
+ "transform as parameter but not both"
178
+ )
179
+ with rio.open(input_dem, "r+") as in_dem:
180
+ previous_transform = in_dem.transform
181
+ in_dem.transform = transform
182
+ return previous_transform
183
+
184
+
185
+ def reverse_dem(input_dem):
186
+ """
187
+ Compute the opposite of a DEM :
188
+ Altitudes sign is changed
189
+
190
+ :param input_dem: path of DEM to reverse
191
+ :type input_dem: str
192
+ """
193
+ with rio.open(input_dem, "r") as in_dem:
194
+ data = in_dem.read()
195
+ metadata = in_dem.meta
196
+ nodata = in_dem.nodata
197
+ with rio.open(input_dem, "w", **metadata) as out_dem:
198
+ out_dem.write(-data)
199
+ out_dem.nodata = -nodata
200
+
201
+
202
+ def downsample_dem(
203
+ input_dem,
204
+ scale,
205
+ interpolator,
206
+ median_filter_size=None,
207
+ default_alt=0,
208
+ ):
209
+ """
210
+ Downsample median DEM with median resampling
211
+
212
+ :param input_dem: path of DEM to downsample (only one band)
213
+ :type input_dem: str
214
+ """
215
+ with rio.open(input_dem) as in_dem:
216
+ data = in_dem.read(1)
217
+ metadata = in_dem.meta
218
+ src_transform = in_dem.transform
219
+ width = in_dem.width
220
+ height = in_dem.height
221
+ crs = in_dem.crs
222
+ nodata = in_dem.nodata
223
+
224
+ dst_transform = src_transform * Affine.scale(scale)
225
+ dst_height = int(height // scale) + 1
226
+ dst_width = int(width // scale) + 1
227
+ metadata["transform"] = dst_transform
228
+ metadata["height"] = dst_height
229
+ metadata["width"] = dst_width
230
+ dem_data = np.zeros((dst_height, dst_width))
231
+ interpolator_dict = {
232
+ "min": Resampling.min,
233
+ "median": Resampling.med,
234
+ "max": Resampling.max,
235
+ "nearest": Resampling.nearest,
236
+ }
237
+ interpolator = interpolator_dict[interpolator]
238
+ reproject(
239
+ data,
240
+ dem_data,
241
+ src_transform=src_transform,
242
+ src_crs=crs,
243
+ dst_transform=dst_transform,
244
+ dst_crs=crs,
245
+ dst_nodata=nodata,
246
+ resampling=interpolator,
247
+ )
248
+
249
+ # Post-processing
250
+
251
+ # Median filter
252
+ if median_filter_size is not None:
253
+ dem_data = median_filter(dem_data, size=median_filter_size)
254
+
255
+ # Fill nodata
256
+ dem_data = rio.fill.fillnodata(
257
+ dem_data,
258
+ mask=~(dem_data == nodata),
259
+ )
260
+
261
+ dem_data[dem_data == nodata] = default_alt
262
+
263
+ with rio.open(input_dem, "w", **metadata) as dst:
264
+ dst.write(dem_data, 1)
265
+
266
+
267
+ def modify_terrain_bounds(terrain_bounds, linear_margin, constant_margin):
268
+ """
269
+ Modify the terrain bounds
270
+
271
+ :param terrain_bounds: Input region of interest for DEM
272
+ :type terrain_bounds: list
273
+ :param margin: Margin of the output ROI in meters
274
+ :type margin: int
275
+ """
276
+ xsize = terrain_bounds[2] - terrain_bounds[0]
277
+ ysize = terrain_bounds[3] - terrain_bounds[1]
278
+ xmin = terrain_bounds[0] - linear_margin * xsize - constant_margin
279
+ ymin = terrain_bounds[1] - linear_margin * ysize - constant_margin
280
+ xmax = terrain_bounds[2] + linear_margin * xsize + constant_margin
281
+ ymax = terrain_bounds[3] + linear_margin * ysize + constant_margin
282
+
283
+ terrain_bounds = [xmin, ymin, xmax, ymax]
284
+
285
+ return terrain_bounds
286
+
287
+
288
+ def reproject_dem(dsm_file_name, epsg_out, out_file_name):
289
+ """
290
+ Reproject the DEM
291
+
292
+ :param dsm_file_name: the path to dsm
293
+ :type dsm_file_name: str
294
+ :param epsg_out: the epsg code
295
+ :type epsg_out: int
296
+ :param out_file_name: the out path file
297
+ :type out_file_name: str
298
+ """
299
+ with rio.open(dsm_file_name) as src:
300
+ transform, width, height = calculate_default_transform(
301
+ src.crs, epsg_out, src.width, src.height, *src.bounds
302
+ )
303
+ kwargs = src.meta.copy()
304
+ kwargs.update(
305
+ {
306
+ "crs": epsg_out,
307
+ "transform": transform,
308
+ "width": width,
309
+ "height": height,
310
+ }
311
+ )
312
+
313
+ with rio.open(out_file_name, "w", **kwargs) as dst:
314
+ for i in range(1, src.count + 1):
315
+ reproject(
316
+ source=rio.band(src, i),
317
+ destination=rio.band(dst, i),
318
+ src_transform=src.transform,
319
+ src_crs=src.crs,
320
+ dst_transform=transform,
321
+ dst_crs=epsg_out,
322
+ resampling=Resampling.nearest,
323
+ )
@@ -0,0 +1,30 @@
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 fill disparity map module init file
23
+ """
24
+ # flake8: noqa: F401
25
+
26
+ from cars.applications.dense_match_filling.abstract_dense_match_filling_app import ( # pylint: disable=C0301
27
+ DenseMatchFilling,
28
+ )
29
+
30
+ from . import zero_padding_app