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,528 @@
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 statistical point removal application class.
23
+ """
24
+
25
+
26
+ import copy
27
+
28
+ # Standard imports
29
+ import logging
30
+ import os
31
+
32
+ import numpy as np
33
+
34
+ # Third party imports
35
+ from json_checker import And, Checker, Or
36
+ from pyproj import CRS
37
+
38
+ # CARS imports
39
+ import cars.orchestrator.orchestrator as ocht
40
+ from cars.applications import application_constants
41
+ from cars.applications.point_cloud_outlier_removal import (
42
+ abstract_outlier_removal_app as pc_removal,
43
+ )
44
+ from cars.applications.point_cloud_outlier_removal import (
45
+ outlier_removal_algo,
46
+ )
47
+ from cars.applications.triangulation import pc_transform
48
+ from cars.applications.triangulation.triangulation_wrappers import (
49
+ generate_point_cloud_file_names,
50
+ )
51
+ from cars.core import constants as cst
52
+ from cars.core import projection
53
+ from cars.data_structures import cars_dataset
54
+
55
+ # R0903 temporary disabled for error "Too few public methods"
56
+ # œgoing to be corrected by adding new methods as check_conf
57
+
58
+
59
+ class Statistical(
60
+ pc_removal.PointCloudOutlierRemoval, short_name="statistical"
61
+ ): # pylint: disable=R0903
62
+ """
63
+ Statistical
64
+ """
65
+
66
+ # pylint: disable=too-many-instance-attributes
67
+
68
+ def __init__(self, scaling_coeff, conf=None):
69
+ """
70
+ Init function of Statistical
71
+
72
+ :param scaling_coeff: scaling factor for resolution
73
+ :type scaling_coeff: float
74
+ :param conf: configuration for points outlier removal
75
+ :return: a application_to_use object
76
+ """
77
+
78
+ super().__init__(scaling_coeff, conf=conf)
79
+
80
+ self.used_method = self.used_config["method"]
81
+
82
+ # statistical outliers
83
+ self.k = self.used_config["k"]
84
+ self.filtering_constant = self.used_config["filtering_constant"]
85
+ self.mean_factor = self.used_config["mean_factor"]
86
+ self.std_dev_factor = self.used_config["std_dev_factor"]
87
+ self.use_median = self.used_config["use_median"]
88
+ self.half_epipolar_size = self.used_config["half_epipolar_size"]
89
+
90
+ # Saving files
91
+ self.save_intermediate_data = self.used_config["save_intermediate_data"]
92
+ # Init orchestrator
93
+ self.orchestrator = None
94
+
95
+ def check_conf(self, conf):
96
+ """
97
+ Check configuration
98
+
99
+ :param conf: configuration to check
100
+ :type conf: dict
101
+
102
+ :return: overloaded configuration
103
+ :rtype: dict
104
+
105
+ """
106
+
107
+ # init conf
108
+ if conf is not None:
109
+ overloaded_conf = conf.copy()
110
+ else:
111
+ conf = {}
112
+ overloaded_conf = {}
113
+
114
+ # Overload conf
115
+ overloaded_conf["method"] = conf.get("method", "statistical")
116
+
117
+ overloaded_conf[application_constants.SAVE_INTERMEDIATE_DATA] = (
118
+ conf.get(application_constants.SAVE_INTERMEDIATE_DATA, False)
119
+ )
120
+ overloaded_conf["use_median"] = conf.get("use_median", True)
121
+
122
+ # statistical outlier filtering
123
+ # k: number of neighbors
124
+ overloaded_conf["k"] = conf.get("k", 50)
125
+ # filtering_constant: constant to apply in the distance threshold
126
+ # computation
127
+ overloaded_conf["filtering_constant"] = conf.get(
128
+ "filtering_constant", 0.0
129
+ )
130
+ # mean_factor: factor to apply to the mean in the distance threshold
131
+ # computation
132
+ overloaded_conf["mean_factor"] = conf.get("mean_factor", 1.3)
133
+ # mean_factor: factor to apply to the standard deviation in the
134
+ # distance threshold
135
+ overloaded_conf["std_dev_factor"] = conf.get("std_dev_factor", 3.0)
136
+
137
+ # half_epipolar_size:
138
+ # Half size of the epipolar window used for neighobr search (depth map
139
+ # input only)
140
+ overloaded_conf["half_epipolar_size"] = conf.get(
141
+ "half_epipolar_size", 5
142
+ )
143
+
144
+ point_cloud_outlier_removal_schema = {
145
+ "method": str,
146
+ "k": And(int, lambda x: x > 0),
147
+ "filtering_constant": And(Or(float, int), lambda x: x >= 0),
148
+ "mean_factor": And(Or(float, int), lambda x: x >= 0),
149
+ "std_dev_factor": And(Or(float, int), lambda x: x >= 0),
150
+ "use_median": bool,
151
+ "half_epipolar_size": int,
152
+ application_constants.SAVE_INTERMEDIATE_DATA: bool,
153
+ }
154
+
155
+ # Check conf
156
+ checker = Checker(point_cloud_outlier_removal_schema)
157
+ checker.validate(overloaded_conf)
158
+
159
+ return overloaded_conf
160
+
161
+ def get_optimal_tile_size(
162
+ self,
163
+ max_ram_per_worker,
164
+ superposing_point_clouds=1,
165
+ point_cloud_resolution=0.5,
166
+ ):
167
+ """
168
+ Get the optimal tile size to use, depending on memory available
169
+
170
+ :param max_ram_per_worker: maximum ram available
171
+ :type max_ram_per_worker: int
172
+ :param superposing_point_clouds: number of point clouds superposing
173
+ :type superposing_point_clouds: int
174
+ :param point_cloud_resolution: resolution of point cloud
175
+ :type point_cloud_resolution: float
176
+
177
+ :return: optimal tile size in meter
178
+ :rtype: float
179
+
180
+ """
181
+
182
+ tot = 10000 * superposing_point_clouds / point_cloud_resolution
183
+
184
+ import_ = 200 # MiB
185
+ tile_size = int(
186
+ np.sqrt(float(((max_ram_per_worker - import_) * 2**23)) / tot)
187
+ )
188
+
189
+ logging.info(
190
+ "Estimated optimal tile size for statistical "
191
+ "removal: {} meters".format(tile_size)
192
+ )
193
+
194
+ return tile_size
195
+
196
+ def get_method(self):
197
+ """
198
+ Get margins to use during point clouds fusion
199
+
200
+ :return: algorithm method
201
+ :rtype: string
202
+
203
+ """
204
+
205
+ return self.used_method
206
+
207
+ def get_epipolar_margin(self):
208
+ """
209
+ Get epipolar margin to use
210
+
211
+ :return: margin
212
+ :rtype: int
213
+ """
214
+ margin = self.half_epipolar_size
215
+
216
+ return margin
217
+
218
+ def get_on_ground_margin(self, resolution=0.5):
219
+ """
220
+ Get margins to use during point clouds fusion
221
+
222
+ :return: margin
223
+ :rtype: float
224
+
225
+ """
226
+
227
+ return 0
228
+
229
+ def run( # pylint: disable=too-many-positional-arguments
230
+ self,
231
+ merged_point_cloud,
232
+ orchestrator=None,
233
+ depth_map_dir=None,
234
+ point_cloud_dir=None,
235
+ dump_dir=None,
236
+ epsg=None,
237
+ ):
238
+ """
239
+ Run PointCloudOutlierRemoval application.
240
+
241
+ Creates a CarsDataset filled with new point cloud tiles.
242
+
243
+ :param merged_point_cloud: merged point cloud. CarsDataset contains:
244
+
245
+ - Z x W Delayed tiles. \
246
+ Each tile will be a future pandas DataFrame containing:
247
+
248
+ - data : with keys : "x", "y", "z", "corr_msk" \
249
+ optional: "clr", "msk", "data_valid","coord_epi_geom_i",\
250
+ "coord_epi_geom_j", "idx_im_epi"
251
+ - attrs with keys: "epsg"
252
+ - attributes containing "bounds", "ysize", "xsize", "epsg"
253
+
254
+ :type merged_point_cloud: CarsDataset filled with pandas.DataFrame
255
+ :param orchestrator: orchestrator used
256
+ :param depth_map_dir: output depth map directory. If None output will
257
+ be written in dump_dir if intermediate data is requested
258
+ :type depth_map_dir: str
259
+ :param point_cloud_dir: output depth map directory. If None output will
260
+ be written in dump_dir if intermediate data is requested
261
+ :type point_cloud_dir: str
262
+ :param dump_dir: dump dir for output (except depth map) if intermediate
263
+ data is requested
264
+ :type dump_dir: str
265
+ :param epsg: cartographic reference for the point cloud (array input)
266
+ :type epsg: int
267
+
268
+ :return: filtered merged point cloud. CarsDataset contains:
269
+
270
+ - Z x W Delayed tiles. \
271
+ Each tile will be a future pandas DataFrame containing:
272
+
273
+ - data : with keys "x", "y", "z", "corr_msk" \
274
+ optional: "clr", "msk", "data_valid", "coord_epi_geom_i",\
275
+ "coord_epi_geom_j", "idx_im_epi"
276
+ - attrs with keys: "epsg"
277
+ - attributes containing "bounds", "ysize", "xsize", "epsg"
278
+
279
+ :rtype : CarsDataset filled with xr.Dataset
280
+ """
281
+
282
+ # Default orchestrator
283
+ if orchestrator is None:
284
+ # Create default sequential orchestrator for current application
285
+ # be awere, no out_json will be shared between orchestrators
286
+ # No files saved
287
+ self.orchestrator = ocht.Orchestrator(
288
+ orchestrator_conf={"mode": "sequential"}
289
+ )
290
+ else:
291
+ self.orchestrator = orchestrator
292
+
293
+ if dump_dir is None:
294
+ dump_dir = self.generate_unknown_dump_dir(self.orchestrator)
295
+
296
+ if merged_point_cloud.dataset_type != "arrays":
297
+ raise RuntimeError(
298
+ "Only arrays is supported in statistical removal"
299
+ )
300
+
301
+ prefix = os.path.basename(dump_dir)
302
+ # Save as depth map
303
+ filtered_point_cloud, saving_info_epipolar = (
304
+ self.__register_epipolar_dataset__(
305
+ merged_point_cloud,
306
+ depth_map_dir,
307
+ dump_dir,
308
+ app_name="statistical",
309
+ pair_key=prefix,
310
+ )
311
+ )
312
+
313
+ # Save as point cloud
314
+ (
315
+ flatten_filtered_point_cloud,
316
+ laz_pc_dir_name,
317
+ csv_pc_dir_name,
318
+ saving_info_flatten,
319
+ ) = self.__register_pc_dataset__(
320
+ merged_point_cloud,
321
+ point_cloud_dir,
322
+ dump_dir,
323
+ app_name="statistical",
324
+ )
325
+
326
+ # initialize empty index file for point cloud product if official
327
+ # product is requested
328
+ pc_index = None
329
+ if point_cloud_dir:
330
+ pc_index = {}
331
+
332
+ # Generate rasters
333
+ for col in range(filtered_point_cloud.shape[1]):
334
+ for row in range(filtered_point_cloud.shape[0]):
335
+
336
+ # update saving infos for potential replacement
337
+ full_saving_info_epipolar = ocht.update_saving_infos(
338
+ saving_info_epipolar, row=row, col=col
339
+ )
340
+ full_saving_info_flatten = None
341
+ if saving_info_flatten is not None:
342
+ full_saving_info_flatten = ocht.update_saving_infos(
343
+ saving_info_flatten, row=row, col=col
344
+ )
345
+
346
+ if merged_point_cloud[row][col] is not None:
347
+ csv_pc_file_name, laz_pc_file_name = (
348
+ generate_point_cloud_file_names(
349
+ csv_pc_dir_name,
350
+ laz_pc_dir_name,
351
+ row,
352
+ col,
353
+ pc_index,
354
+ pair_key=prefix,
355
+ )
356
+ )
357
+ window = merged_point_cloud.tiling_grid[row, col]
358
+ overlap = filtered_point_cloud.overlaps[row, col]
359
+ # Delayed call to cloud filtering
360
+ (
361
+ filtered_point_cloud[row, col],
362
+ flatten_filtered_point_cloud[row, col],
363
+ ) = self.orchestrator.cluster.create_task(
364
+ epipolar_statistical_removal_wrapper, nout=2
365
+ )(
366
+ merged_point_cloud[row, col],
367
+ self.k,
368
+ self.filtering_constant,
369
+ self.mean_factor,
370
+ self.std_dev_factor,
371
+ self.use_median,
372
+ self.half_epipolar_size,
373
+ window,
374
+ overlap,
375
+ epsg=epsg,
376
+ point_cloud_csv_file_name=csv_pc_file_name,
377
+ point_cloud_laz_file_name=laz_pc_file_name,
378
+ saving_info_epipolar=full_saving_info_epipolar,
379
+ saving_info_flatten=full_saving_info_flatten,
380
+ )
381
+
382
+ # update point cloud index
383
+ if point_cloud_dir:
384
+ self.orchestrator.update_index(pc_index)
385
+
386
+ return filtered_point_cloud
387
+
388
+
389
+ # pylint: disable=too-many-positional-arguments
390
+ def epipolar_statistical_removal_wrapper(
391
+ epipolar_ds,
392
+ statistical_k,
393
+ filtering_constant,
394
+ mean_factor,
395
+ std_dev_factor,
396
+ use_median,
397
+ half_epipolar_size,
398
+ window,
399
+ overlap,
400
+ epsg,
401
+ point_cloud_csv_file_name=None,
402
+ point_cloud_laz_file_name=None,
403
+ saving_info_epipolar=None,
404
+ saving_info_flatten=None,
405
+ ):
406
+ """
407
+ Statistical outlier removal in epipolar geometry
408
+
409
+ :param epipolar_ds: epipolar dataset to filter
410
+ :type epipolar_ds: xr.Dataset
411
+ :param statistical_k: k
412
+ :type statistical_k: int
413
+ :param filtering_constant: constant applied to the threshold
414
+ :type filtering_constant: float
415
+ :param mean_factor: mean factor
416
+ :type mean_factor: float
417
+ :param std_dev_factor: std factor
418
+ :type std_dev_factor: float
419
+ :param use_median: use median and quartile instead of mean and std
420
+ :type use median: bool
421
+ :param half_epipolar_size: half size of the window used to search neighbors
422
+ :type half_epipolar_size: int
423
+ :param window: window of base tile [row min, row max, col min col max]
424
+ :type window: list
425
+ :param overlap: overlap [row min, row max, col min col max]
426
+ :type overlap: list
427
+ :param epsg: epsg code of the CRS used to compute distances
428
+ :type epsg: int
429
+
430
+ :return: filtered dataset
431
+ :rtype: xr.Dataset
432
+
433
+ """
434
+
435
+ # Copy input cloud
436
+ filtered_cloud = copy.copy(epipolar_ds)
437
+
438
+ # Get current epsg
439
+ cloud_epsg = filtered_cloud.attrs["epsg"]
440
+ current_epsg = cloud_epsg
441
+
442
+ # Check if can be used to filter
443
+ spatial_ref = CRS.from_epsg(cloud_epsg)
444
+ if spatial_ref.is_geographic:
445
+ logging.debug(
446
+ "The point cloud to filter is not in a cartographic system. "
447
+ "The filter's default parameters might not be adapted "
448
+ "to this referential. Please, convert the point "
449
+ "cloud to ECEF to ensure a proper point_cloud."
450
+ )
451
+ # Convert to epsg = 4978
452
+ cartographic_epsg = 4978
453
+
454
+ projection.point_cloud_conversion_dataset(
455
+ filtered_cloud, cartographic_epsg
456
+ )
457
+ current_epsg = cartographic_epsg
458
+
459
+ outlier_removal_algo.epipolar_statistical_filtering(
460
+ filtered_cloud,
461
+ k=statistical_k,
462
+ filtering_constant=filtering_constant,
463
+ mean_factor=mean_factor,
464
+ dev_factor=std_dev_factor,
465
+ use_median=use_median,
466
+ half_window_size=half_epipolar_size,
467
+ )
468
+
469
+ # Fill with attributes
470
+ cars_dataset.fill_dataset(
471
+ filtered_cloud,
472
+ saving_info=saving_info_epipolar,
473
+ window=cars_dataset.window_array_to_dict(window),
474
+ profile=None,
475
+ attributes=None,
476
+ overlaps=cars_dataset.overlap_array_to_dict(overlap),
477
+ )
478
+
479
+ # Flatten point cloud to save it as LAZ
480
+ flatten_filtered_cloud = None
481
+ if point_cloud_csv_file_name or point_cloud_laz_file_name:
482
+ # Convert epipolar array into point cloud
483
+ flatten_filtered_cloud, cloud_epsg = (
484
+ pc_transform.depth_map_dataset_to_dataframe(
485
+ filtered_cloud, current_epsg
486
+ )
487
+ )
488
+ # Convert to wanted epsg
489
+ if epsg is not None and cloud_epsg != epsg:
490
+ projection.point_cloud_conversion_dataframe(
491
+ flatten_filtered_cloud, cloud_epsg, epsg
492
+ )
493
+ cloud_epsg = epsg
494
+
495
+ # Fill attributes for LAZ saving
496
+ color_type = pc_transform.get_color_type([filtered_cloud])
497
+ attributes = {
498
+ "epsg": cloud_epsg,
499
+ "color_type": color_type,
500
+ cst.CROPPED_DISPARITY_RANGE: ocht.get_disparity_range_cropped(
501
+ epipolar_ds
502
+ ),
503
+ }
504
+ cars_dataset.fill_dataframe(
505
+ flatten_filtered_cloud,
506
+ saving_info=saving_info_flatten,
507
+ attributes=attributes,
508
+ )
509
+
510
+ # Save point cloud in worker
511
+ if point_cloud_csv_file_name:
512
+ cars_dataset.run_save_points(
513
+ flatten_filtered_cloud,
514
+ point_cloud_csv_file_name,
515
+ overwrite=True,
516
+ point_cloud_format="csv",
517
+ overwrite_file_name=False,
518
+ )
519
+ if point_cloud_laz_file_name:
520
+ cars_dataset.run_save_points(
521
+ flatten_filtered_cloud,
522
+ point_cloud_laz_file_name,
523
+ overwrite=True,
524
+ point_cloud_format="laz",
525
+ overwrite_file_name=False,
526
+ )
527
+
528
+ return filtered_cloud, flatten_filtered_cloud
@@ -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 rasterization module init file
23
+ """
24
+ # flake8: noqa: F401
25
+
26
+ from cars.applications.rasterization.abstract_pc_rasterization_app import (
27
+ PointCloudRasterization,
28
+ )
29
+
30
+ from . import simple_gaussian_app