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,101 @@
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 abstract dsm filling application class.
23
+ """
24
+ import logging
25
+ from abc import ABCMeta, abstractmethod
26
+ from typing import Dict
27
+
28
+ from cars.applications.application import Application
29
+ from cars.applications.application_template import ApplicationTemplate
30
+
31
+
32
+ @Application.register("dsm_filling")
33
+ class DsmFilling(ApplicationTemplate, metaclass=ABCMeta):
34
+ """
35
+ DsmFilling
36
+ """
37
+
38
+ available_applications: Dict = {}
39
+ default_application = "bulldozer"
40
+
41
+ def __new__(cls, conf=None): # pylint: disable=W0613
42
+ """
43
+ Return the required application
44
+ :raises:
45
+ - KeyError when the required application is not registered
46
+
47
+ :param orchestrator: orchestrator used
48
+ :param conf: configuration for filling
49
+ :return: an application_to_use object
50
+ """
51
+
52
+ dsm_filling_method = cls.default_application
53
+ if bool(conf) is False:
54
+ logging.info(
55
+ "dsm_filling method not specified, default"
56
+ " {} is used".format(dsm_filling_method)
57
+ )
58
+ else:
59
+ dsm_filling_method = conf["method"]
60
+
61
+ if dsm_filling_method not in cls.available_applications:
62
+ logging.error(
63
+ "No dsm_filling application named {} registered".format(
64
+ dsm_filling_method
65
+ )
66
+ )
67
+ raise KeyError(
68
+ "No dsm_filling application named {} registered".format(
69
+ dsm_filling_method
70
+ )
71
+ )
72
+
73
+ logging.info(
74
+ "The DsmFilling {} application will be used".format(
75
+ dsm_filling_method
76
+ )
77
+ )
78
+
79
+ return super(DsmFilling, cls).__new__(
80
+ cls.available_applications[dsm_filling_method]
81
+ )
82
+
83
+ def __init_subclass__(cls, short_name, **kwargs): # pylint: disable=E0302
84
+ super().__init_subclass__(**kwargs)
85
+ cls.available_applications[short_name] = cls
86
+
87
+ def __init__(self, conf=None):
88
+ """
89
+ Init function of DSM Filling
90
+
91
+ :param conf: configuration
92
+ :return: an application_to_use object
93
+ """
94
+
95
+ super().__init__(conf=conf)
96
+
97
+ @abstractmethod
98
+ def run(self):
99
+ """
100
+ Run dsm filling using initial elevation and the current dsm
101
+ """
@@ -0,0 +1,278 @@
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 border interpolation dsm filling application class.
23
+ """
24
+
25
+ import logging
26
+ import os
27
+ import shutil
28
+ import warnings
29
+
30
+ import numpy as np
31
+ import rasterio as rio
32
+ import scipy
33
+ import skimage
34
+ from json_checker import Checker, Or
35
+ from pyproj import CRS
36
+ from rasterio.errors import NodataShadowWarning
37
+ from shapely import Polygon
38
+
39
+ from cars.core import inputs, projection
40
+ from cars.orchestrator.cluster.log_wrapper import cars_profile
41
+
42
+ from .abstract_dsm_filling_app import DsmFilling
43
+
44
+
45
+ class BorderInterpolation(DsmFilling, short_name="border_interpolation"):
46
+ """
47
+ Border interpolation
48
+ """
49
+
50
+ def __init__(self, conf=None):
51
+ """
52
+ Init function of BorderInterpolation
53
+
54
+ :param conf: configuration for BulldozerFilling
55
+ :return: an application_to_use object
56
+ """
57
+ super().__init__(conf=conf)
58
+
59
+ # check conf
60
+ self.used_method = self.used_config["method"]
61
+ self.classification = self.used_config["classification"]
62
+ self.component_min_size = self.used_config["component_min_size"]
63
+ self.border_size = self.used_config["border_size"]
64
+ self.percentile = self.used_config["percentile"]
65
+ self.save_intermediate_data = self.used_config["save_intermediate_data"]
66
+
67
+ def check_conf(self, conf):
68
+
69
+ # init conf
70
+ if conf is not None:
71
+ overloaded_conf = conf.copy()
72
+ else:
73
+ conf = {}
74
+ overloaded_conf = {}
75
+
76
+ # Overload conf
77
+ overloaded_conf["method"] = conf.get("method", "border_interpolation")
78
+ overloaded_conf["classification"] = conf.get("classification", "nodata")
79
+ if isinstance(overloaded_conf["classification"], str):
80
+ overloaded_conf["classification"] = [
81
+ overloaded_conf["classification"]
82
+ ]
83
+ overloaded_conf["component_min_size"] = conf.get(
84
+ "component_min_size", 5
85
+ )
86
+ overloaded_conf["border_size"] = conf.get("border_size", 10)
87
+ overloaded_conf["percentile"] = conf.get("percentile", 10)
88
+ overloaded_conf["save_intermediate_data"] = conf.get(
89
+ "save_intermediate_data", False
90
+ )
91
+
92
+ rectification_schema = {
93
+ "method": str,
94
+ "classification": Or(None, [str]),
95
+ "component_min_size": int,
96
+ "border_size": int,
97
+ "percentile": Or(int, float),
98
+ "save_intermediate_data": bool,
99
+ }
100
+
101
+ # Check conf
102
+ checker = Checker(rectification_schema)
103
+ checker.validate(overloaded_conf)
104
+
105
+ return overloaded_conf
106
+
107
+ @cars_profile(name="Border interpolation filling")
108
+ def run( # pylint: disable=too-many-positional-arguments # noqa C901
109
+ self,
110
+ dsm_file,
111
+ classif_file,
112
+ filling_file,
113
+ dtm_file,
114
+ dump_dir,
115
+ roi_polys,
116
+ roi_epsg,
117
+ dsm_dir=None,
118
+ ):
119
+ """
120
+ Run dsm filling using initial elevation and the current dsm
121
+ Replaces dsm.tif by the filled dsm. Adds a new band
122
+ to filling.tif if it exists.
123
+ The old dsm is saved in dump_dir.
124
+
125
+ roi_poly can any of these objects :
126
+ - a list of Shapely Polygons
127
+ - a Shapely Polygon
128
+ """
129
+
130
+ if dsm_dir is not None:
131
+ dsm_path_out = os.path.join(dsm_dir, "dsm.tif")
132
+ filling_path_out = os.path.join(dsm_dir, "filling.tif")
133
+ else:
134
+ dsm_path_out = dsm_file
135
+ filling_path_out = filling_file
136
+
137
+ if self.classification is None:
138
+ self.classification = ["nodata"]
139
+ logging.error(
140
+ "Filling method 'border_interpolation' needs a classification"
141
+ )
142
+
143
+ if not os.path.exists(dump_dir):
144
+ os.makedirs(dump_dir)
145
+
146
+ old_dsm_path = os.path.join(dump_dir, "dsm_not_filled.tif")
147
+ new_dsm_path = os.path.join(dump_dir, "dsm_filled.tif")
148
+
149
+ # get dsm to be filled and its metadata
150
+ with rio.open(dsm_file) as in_dsm:
151
+ dsm = in_dsm.read(1)
152
+ dsm_tr = in_dsm.transform
153
+ dsm_crs = in_dsm.crs
154
+ dsm_meta = in_dsm.meta
155
+ dsm_nodata = in_dsm.nodata
156
+
157
+ roi_raster = np.ones(dsm.shape)
158
+
159
+ if isinstance(roi_polys, list):
160
+ roi_polys_outepsg = []
161
+ for poly in roi_polys:
162
+ if isinstance(poly, Polygon):
163
+ roi_poly_outepsg = projection.polygon_projection_crs(
164
+ poly, CRS(roi_epsg), dsm_crs
165
+ )
166
+ roi_polys_outepsg.append(roi_poly_outepsg)
167
+
168
+ roi_raster = rio.features.rasterize(
169
+ roi_polys_outepsg, out_shape=roi_raster.shape, transform=dsm_tr
170
+ )
171
+ elif isinstance(roi_polys, Polygon):
172
+ roi_poly_outepsg = projection.polygon_projection_crs(
173
+ roi_polys, CRS(roi_epsg), dsm_crs
174
+ )
175
+ roi_raster = rio.features.rasterize(
176
+ [roi_poly_outepsg], out_shape=roi_raster.shape, transform=dsm_tr
177
+ )
178
+
179
+ # get dtm to fill the dsm
180
+ if dtm_file is not None:
181
+ logging.info(
182
+ "Use DTM file {} for border interpolation".format(dtm_file)
183
+ )
184
+ with rio.open(dtm_file) as in_dtm:
185
+ dtm = in_dtm.read(1)
186
+ dtm_nodata = in_dtm.nodata
187
+ else:
188
+ logging.info(
189
+ "No DTM provided : DSM {} will be used for "
190
+ "border interpolation".format(dsm_file)
191
+ )
192
+ dtm = dsm.copy()
193
+ dtm_nodata = dsm_nodata
194
+ dtm[dtm == dtm_nodata] = np.nan
195
+
196
+ if self.save_intermediate_data:
197
+ with rio.open(old_dsm_path, "w", **dsm_meta) as out_dsm:
198
+ out_dsm.write(dsm, 1)
199
+
200
+ if classif_file is not None:
201
+ classif_descriptions = inputs.get_descriptions_bands(classif_file)
202
+ else:
203
+ classif_descriptions = []
204
+ combined_mask = np.zeros_like(dsm).astype(np.uint8)
205
+ for label in self.classification:
206
+ if label in classif_descriptions:
207
+ index_classif = classif_descriptions.index(label) + 1
208
+ with rio.open(classif_file) as in_classif:
209
+ classif = in_classif.read(index_classif)
210
+
211
+ with warnings.catch_warnings():
212
+ warnings.simplefilter("ignore", NodataShadowWarning)
213
+ classif_msk = in_classif.read_masks(1)
214
+
215
+ classif[classif_msk == 0] = 0
216
+ filling_mask = np.logical_and(classif, roi_raster > 0)
217
+ else:
218
+ logging.error(
219
+ "Label {} not found in classification "
220
+ "descriptions {}".format(label, classif_descriptions)
221
+ )
222
+ continue
223
+ logging.info(
224
+ "Filling of {} with Bulldozer DTM using "
225
+ "border interpolation".format(label)
226
+ )
227
+ filling_mask[classif_msk == 0] = 0
228
+ filling_mask = skimage.morphology.binary_opening(
229
+ filling_mask,
230
+ footprint=[
231
+ (np.ones((self.component_min_size, 1)), 1),
232
+ (np.ones((1, self.component_min_size)), 1),
233
+ ],
234
+ )
235
+ features, num_features = scipy.ndimage.label(filling_mask)
236
+ logging.info("Filling of {} features".format(num_features))
237
+ features_boundaries = skimage.morphology.dilation(
238
+ features,
239
+ footprint=[
240
+ (np.ones((self.border_size, 1)), 1),
241
+ (np.ones((1, self.border_size)), 1),
242
+ ],
243
+ )
244
+ features_boundaries[filling_mask] = 0
245
+ borders_file_path = os.path.join(
246
+ dump_dir, "borders_of_{}.tif".format(label)
247
+ )
248
+ if self.save_intermediate_data:
249
+ with rio.open(
250
+ borders_file_path, "w", **dsm_meta
251
+ ) as out_borders:
252
+ out_borders.write(features_boundaries, 1)
253
+ for feature_id in range(1, num_features + 1):
254
+ altitude = np.nanpercentile(
255
+ dtm[features_boundaries == feature_id], self.percentile
256
+ )
257
+ if altitude is not None:
258
+ dsm[features == feature_id] = altitude
259
+ combined_mask = np.logical_or(combined_mask, filling_mask)
260
+
261
+ with rio.open(dsm_path_out, "w", **dsm_meta) as out_dsm:
262
+ out_dsm.write(dsm, 1)
263
+ if self.save_intermediate_data:
264
+ shutil.copy2(dsm_path_out, new_dsm_path)
265
+
266
+ if filling_file is not None:
267
+ with rio.open(filling_file, "r") as src:
268
+ fill_meta = src.meta
269
+ bands = [src.read(i + 1) for i in range(src.count)]
270
+ bands_desc = [src.descriptions[i] for i in range(src.count)]
271
+ fill_meta["count"] += 1
272
+ bands.append(combined_mask.astype(np.uint8))
273
+ bands_desc.append("border_interpolation")
274
+
275
+ with rio.open(filling_path_out, "w", **fill_meta) as out:
276
+ for i, band in enumerate(bands):
277
+ out.write(band, i + 1)
278
+ out.set_band_description(i + 1, bands_desc[i])
@@ -0,0 +1,44 @@
1
+ # both paths will be overwritten in the filling application
2
+ dsm_path: "path/to/dsm"
3
+ output_dir: "path/to/output"
4
+
5
+ # everything else will be used directly as-is
6
+
7
+ #-------------------------#
8
+ # Options #
9
+ #-------------------------#
10
+
11
+
12
+ max_object_size : 16
13
+ # If True, keep the intermediate results
14
+ developer_mode : False
15
+
16
+
17
+ #-------------------------#
18
+ # Advanced settings #
19
+ #-------------------------#
20
+ # [Optional] - Altimetric height accuracy of the input DSM (m). If null, use the default value: 2*planimetric resolution
21
+ dsm_z_accuracy: null
22
+ # [Optional] - Maximum slope of the observed landscape terrain (%)
23
+ # former slope_threshold
24
+ max_ground_slope: 2.0
25
+ # [Optional] - If True, activate the ground pre-detection
26
+ activate_ground_anchors : False
27
+ # [Optional] - If True, keep the intermediate results
28
+ developer_mode : False
29
+
30
+
31
+ #-------------------------#
32
+ # Bulldozer core settings #
33
+ #-------------------------#
34
+ # /!\ Modify those data at your own risk (it is suggested to keep the default values) /!\
35
+
36
+ # [Optional] - DtmExtraction parameters
37
+ # former uniform_filter_size
38
+ cloth_tension_force : 3
39
+ prevent_unhook_iter : 10
40
+ num_outer_iter : 50
41
+ num_inner_iter : 10
42
+
43
+
44
+