cars 1.0.0rc1__cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.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 (200) hide show
  1. cars/__init__.py +74 -0
  2. cars/applications/__init__.py +37 -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 +104 -0
  8. cars/applications/auxiliary_filling/auxiliary_filling_algo.py +475 -0
  9. cars/applications/auxiliary_filling/auxiliary_filling_from_sensors_app.py +630 -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 +655 -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 +1460 -0
  28. cars/applications/dense_matching/cpp/__init__.py +0 -0
  29. cars/applications/dense_matching/cpp/dense_matching_cpp.cpython-312-i386-linux-gnu.so +0 -0
  30. cars/applications/dense_matching/cpp/dense_matching_cpp.py +94 -0
  31. cars/applications/dense_matching/cpp/includes/dense_matching.hpp +58 -0
  32. cars/applications/dense_matching/cpp/meson.build +9 -0
  33. cars/applications/dense_matching/cpp/src/bindings.cpp +13 -0
  34. cars/applications/dense_matching/cpp/src/dense_matching.cpp +207 -0
  35. cars/applications/dense_matching/dense_matching_algo.py +401 -0
  36. cars/applications/dense_matching/dense_matching_constants.py +89 -0
  37. cars/applications/dense_matching/dense_matching_wrappers.py +951 -0
  38. cars/applications/dense_matching/disparity_grid_algo.py +588 -0
  39. cars/applications/dense_matching/loaders/__init__.py +23 -0
  40. cars/applications/dense_matching/loaders/config_census_sgm_default.json +31 -0
  41. cars/applications/dense_matching/loaders/config_census_sgm_homogeneous.json +30 -0
  42. cars/applications/dense_matching/loaders/config_census_sgm_mountain_and_vegetation.json +30 -0
  43. cars/applications/dense_matching/loaders/config_census_sgm_shadow.json +30 -0
  44. cars/applications/dense_matching/loaders/config_census_sgm_sparse.json +36 -0
  45. cars/applications/dense_matching/loaders/config_census_sgm_urban.json +30 -0
  46. cars/applications/dense_matching/loaders/config_mapping.json +13 -0
  47. cars/applications/dense_matching/loaders/config_mccnn.json +28 -0
  48. cars/applications/dense_matching/loaders/global_land_cover_map.tif +0 -0
  49. cars/applications/dense_matching/loaders/pandora_loader.py +593 -0
  50. cars/applications/dsm_filling/__init__.py +32 -0
  51. cars/applications/dsm_filling/abstract_dsm_filling_app.py +101 -0
  52. cars/applications/dsm_filling/border_interpolation_app.py +270 -0
  53. cars/applications/dsm_filling/bulldozer_config/base_config.yaml +44 -0
  54. cars/applications/dsm_filling/bulldozer_filling_app.py +279 -0
  55. cars/applications/dsm_filling/exogenous_filling_app.py +333 -0
  56. cars/applications/grid_generation/__init__.py +30 -0
  57. cars/applications/grid_generation/abstract_grid_generation_app.py +142 -0
  58. cars/applications/grid_generation/epipolar_grid_generation_app.py +327 -0
  59. cars/applications/grid_generation/grid_correction_app.py +496 -0
  60. cars/applications/grid_generation/grid_generation_algo.py +388 -0
  61. cars/applications/grid_generation/grid_generation_constants.py +46 -0
  62. cars/applications/grid_generation/transform_grid.py +88 -0
  63. cars/applications/ground_truth_reprojection/__init__.py +30 -0
  64. cars/applications/ground_truth_reprojection/abstract_ground_truth_reprojection_app.py +137 -0
  65. cars/applications/ground_truth_reprojection/direct_localization_app.py +629 -0
  66. cars/applications/ground_truth_reprojection/ground_truth_reprojection_algo.py +275 -0
  67. cars/applications/point_cloud_outlier_removal/__init__.py +30 -0
  68. cars/applications/point_cloud_outlier_removal/abstract_outlier_removal_app.py +385 -0
  69. cars/applications/point_cloud_outlier_removal/outlier_removal_algo.py +392 -0
  70. cars/applications/point_cloud_outlier_removal/outlier_removal_constants.py +43 -0
  71. cars/applications/point_cloud_outlier_removal/small_components_app.py +527 -0
  72. cars/applications/point_cloud_outlier_removal/statistical_app.py +531 -0
  73. cars/applications/rasterization/__init__.py +30 -0
  74. cars/applications/rasterization/abstract_pc_rasterization_app.py +183 -0
  75. cars/applications/rasterization/rasterization_algo.py +534 -0
  76. cars/applications/rasterization/rasterization_constants.py +38 -0
  77. cars/applications/rasterization/rasterization_wrappers.py +634 -0
  78. cars/applications/rasterization/simple_gaussian_app.py +1152 -0
  79. cars/applications/resampling/__init__.py +28 -0
  80. cars/applications/resampling/abstract_resampling_app.py +187 -0
  81. cars/applications/resampling/bicubic_resampling_app.py +762 -0
  82. cars/applications/resampling/resampling_algo.py +614 -0
  83. cars/applications/resampling/resampling_constants.py +36 -0
  84. cars/applications/resampling/resampling_wrappers.py +309 -0
  85. cars/applications/sparse_matching/__init__.py +30 -0
  86. cars/applications/sparse_matching/abstract_sparse_matching_app.py +498 -0
  87. cars/applications/sparse_matching/sift_app.py +735 -0
  88. cars/applications/sparse_matching/sparse_matching_algo.py +360 -0
  89. cars/applications/sparse_matching/sparse_matching_constants.py +68 -0
  90. cars/applications/sparse_matching/sparse_matching_wrappers.py +238 -0
  91. cars/applications/triangulation/__init__.py +32 -0
  92. cars/applications/triangulation/abstract_triangulation_app.py +227 -0
  93. cars/applications/triangulation/line_of_sight_intersection_app.py +1243 -0
  94. cars/applications/triangulation/pc_transform.py +552 -0
  95. cars/applications/triangulation/triangulation_algo.py +371 -0
  96. cars/applications/triangulation/triangulation_constants.py +38 -0
  97. cars/applications/triangulation/triangulation_wrappers.py +259 -0
  98. cars/bundleadjustment.py +757 -0
  99. cars/cars.py +177 -0
  100. cars/conf/__init__.py +23 -0
  101. cars/conf/geoid/egm96.grd +0 -0
  102. cars/conf/geoid/egm96.grd.hdr +15 -0
  103. cars/conf/input_parameters.py +156 -0
  104. cars/conf/mask_cst.py +35 -0
  105. cars/core/__init__.py +23 -0
  106. cars/core/cars_logging.py +402 -0
  107. cars/core/constants.py +191 -0
  108. cars/core/constants_disparity.py +50 -0
  109. cars/core/datasets.py +140 -0
  110. cars/core/geometry/__init__.py +27 -0
  111. cars/core/geometry/abstract_geometry.py +1119 -0
  112. cars/core/geometry/shareloc_geometry.py +598 -0
  113. cars/core/inputs.py +568 -0
  114. cars/core/outputs.py +176 -0
  115. cars/core/preprocessing.py +722 -0
  116. cars/core/projection.py +843 -0
  117. cars/core/roi_tools.py +215 -0
  118. cars/core/tiling.py +774 -0
  119. cars/core/utils.py +164 -0
  120. cars/data_structures/__init__.py +23 -0
  121. cars/data_structures/cars_dataset.py +1541 -0
  122. cars/data_structures/cars_dict.py +74 -0
  123. cars/data_structures/corresponding_tiles_tools.py +186 -0
  124. cars/data_structures/dataframe_converter.py +185 -0
  125. cars/data_structures/format_transformation.py +297 -0
  126. cars/devibrate.py +689 -0
  127. cars/extractroi.py +264 -0
  128. cars/orchestrator/__init__.py +23 -0
  129. cars/orchestrator/achievement_tracker.py +125 -0
  130. cars/orchestrator/cluster/__init__.py +37 -0
  131. cars/orchestrator/cluster/abstract_cluster.py +244 -0
  132. cars/orchestrator/cluster/abstract_dask_cluster.py +375 -0
  133. cars/orchestrator/cluster/dask_cluster_tools.py +103 -0
  134. cars/orchestrator/cluster/dask_config/README.md +94 -0
  135. cars/orchestrator/cluster/dask_config/dask.yaml +21 -0
  136. cars/orchestrator/cluster/dask_config/distributed.yaml +70 -0
  137. cars/orchestrator/cluster/dask_config/jobqueue.yaml +26 -0
  138. cars/orchestrator/cluster/dask_config/reference_confs/dask-schema.yaml +137 -0
  139. cars/orchestrator/cluster/dask_config/reference_confs/dask.yaml +26 -0
  140. cars/orchestrator/cluster/dask_config/reference_confs/distributed-schema.yaml +1009 -0
  141. cars/orchestrator/cluster/dask_config/reference_confs/distributed.yaml +273 -0
  142. cars/orchestrator/cluster/dask_config/reference_confs/jobqueue.yaml +212 -0
  143. cars/orchestrator/cluster/dask_jobqueue_utils.py +204 -0
  144. cars/orchestrator/cluster/local_dask_cluster.py +116 -0
  145. cars/orchestrator/cluster/log_wrapper.py +1075 -0
  146. cars/orchestrator/cluster/mp_cluster/__init__.py +27 -0
  147. cars/orchestrator/cluster/mp_cluster/mp_factorizer.py +212 -0
  148. cars/orchestrator/cluster/mp_cluster/mp_objects.py +535 -0
  149. cars/orchestrator/cluster/mp_cluster/mp_tools.py +93 -0
  150. cars/orchestrator/cluster/mp_cluster/mp_wrapper.py +505 -0
  151. cars/orchestrator/cluster/mp_cluster/multiprocessing_cluster.py +873 -0
  152. cars/orchestrator/cluster/mp_cluster/multiprocessing_profiler.py +399 -0
  153. cars/orchestrator/cluster/pbs_dask_cluster.py +207 -0
  154. cars/orchestrator/cluster/sequential_cluster.py +139 -0
  155. cars/orchestrator/cluster/slurm_dask_cluster.py +234 -0
  156. cars/orchestrator/orchestrator.py +905 -0
  157. cars/orchestrator/orchestrator_constants.py +29 -0
  158. cars/orchestrator/registry/__init__.py +23 -0
  159. cars/orchestrator/registry/abstract_registry.py +143 -0
  160. cars/orchestrator/registry/compute_registry.py +106 -0
  161. cars/orchestrator/registry/id_generator.py +116 -0
  162. cars/orchestrator/registry/replacer_registry.py +213 -0
  163. cars/orchestrator/registry/saver_registry.py +363 -0
  164. cars/orchestrator/registry/unseen_registry.py +118 -0
  165. cars/orchestrator/tiles_profiler.py +279 -0
  166. cars/pipelines/__init__.py +26 -0
  167. cars/pipelines/conf_resolution/conf_final_resolution.yaml +5 -0
  168. cars/pipelines/conf_resolution/conf_first_resolution.yaml +2 -0
  169. cars/pipelines/conf_resolution/conf_intermediate_resolution.yaml +2 -0
  170. cars/pipelines/default/__init__.py +26 -0
  171. cars/pipelines/default/default_pipeline.py +786 -0
  172. cars/pipelines/parameters/__init__.py +0 -0
  173. cars/pipelines/parameters/advanced_parameters.py +417 -0
  174. cars/pipelines/parameters/advanced_parameters_constants.py +69 -0
  175. cars/pipelines/parameters/application_parameters.py +71 -0
  176. cars/pipelines/parameters/depth_map_inputs.py +0 -0
  177. cars/pipelines/parameters/dsm_inputs.py +918 -0
  178. cars/pipelines/parameters/dsm_inputs_constants.py +25 -0
  179. cars/pipelines/parameters/output_constants.py +52 -0
  180. cars/pipelines/parameters/output_parameters.py +454 -0
  181. cars/pipelines/parameters/sensor_inputs.py +842 -0
  182. cars/pipelines/parameters/sensor_inputs_constants.py +49 -0
  183. cars/pipelines/parameters/sensor_loaders/__init__.py +29 -0
  184. cars/pipelines/parameters/sensor_loaders/basic_classif_loader.py +86 -0
  185. cars/pipelines/parameters/sensor_loaders/basic_image_loader.py +98 -0
  186. cars/pipelines/parameters/sensor_loaders/pivot_classif_loader.py +90 -0
  187. cars/pipelines/parameters/sensor_loaders/pivot_image_loader.py +105 -0
  188. cars/pipelines/parameters/sensor_loaders/sensor_loader.py +93 -0
  189. cars/pipelines/parameters/sensor_loaders/sensor_loader_template.py +71 -0
  190. cars/pipelines/parameters/sensor_loaders/slurp_classif_loader.py +86 -0
  191. cars/pipelines/pipeline.py +119 -0
  192. cars/pipelines/pipeline_constants.py +31 -0
  193. cars/pipelines/pipeline_template.py +139 -0
  194. cars/pipelines/unit/__init__.py +26 -0
  195. cars/pipelines/unit/unit_pipeline.py +2850 -0
  196. cars/starter.py +167 -0
  197. cars-1.0.0rc1.dist-info/METADATA +292 -0
  198. cars-1.0.0rc1.dist-info/RECORD +200 -0
  199. cars-1.0.0rc1.dist-info/WHEEL +6 -0
  200. cars-1.0.0rc1.dist-info/entry_points.txt +8 -0
@@ -0,0 +1,531 @@
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
+ self.save_by_pair = self.used_config["save_by_pair"]
93
+ # Init orchestrator
94
+ self.orchestrator = None
95
+
96
+ def check_conf(self, conf):
97
+ """
98
+ Check configuration
99
+
100
+ :param conf: configuration to check
101
+ :type conf: dict
102
+
103
+ :return: overloaded configuration
104
+ :rtype: dict
105
+
106
+ """
107
+
108
+ # init conf
109
+ if conf is not None:
110
+ overloaded_conf = conf.copy()
111
+ else:
112
+ conf = {}
113
+ overloaded_conf = {}
114
+
115
+ # Overload conf
116
+ overloaded_conf["method"] = conf.get("method", "statistical")
117
+
118
+ overloaded_conf[application_constants.SAVE_INTERMEDIATE_DATA] = (
119
+ conf.get(application_constants.SAVE_INTERMEDIATE_DATA, False)
120
+ )
121
+ overloaded_conf["save_by_pair"] = conf.get("save_by_pair", False)
122
+ overloaded_conf["use_median"] = conf.get("use_median", True)
123
+
124
+ # statistical outlier filtering
125
+ # k: number of neighbors
126
+ overloaded_conf["k"] = conf.get("k", 50)
127
+ # filtering_constant: constant to apply in the distance threshold
128
+ # computation
129
+ overloaded_conf["filtering_constant"] = conf.get(
130
+ "filtering_constant", 0.0
131
+ )
132
+ # mean_factor: factor to apply to the mean in the distance threshold
133
+ # computation
134
+ overloaded_conf["mean_factor"] = conf.get("mean_factor", 1.3)
135
+ # mean_factor: factor to apply to the standard deviation in the
136
+ # distance threshold
137
+ overloaded_conf["std_dev_factor"] = conf.get("std_dev_factor", 3.0)
138
+
139
+ # half_epipolar_size:
140
+ # Half size of the epipolar window used for neighobr search (depth map
141
+ # input only)
142
+ overloaded_conf["half_epipolar_size"] = conf.get(
143
+ "half_epipolar_size", 5
144
+ )
145
+
146
+ point_cloud_outlier_removal_schema = {
147
+ "method": str,
148
+ "save_by_pair": bool,
149
+ "k": And(int, lambda x: x > 0),
150
+ "filtering_constant": And(Or(float, int), lambda x: x >= 0),
151
+ "mean_factor": And(Or(float, int), lambda x: x >= 0),
152
+ "std_dev_factor": And(Or(float, int), lambda x: x >= 0),
153
+ "use_median": bool,
154
+ "half_epipolar_size": int,
155
+ application_constants.SAVE_INTERMEDIATE_DATA: bool,
156
+ }
157
+
158
+ # Check conf
159
+ checker = Checker(point_cloud_outlier_removal_schema)
160
+ checker.validate(overloaded_conf)
161
+
162
+ return overloaded_conf
163
+
164
+ def get_optimal_tile_size(
165
+ self,
166
+ max_ram_per_worker,
167
+ superposing_point_clouds=1,
168
+ point_cloud_resolution=0.5,
169
+ ):
170
+ """
171
+ Get the optimal tile size to use, depending on memory available
172
+
173
+ :param max_ram_per_worker: maximum ram available
174
+ :type max_ram_per_worker: int
175
+ :param superposing_point_clouds: number of point clouds superposing
176
+ :type superposing_point_clouds: int
177
+ :param point_cloud_resolution: resolution of point cloud
178
+ :type point_cloud_resolution: float
179
+
180
+ :return: optimal tile size in meter
181
+ :rtype: float
182
+
183
+ """
184
+
185
+ tot = 10000 * superposing_point_clouds / point_cloud_resolution
186
+
187
+ import_ = 200 # MiB
188
+ tile_size = int(
189
+ np.sqrt(float(((max_ram_per_worker - import_) * 2**23)) / tot)
190
+ )
191
+
192
+ logging.info(
193
+ "Estimated optimal tile size for statistical "
194
+ "removal: {} meters".format(tile_size)
195
+ )
196
+
197
+ return tile_size
198
+
199
+ def get_method(self):
200
+ """
201
+ Get margins to use during point clouds fusion
202
+
203
+ :return: algorithm method
204
+ :rtype: string
205
+
206
+ """
207
+
208
+ return self.used_method
209
+
210
+ def get_epipolar_margin(self):
211
+ """
212
+ Get epipolar margin to use
213
+
214
+ :return: margin
215
+ :rtype: int
216
+ """
217
+ margin = self.half_epipolar_size
218
+
219
+ return margin
220
+
221
+ def get_on_ground_margin(self, resolution=0.5):
222
+ """
223
+ Get margins to use during point clouds fusion
224
+
225
+ :return: margin
226
+ :rtype: float
227
+
228
+ """
229
+
230
+ return 0
231
+
232
+ def run( # pylint: disable=too-many-positional-arguments
233
+ self,
234
+ merged_point_cloud,
235
+ orchestrator=None,
236
+ depth_map_dir=None,
237
+ point_cloud_dir=None,
238
+ dump_dir=None,
239
+ epsg=None,
240
+ ):
241
+ """
242
+ Run PointCloudOutlierRemoval application.
243
+
244
+ Creates a CarsDataset filled with new point cloud tiles.
245
+
246
+ :param merged_point_cloud: merged point cloud. CarsDataset contains:
247
+
248
+ - Z x W Delayed tiles. \
249
+ Each tile will be a future pandas DataFrame containing:
250
+
251
+ - data : with keys : "x", "y", "z", "corr_msk" \
252
+ optional: "clr", "msk", "data_valid","coord_epi_geom_i",\
253
+ "coord_epi_geom_j", "idx_im_epi"
254
+ - attrs with keys: "epsg"
255
+ - attributes containing "bounds", "ysize", "xsize", "epsg"
256
+
257
+ :type merged_point_cloud: CarsDataset filled with pandas.DataFrame
258
+ :param orchestrator: orchestrator used
259
+ :param depth_map_dir: output depth map directory. If None output will
260
+ be written in dump_dir if intermediate data is requested
261
+ :type depth_map_dir: str
262
+ :param point_cloud_dir: output depth map directory. If None output will
263
+ be written in dump_dir if intermediate data is requested
264
+ :type point_cloud_dir: str
265
+ :param dump_dir: dump dir for output (except depth map) if intermediate
266
+ data is requested
267
+ :type dump_dir: str
268
+ :param epsg: cartographic reference for the point cloud (array input)
269
+ :type epsg: int
270
+
271
+ :return: filtered merged point cloud. CarsDataset contains:
272
+
273
+ - Z x W Delayed tiles. \
274
+ Each tile will be a future pandas DataFrame containing:
275
+
276
+ - data : with keys "x", "y", "z", "corr_msk" \
277
+ optional: "clr", "msk", "data_valid", "coord_epi_geom_i",\
278
+ "coord_epi_geom_j", "idx_im_epi"
279
+ - attrs with keys: "epsg"
280
+ - attributes containing "bounds", "ysize", "xsize", "epsg"
281
+
282
+ :rtype : CarsDataset filled with xr.Dataset
283
+ """
284
+
285
+ # Default orchestrator
286
+ if orchestrator is None:
287
+ # Create default sequential orchestrator for current application
288
+ # be awere, no out_json will be shared between orchestrators
289
+ # No files saved
290
+ self.orchestrator = ocht.Orchestrator(
291
+ orchestrator_conf={"mode": "sequential"}
292
+ )
293
+ else:
294
+ self.orchestrator = orchestrator
295
+
296
+ if dump_dir is None:
297
+ dump_dir = self.generate_unknown_dump_dir(self.orchestrator)
298
+
299
+ if merged_point_cloud.dataset_type != "arrays":
300
+ raise RuntimeError(
301
+ "Only arrays is supported in statistical removal"
302
+ )
303
+
304
+ prefix = os.path.basename(dump_dir)
305
+ # Save as depth map
306
+ filtered_point_cloud, saving_info_epipolar = (
307
+ self.__register_epipolar_dataset__(
308
+ merged_point_cloud,
309
+ depth_map_dir,
310
+ dump_dir,
311
+ app_name="statistical",
312
+ pair_key=prefix,
313
+ )
314
+ )
315
+
316
+ # Save as point cloud
317
+ (
318
+ flatten_filtered_point_cloud,
319
+ laz_pc_dir_name,
320
+ csv_pc_dir_name,
321
+ saving_info_flatten,
322
+ ) = self.__register_pc_dataset__(
323
+ merged_point_cloud,
324
+ point_cloud_dir,
325
+ dump_dir,
326
+ app_name="statistical",
327
+ )
328
+
329
+ # initialize empty index file for point cloud product if official
330
+ # product is requested
331
+ pc_index = None
332
+ if point_cloud_dir:
333
+ pc_index = {}
334
+
335
+ # Generate rasters
336
+ for col in range(filtered_point_cloud.shape[1]):
337
+ for row in range(filtered_point_cloud.shape[0]):
338
+
339
+ # update saving infos for potential replacement
340
+ full_saving_info_epipolar = ocht.update_saving_infos(
341
+ saving_info_epipolar, row=row, col=col
342
+ )
343
+ full_saving_info_flatten = None
344
+ if saving_info_flatten is not None:
345
+ full_saving_info_flatten = ocht.update_saving_infos(
346
+ saving_info_flatten, row=row, col=col
347
+ )
348
+
349
+ if merged_point_cloud[row][col] is not None:
350
+ csv_pc_file_name, laz_pc_file_name = (
351
+ generate_point_cloud_file_names(
352
+ csv_pc_dir_name,
353
+ laz_pc_dir_name,
354
+ row,
355
+ col,
356
+ pc_index,
357
+ pair_key=prefix,
358
+ )
359
+ )
360
+ window = merged_point_cloud.tiling_grid[row, col]
361
+ overlap = filtered_point_cloud.overlaps[row, col]
362
+ # Delayed call to cloud filtering
363
+ (
364
+ filtered_point_cloud[row, col],
365
+ flatten_filtered_point_cloud[row, col],
366
+ ) = self.orchestrator.cluster.create_task(
367
+ epipolar_statistical_removal_wrapper, nout=2
368
+ )(
369
+ merged_point_cloud[row, col],
370
+ self.k,
371
+ self.filtering_constant,
372
+ self.mean_factor,
373
+ self.std_dev_factor,
374
+ self.use_median,
375
+ self.half_epipolar_size,
376
+ window,
377
+ overlap,
378
+ epsg=epsg,
379
+ point_cloud_csv_file_name=csv_pc_file_name,
380
+ point_cloud_laz_file_name=laz_pc_file_name,
381
+ saving_info_epipolar=full_saving_info_epipolar,
382
+ saving_info_flatten=full_saving_info_flatten,
383
+ )
384
+
385
+ # update point cloud index
386
+ if point_cloud_dir:
387
+ self.orchestrator.update_index(pc_index)
388
+
389
+ return filtered_point_cloud
390
+
391
+
392
+ # pylint: disable=too-many-positional-arguments
393
+ def epipolar_statistical_removal_wrapper(
394
+ epipolar_ds,
395
+ statistical_k,
396
+ filtering_constant,
397
+ mean_factor,
398
+ std_dev_factor,
399
+ use_median,
400
+ half_epipolar_size,
401
+ window,
402
+ overlap,
403
+ epsg,
404
+ point_cloud_csv_file_name=None,
405
+ point_cloud_laz_file_name=None,
406
+ saving_info_epipolar=None,
407
+ saving_info_flatten=None,
408
+ ):
409
+ """
410
+ Statistical outlier removal in epipolar geometry
411
+
412
+ :param epipolar_ds: epipolar dataset to filter
413
+ :type epipolar_ds: xr.Dataset
414
+ :param statistical_k: k
415
+ :type statistical_k: int
416
+ :param filtering_constant: constant applied to the threshold
417
+ :type filtering_constant: float
418
+ :param mean_factor: mean factor
419
+ :type mean_factor: float
420
+ :param std_dev_factor: std factor
421
+ :type std_dev_factor: float
422
+ :param use_median: use median and quartile instead of mean and std
423
+ :type use median: bool
424
+ :param half_epipolar_size: half size of the window used to search neighbors
425
+ :type half_epipolar_size: int
426
+ :param window: window of base tile [row min, row max, col min col max]
427
+ :type window: list
428
+ :param overlap: overlap [row min, row max, col min col max]
429
+ :type overlap: list
430
+ :param epsg: epsg code of the CRS used to compute distances
431
+ :type epsg: int
432
+
433
+ :return: filtered dataset
434
+ :rtype: xr.Dataset
435
+
436
+ """
437
+
438
+ # Copy input cloud
439
+ filtered_cloud = copy.copy(epipolar_ds)
440
+
441
+ # Get current epsg
442
+ cloud_epsg = filtered_cloud.attrs["epsg"]
443
+ current_epsg = cloud_epsg
444
+
445
+ # Check if can be used to filter
446
+ spatial_ref = CRS.from_epsg(cloud_epsg)
447
+ if spatial_ref.is_geographic:
448
+ logging.debug(
449
+ "The point cloud to filter is not in a cartographic system. "
450
+ "The filter's default parameters might not be adapted "
451
+ "to this referential. Please, convert the point "
452
+ "cloud to ECEF to ensure a proper point_cloud."
453
+ )
454
+ # Convert to epsg = 4978
455
+ cartographic_epsg = 4978
456
+
457
+ projection.point_cloud_conversion_dataset(
458
+ filtered_cloud, cartographic_epsg
459
+ )
460
+ current_epsg = cartographic_epsg
461
+
462
+ outlier_removal_algo.epipolar_statistical_filtering(
463
+ filtered_cloud,
464
+ k=statistical_k,
465
+ filtering_constant=filtering_constant,
466
+ mean_factor=mean_factor,
467
+ dev_factor=std_dev_factor,
468
+ use_median=use_median,
469
+ half_window_size=half_epipolar_size,
470
+ )
471
+
472
+ # Fill with attributes
473
+ cars_dataset.fill_dataset(
474
+ filtered_cloud,
475
+ saving_info=saving_info_epipolar,
476
+ window=cars_dataset.window_array_to_dict(window),
477
+ profile=None,
478
+ attributes=None,
479
+ overlaps=cars_dataset.overlap_array_to_dict(overlap),
480
+ )
481
+
482
+ # Flatten point cloud to save it as LAZ
483
+ flatten_filtered_cloud = None
484
+ if point_cloud_csv_file_name or point_cloud_laz_file_name:
485
+ # Convert epipolar array into point cloud
486
+ flatten_filtered_cloud, cloud_epsg = (
487
+ pc_transform.depth_map_dataset_to_dataframe(
488
+ filtered_cloud, current_epsg
489
+ )
490
+ )
491
+ # Convert to wanted epsg
492
+ if epsg is not None and cloud_epsg != epsg:
493
+ projection.point_cloud_conversion_dataframe(
494
+ flatten_filtered_cloud, cloud_epsg, epsg
495
+ )
496
+ cloud_epsg = epsg
497
+
498
+ # Fill attributes for LAZ saving
499
+ color_type = pc_transform.get_color_type([filtered_cloud])
500
+ attributes = {
501
+ "epsg": cloud_epsg,
502
+ "color_type": color_type,
503
+ cst.CROPPED_DISPARITY_RANGE: ocht.get_disparity_range_cropped(
504
+ epipolar_ds
505
+ ),
506
+ }
507
+ cars_dataset.fill_dataframe(
508
+ flatten_filtered_cloud,
509
+ saving_info=saving_info_flatten,
510
+ attributes=attributes,
511
+ )
512
+
513
+ # Save point cloud in worker
514
+ if point_cloud_csv_file_name:
515
+ cars_dataset.run_save_points(
516
+ flatten_filtered_cloud,
517
+ point_cloud_csv_file_name,
518
+ overwrite=True,
519
+ point_cloud_format="csv",
520
+ overwrite_file_name=False,
521
+ )
522
+ if point_cloud_laz_file_name:
523
+ cars_dataset.run_save_points(
524
+ flatten_filtered_cloud,
525
+ point_cloud_laz_file_name,
526
+ overwrite=True,
527
+ point_cloud_format="laz",
528
+ overwrite_file_name=False,
529
+ )
530
+
531
+ 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