cars 1.0.0a2__cp310-cp310-win_amd64.whl → 1.0.0a4__cp310-cp310-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.
- cars/__init__.py +3 -3
- cars/applications/__init__.py +0 -3
- cars/applications/application.py +14 -6
- cars/applications/application_template.py +42 -0
- cars/applications/auxiliary_filling/abstract_auxiliary_filling_app.py +12 -2
- cars/applications/auxiliary_filling/auxiliary_filling_algo.py +2 -2
- cars/applications/auxiliary_filling/auxiliary_filling_from_sensors_app.py +95 -46
- cars/applications/auxiliary_filling/auxiliary_filling_wrappers.py +7 -6
- cars/applications/dem_generation/abstract_dem_generation_app.py +9 -5
- cars/applications/dem_generation/dem_generation_algo.py +1 -1
- cars/applications/dem_generation/dem_generation_wrappers.py +44 -59
- cars/applications/dem_generation/dichotomic_generation_app.py +9 -6
- cars/applications/dem_generation/rasterization_app.py +112 -43
- cars/applications/dense_match_filling/__init__.py +1 -1
- cars/applications/dense_match_filling/abstract_dense_match_filling_app.py +2 -15
- cars/applications/dense_match_filling/fill_disp_algo.py +32 -373
- cars/applications/dense_match_filling/fill_disp_wrappers.py +0 -343
- cars/applications/dense_match_filling/zero_padding_app.py +10 -5
- cars/applications/dense_matching/abstract_dense_matching_app.py +2 -1
- cars/applications/dense_matching/census_mccnn_sgm_app.py +48 -60
- cars/applications/dense_matching/cpp/dense_matching_cpp.cp310-win_amd64.dll.a +0 -0
- cars/applications/dense_matching/cpp/dense_matching_cpp.cp310-win_amd64.pyd +0 -0
- cars/applications/dense_matching/dense_matching_algo.py +48 -14
- cars/applications/dense_matching/dense_matching_wrappers.py +11 -3
- cars/applications/dense_matching/disparity_grid_algo.py +95 -79
- cars/applications/dense_matching/loaders/config_mapping.json +13 -0
- cars/applications/dense_matching/loaders/global_land_cover_map.tif +0 -0
- cars/applications/dense_matching/loaders/pandora_loader.py +169 -34
- cars/applications/dsm_filling/border_interpolation_app.py +11 -12
- cars/applications/dsm_filling/bulldozer_filling_app.py +16 -15
- cars/applications/dsm_filling/exogenous_filling_app.py +14 -14
- cars/applications/grid_generation/abstract_grid_generation_app.py +1 -1
- cars/applications/grid_generation/epipolar_grid_generation_app.py +4 -2
- cars/applications/grid_generation/grid_correction_app.py +4 -1
- cars/applications/grid_generation/grid_generation_algo.py +7 -2
- cars/applications/ground_truth_reprojection/abstract_ground_truth_reprojection_app.py +1 -1
- cars/applications/ground_truth_reprojection/direct_localization_app.py +2 -2
- cars/applications/ground_truth_reprojection/ground_truth_reprojection_algo.py +2 -1
- cars/applications/point_cloud_fusion/abstract_pc_fusion_app.py +0 -155
- cars/applications/point_cloud_fusion/mapping_to_terrain_tiles_app.py +0 -658
- cars/applications/point_cloud_fusion/pc_fusion_algo.py +0 -1339
- cars/applications/point_cloud_fusion/pc_fusion_wrappers.py +0 -869
- cars/applications/point_cloud_outlier_removal/abstract_outlier_removal_app.py +11 -6
- cars/applications/point_cloud_outlier_removal/outlier_removal_algo.py +9 -8
- cars/applications/point_cloud_outlier_removal/small_components_app.py +101 -270
- cars/applications/point_cloud_outlier_removal/statistical_app.py +120 -277
- cars/applications/rasterization/abstract_pc_rasterization_app.py +2 -1
- cars/applications/rasterization/rasterization_algo.py +18 -6
- cars/applications/rasterization/rasterization_wrappers.py +2 -1
- cars/applications/rasterization/simple_gaussian_app.py +88 -116
- cars/applications/resampling/abstract_resampling_app.py +1 -1
- cars/applications/resampling/bicubic_resampling_app.py +3 -1
- cars/applications/resampling/resampling_algo.py +60 -53
- cars/applications/resampling/resampling_wrappers.py +3 -1
- cars/applications/sparse_matching/abstract_sparse_matching_app.py +1 -1
- cars/applications/sparse_matching/sift_app.py +5 -25
- cars/applications/sparse_matching/sparse_matching_algo.py +3 -2
- cars/applications/sparse_matching/sparse_matching_wrappers.py +1 -1
- cars/applications/triangulation/abstract_triangulation_app.py +1 -1
- cars/applications/triangulation/line_of_sight_intersection_app.py +13 -11
- cars/applications/triangulation/pc_transform.py +552 -0
- cars/applications/triangulation/triangulation_algo.py +6 -4
- cars/applications/triangulation/triangulation_wrappers.py +1 -0
- cars/bundleadjustment.py +6 -6
- cars/cars.py +11 -9
- cars/core/cars_logging.py +80 -49
- cars/core/constants.py +0 -1
- cars/core/datasets.py +5 -2
- cars/core/geometry/abstract_geometry.py +364 -22
- cars/core/geometry/shareloc_geometry.py +112 -82
- cars/core/inputs.py +72 -19
- cars/core/outputs.py +1 -1
- cars/core/preprocessing.py +17 -3
- cars/core/projection.py +126 -6
- cars/core/tiling.py +10 -3
- cars/data_structures/cars_dataset.py +12 -10
- cars/data_structures/corresponding_tiles_tools.py +0 -103
- cars/data_structures/format_transformation.py +4 -1
- cars/devibrate.py +6 -3
- cars/extractroi.py +20 -21
- cars/orchestrator/cluster/abstract_cluster.py +15 -5
- cars/orchestrator/cluster/abstract_dask_cluster.py +6 -2
- cars/orchestrator/cluster/dask_jobqueue_utils.py +1 -1
- cars/orchestrator/cluster/log_wrapper.py +149 -22
- cars/orchestrator/cluster/mp_cluster/multiprocessing_cluster.py +12 -4
- cars/orchestrator/cluster/mp_cluster/multiprocessing_profiler.py +2 -2
- cars/orchestrator/cluster/pbs_dask_cluster.py +1 -1
- cars/orchestrator/cluster/sequential_cluster.py +5 -4
- cars/orchestrator/cluster/slurm_dask_cluster.py +1 -1
- cars/orchestrator/orchestrator.py +15 -4
- cars/orchestrator/registry/id_generator.py +1 -0
- cars/orchestrator/registry/saver_registry.py +2 -2
- cars/pipelines/conf_resolution/conf_final_resolution.json +5 -3
- cars/pipelines/default/default_pipeline.py +461 -1052
- cars/pipelines/parameters/advanced_parameters.py +91 -64
- cars/pipelines/parameters/advanced_parameters_constants.py +6 -5
- cars/pipelines/parameters/application_parameters.py +71 -0
- cars/pipelines/parameters/depth_map_inputs.py +0 -314
- cars/pipelines/parameters/dsm_inputs.py +40 -4
- cars/pipelines/parameters/output_parameters.py +44 -8
- cars/pipelines/parameters/sensor_inputs.py +122 -73
- cars/pipelines/parameters/sensor_inputs_constants.py +0 -2
- cars/pipelines/parameters/sensor_loaders/__init__.py +4 -3
- cars/pipelines/parameters/sensor_loaders/basic_classif_loader.py +106 -0
- cars/pipelines/parameters/sensor_loaders/{basic_sensor_loader.py → basic_image_loader.py} +16 -22
- cars/pipelines/parameters/sensor_loaders/pivot_classif_loader.py +121 -0
- cars/pipelines/parameters/sensor_loaders/{pivot_sensor_loader.py → pivot_image_loader.py} +10 -21
- cars/pipelines/parameters/sensor_loaders/sensor_loader.py +4 -6
- cars/pipelines/parameters/sensor_loaders/sensor_loader_template.py +1 -3
- cars/pipelines/pipeline_template.py +1 -3
- cars/pipelines/unit/unit_pipeline.py +676 -1070
- cars/starter.py +4 -3
- cars-1.0.0a4.dist-info/DELVEWHEEL +2 -0
- {cars-1.0.0a2.dist-info → cars-1.0.0a4.dist-info}/METADATA +135 -53
- {cars-1.0.0a2.dist-info → cars-1.0.0a4.dist-info}/RECORD +120 -134
- cars.libs/libgcc_s_seh-1-b2494fcbd4d80cf2c98fdd5261f6d850.dll +0 -0
- cars.libs/libstdc++-6-e9b0d12ae0e9555bbae55e8dfd08c3f7.dll +0 -0
- cars.libs/libwinpthread-1-7882d1b093714ccdfaf4e0789a817792.dll +0 -0
- cars/applications/dense_match_filling/cpp/__init__.py +0 -0
- cars/applications/dense_match_filling/cpp/dense_match_filling_cpp.cp310-win_amd64.dll.a +0 -0
- cars/applications/dense_match_filling/cpp/dense_match_filling_cpp.cp310-win_amd64.pyd +0 -0
- cars/applications/dense_match_filling/cpp/dense_match_filling_cpp.py +0 -72
- cars/applications/dense_match_filling/cpp/includes/dense_match_filling.hpp +0 -46
- cars/applications/dense_match_filling/cpp/meson.build +0 -9
- cars/applications/dense_match_filling/cpp/src/bindings.cpp +0 -11
- cars/applications/dense_match_filling/cpp/src/dense_match_filling.cpp +0 -142
- cars/applications/dense_match_filling/plane_app.py +0 -556
- cars/applications/hole_detection/__init__.py +0 -30
- cars/applications/hole_detection/abstract_hole_detection_app.py +0 -125
- cars/applications/hole_detection/cloud_to_bbox_app.py +0 -346
- cars/applications/hole_detection/hole_detection_algo.py +0 -144
- cars/applications/hole_detection/hole_detection_wrappers.py +0 -53
- cars/applications/point_cloud_denoising/__init__.py +0 -29
- cars/applications/point_cloud_denoising/abstract_pc_denoising_app.py +0 -273
- cars/applications/point_cloud_fusion/__init__.py +0 -30
- cars/applications/point_cloud_fusion/cloud_fusion_constants.py +0 -39
- cars/applications/sparse_matching/pandora_sparse_matching_app.py +0 -0
- cars/pipelines/parameters/depth_map_inputs_constants.py +0 -25
- cars-1.0.0a2.dist-info/DELVEWHEEL +0 -2
- cars.libs/libgcc_s_seh-1-f2b6825d483bdf14050493af93b5997d.dll +0 -0
- cars.libs/libstdc++-6-6b0059df6bc601df5a0f18a5805eea05.dll +0 -0
- cars.libs/libwinpthread-1-e01b8e85fd67c2b861f64d4ccc7df607.dll +0 -0
- {cars-1.0.0a2.dist-info → cars-1.0.0a4.dist-info}/WHEEL +0 -0
- {cars-1.0.0a2.dist-info → cars-1.0.0a4.dist-info}/entry_points.txt +0 -0
|
@@ -1,658 +0,0 @@
|
|
|
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 epipolar cloud fusion application class.
|
|
23
|
-
"""
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
# Standard imports
|
|
27
|
-
import logging
|
|
28
|
-
import os
|
|
29
|
-
from collections import Counter
|
|
30
|
-
|
|
31
|
-
# Third party imports
|
|
32
|
-
import numpy as np
|
|
33
|
-
from json_checker import Checker
|
|
34
|
-
from shapely.geometry import Polygon
|
|
35
|
-
|
|
36
|
-
import cars.orchestrator.orchestrator as ocht
|
|
37
|
-
from cars.applications import application_constants
|
|
38
|
-
from cars.applications.point_cloud_fusion import (
|
|
39
|
-
cloud_fusion_constants,
|
|
40
|
-
pc_fusion_algo,
|
|
41
|
-
pc_fusion_wrappers,
|
|
42
|
-
)
|
|
43
|
-
from cars.applications.point_cloud_fusion.abstract_pc_fusion_app import (
|
|
44
|
-
PointCloudFusion,
|
|
45
|
-
)
|
|
46
|
-
from cars.applications.triangulation.triangulation_wrappers import (
|
|
47
|
-
generate_point_cloud_file_names,
|
|
48
|
-
)
|
|
49
|
-
from cars.core import constants as cst
|
|
50
|
-
from cars.core import inputs, projection, tiling
|
|
51
|
-
from cars.core.utils import safe_makedirs
|
|
52
|
-
from cars.data_structures import cars_dataset
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
class MappingToTerrainTiles(
|
|
56
|
-
PointCloudFusion, short_name="mapping_to_terrain_tiles"
|
|
57
|
-
):
|
|
58
|
-
"""
|
|
59
|
-
EpipolarCloudFusion
|
|
60
|
-
"""
|
|
61
|
-
|
|
62
|
-
def __init__(self, conf=None):
|
|
63
|
-
"""
|
|
64
|
-
Init function of EpipolarCloudFusion
|
|
65
|
-
|
|
66
|
-
:param conf: configuration for fusion
|
|
67
|
-
:return: an application_to_use object
|
|
68
|
-
"""
|
|
69
|
-
|
|
70
|
-
super().__init__(conf=conf)
|
|
71
|
-
|
|
72
|
-
# Cloud fusion
|
|
73
|
-
self.used_method = self.used_config["method"]
|
|
74
|
-
|
|
75
|
-
# Init orchestrator
|
|
76
|
-
self.orchestrator = None
|
|
77
|
-
|
|
78
|
-
def check_conf(self, conf):
|
|
79
|
-
"""
|
|
80
|
-
Check configuration
|
|
81
|
-
|
|
82
|
-
:param conf: configuration to check
|
|
83
|
-
:type conf: dict
|
|
84
|
-
|
|
85
|
-
:return: overloaded configuration
|
|
86
|
-
:rtype: dict
|
|
87
|
-
|
|
88
|
-
"""
|
|
89
|
-
|
|
90
|
-
# init conf
|
|
91
|
-
if conf is not None:
|
|
92
|
-
overloaded_conf = conf.copy()
|
|
93
|
-
else:
|
|
94
|
-
conf = {}
|
|
95
|
-
overloaded_conf = {}
|
|
96
|
-
|
|
97
|
-
# Overload conf
|
|
98
|
-
overloaded_conf["method"] = conf.get(
|
|
99
|
-
"method", "mapping_to_terrain_tiles"
|
|
100
|
-
)
|
|
101
|
-
|
|
102
|
-
overloaded_conf["save_by_pair"] = conf.get("save_by_pair", False)
|
|
103
|
-
|
|
104
|
-
overloaded_conf[application_constants.SAVE_INTERMEDIATE_DATA] = (
|
|
105
|
-
conf.get(application_constants.SAVE_INTERMEDIATE_DATA, False)
|
|
106
|
-
)
|
|
107
|
-
point_cloud_fusion_schema = {
|
|
108
|
-
"method": str,
|
|
109
|
-
"save_by_pair": bool,
|
|
110
|
-
application_constants.SAVE_INTERMEDIATE_DATA: bool,
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
# Check conf
|
|
114
|
-
checker = Checker(point_cloud_fusion_schema)
|
|
115
|
-
checker.validate(overloaded_conf)
|
|
116
|
-
|
|
117
|
-
return overloaded_conf
|
|
118
|
-
|
|
119
|
-
def run( # noqa: C901
|
|
120
|
-
self,
|
|
121
|
-
list_epipolar_point_clouds,
|
|
122
|
-
bounds,
|
|
123
|
-
epsg,
|
|
124
|
-
source_pc_names=None,
|
|
125
|
-
orchestrator=None,
|
|
126
|
-
margins=0,
|
|
127
|
-
optimal_terrain_tile_width=500,
|
|
128
|
-
roi=None,
|
|
129
|
-
save_laz_output=False,
|
|
130
|
-
):
|
|
131
|
-
"""
|
|
132
|
-
Run EpipolarCloudFusion application.
|
|
133
|
-
|
|
134
|
-
Creates a CarsDataset corresponding to the merged point clouds,
|
|
135
|
-
tiled with the terrain grid used during rasterization.
|
|
136
|
-
|
|
137
|
-
:param list_epipolar_point_clouds: list with point clouds\
|
|
138
|
-
Each CarsDataset contains:
|
|
139
|
-
|
|
140
|
-
- N x M Delayed tiles. \
|
|
141
|
-
Each tile will be a future xarray Dataset containing:
|
|
142
|
-
|
|
143
|
-
- data : with keys : "x", "y", "z", "corr_msk" \
|
|
144
|
-
optional: "texture", "msk",
|
|
145
|
-
- attrs with keys: "margins", "epi_full_size", "epsg"
|
|
146
|
-
- attributes containing: "disp_lower_bound", "disp_upper_bound" \
|
|
147
|
-
"elevation_delta_lower_bound", "elevation_delta_upper_bound"
|
|
148
|
-
:type list_epipolar_point_clouds: list(CarsDataset) filled with
|
|
149
|
-
xr.Dataset
|
|
150
|
-
:param bounds: terrain bounds
|
|
151
|
-
:type bounds: list
|
|
152
|
-
:param epsg: epsg to use
|
|
153
|
-
:type epsg: str
|
|
154
|
-
:param source_pc_names: source pc names
|
|
155
|
-
:type source_pc_names: list[str]
|
|
156
|
-
:param orchestrator: orchestrator used
|
|
157
|
-
:type orchestrator: Orchestrator
|
|
158
|
-
:param margins: margins needed for tiles, meter or degree
|
|
159
|
-
:type margins: float
|
|
160
|
-
:param optimal_terrain_tile_width: optimal terrain tile width
|
|
161
|
-
:type optimal_terrain_tile_width: int
|
|
162
|
-
:param save_laz_output: save output point cloud as laz
|
|
163
|
-
:type save_laz_output: bool
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
:return: Merged point clouds
|
|
167
|
-
|
|
168
|
-
CarsDataset contains:
|
|
169
|
-
|
|
170
|
-
- Z x W Delayed tiles\
|
|
171
|
-
Each tile will be a future pandas DataFrame containing:
|
|
172
|
-
|
|
173
|
-
- data : with keys : "x", "y", "z", "corr_msk" \
|
|
174
|
-
optional: "clr", "msk", "data_valid","coord_epi_geom_i",\
|
|
175
|
-
"coord_epi_geom_j","idx_im_epi"
|
|
176
|
-
- attrs with keys: "epsg"
|
|
177
|
-
- attributes containing: "bounds", "epsg"
|
|
178
|
-
|
|
179
|
-
:rtype: CarsDataset filled with pandas.DataFrame
|
|
180
|
-
|
|
181
|
-
"""
|
|
182
|
-
|
|
183
|
-
# Default orchestrator
|
|
184
|
-
if orchestrator is None:
|
|
185
|
-
# Create default sequential orchestrator for current application
|
|
186
|
-
# be awere, no out_json will be shared between orchestrators
|
|
187
|
-
# No files saved
|
|
188
|
-
self.orchestrator = ocht.Orchestrator(
|
|
189
|
-
orchestrator_conf={"mode": "sequential"}
|
|
190
|
-
)
|
|
191
|
-
else:
|
|
192
|
-
self.orchestrator = orchestrator
|
|
193
|
-
|
|
194
|
-
save_point_cloud_as_csv = self.used_config.get(
|
|
195
|
-
application_constants.SAVE_INTERMEDIATE_DATA, False
|
|
196
|
-
)
|
|
197
|
-
save_point_cloud_as_laz = (
|
|
198
|
-
self.used_config.get(
|
|
199
|
-
application_constants.SAVE_INTERMEDIATE_DATA, False
|
|
200
|
-
)
|
|
201
|
-
or save_laz_output
|
|
202
|
-
)
|
|
203
|
-
save_by_pair = self.used_config.get("save_by_pair", False)
|
|
204
|
-
|
|
205
|
-
if source_pc_names is None:
|
|
206
|
-
source_pc_names = ["PAIR_0"]
|
|
207
|
-
|
|
208
|
-
# Compute bounds and terrain grid
|
|
209
|
-
[xmin, ymin, xmax, ymax] = bounds
|
|
210
|
-
|
|
211
|
-
# Split terrain bounding box in pieces
|
|
212
|
-
terrain_tiling_grid = tiling.generate_tiling_grid(
|
|
213
|
-
xmin,
|
|
214
|
-
ymin,
|
|
215
|
-
xmax,
|
|
216
|
-
ymax,
|
|
217
|
-
optimal_terrain_tile_width,
|
|
218
|
-
optimal_terrain_tile_width,
|
|
219
|
-
)
|
|
220
|
-
source_pc_names = []
|
|
221
|
-
for point_cloud in list_epipolar_point_clouds:
|
|
222
|
-
if "source_pc_name" in point_cloud.attributes:
|
|
223
|
-
source_pc_names.append(point_cloud.attributes["source_pc_name"])
|
|
224
|
-
# Get dataset type of first item in list_epipolar_point_clouds
|
|
225
|
-
pc_dataset_type = list_epipolar_point_clouds[0].dataset_type
|
|
226
|
-
|
|
227
|
-
if pc_dataset_type in (
|
|
228
|
-
"arrays",
|
|
229
|
-
"dict",
|
|
230
|
-
"points",
|
|
231
|
-
):
|
|
232
|
-
# Create CarsDataset
|
|
233
|
-
merged_point_cloud = cars_dataset.CarsDataset(
|
|
234
|
-
"points", name="point_cloud_fusion"
|
|
235
|
-
)
|
|
236
|
-
|
|
237
|
-
# Compute tiling grid
|
|
238
|
-
merged_point_cloud.tiling_grid = terrain_tiling_grid
|
|
239
|
-
|
|
240
|
-
# update attributes
|
|
241
|
-
merged_point_cloud.attributes["bounds"] = bounds
|
|
242
|
-
merged_point_cloud.attributes["epsg"] = epsg
|
|
243
|
-
merged_point_cloud.attributes["source_pc_names"] = source_pc_names
|
|
244
|
-
|
|
245
|
-
number_of_terrain_tiles = (
|
|
246
|
-
merged_point_cloud.tiling_grid.shape[1]
|
|
247
|
-
* merged_point_cloud.tiling_grid.shape[0]
|
|
248
|
-
)
|
|
249
|
-
|
|
250
|
-
logging.info(
|
|
251
|
-
"Number of tiles in cloud fusion :"
|
|
252
|
-
"row : {} "
|
|
253
|
-
"col : {}".format(
|
|
254
|
-
merged_point_cloud.shape[0],
|
|
255
|
-
merged_point_cloud.shape[1],
|
|
256
|
-
)
|
|
257
|
-
)
|
|
258
|
-
|
|
259
|
-
number_of_epipolar_tiles_per_terrain_tiles = []
|
|
260
|
-
|
|
261
|
-
if pc_dataset_type in (
|
|
262
|
-
"arrays",
|
|
263
|
-
"points",
|
|
264
|
-
):
|
|
265
|
-
# deal with delayed tiles, with a priori disp min and max
|
|
266
|
-
|
|
267
|
-
# Add epipolar_points_min and epipolar_points_max used
|
|
268
|
-
# in point_cloud_fusion
|
|
269
|
-
# , to get corresponding tiles (terrain)
|
|
270
|
-
# TODO change method for corresponding tiles
|
|
271
|
-
list_points_min = []
|
|
272
|
-
list_points_max = []
|
|
273
|
-
for point_cloud in list_epipolar_point_clouds:
|
|
274
|
-
points_min, points_max = tiling.terrain_grid_to_epipolar(
|
|
275
|
-
terrain_tiling_grid,
|
|
276
|
-
point_cloud.tiling_grid,
|
|
277
|
-
point_cloud.attributes["epipolar_grid_min"],
|
|
278
|
-
point_cloud.attributes["epipolar_grid_max"],
|
|
279
|
-
epsg,
|
|
280
|
-
)
|
|
281
|
-
list_points_min.append(points_min)
|
|
282
|
-
list_points_max.append(points_max)
|
|
283
|
-
|
|
284
|
-
# Add infos to orchestrator.out_json
|
|
285
|
-
updating_dict = {
|
|
286
|
-
application_constants.APPLICATION_TAG: {
|
|
287
|
-
cloud_fusion_constants.CLOUD_FUSION_RUN_TAG: {
|
|
288
|
-
cloud_fusion_constants.EPSG_TAG: epsg,
|
|
289
|
-
cloud_fusion_constants.MARGINS_TAG: margins,
|
|
290
|
-
cloud_fusion_constants.NUMBER_TERRAIN_TILES: (
|
|
291
|
-
number_of_terrain_tiles
|
|
292
|
-
),
|
|
293
|
-
cloud_fusion_constants.BOUNDS: bounds,
|
|
294
|
-
},
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
orchestrator.update_out_info(updating_dict)
|
|
298
|
-
|
|
299
|
-
# Generate merged point clouds
|
|
300
|
-
logging.info(
|
|
301
|
-
"Point clouds: Merged points number: {}".format(
|
|
302
|
-
merged_point_cloud.shape[1] * merged_point_cloud.shape[0]
|
|
303
|
-
)
|
|
304
|
-
)
|
|
305
|
-
|
|
306
|
-
# Compute corresponing tiles in parallel if from tif files
|
|
307
|
-
color_type = None
|
|
308
|
-
if pc_dataset_type == "dict":
|
|
309
|
-
corresponding_tiles_cars_ds = (
|
|
310
|
-
pc_fusion_algo.get_corresponding_tiles_tif(
|
|
311
|
-
terrain_tiling_grid,
|
|
312
|
-
list_epipolar_point_clouds,
|
|
313
|
-
margins=margins,
|
|
314
|
-
orchestrator=self.orchestrator,
|
|
315
|
-
)
|
|
316
|
-
)
|
|
317
|
-
color_file = list_epipolar_point_clouds[0].tiles[0][0]["data"][
|
|
318
|
-
"texture"
|
|
319
|
-
]
|
|
320
|
-
if color_file is not None:
|
|
321
|
-
color_type = inputs.rasterio_get_image_type(color_file)
|
|
322
|
-
merged_point_cloud.attributes["color_type"] = color_type
|
|
323
|
-
|
|
324
|
-
# Save objects
|
|
325
|
-
csv_pc_dir_name = None
|
|
326
|
-
if save_point_cloud_as_csv:
|
|
327
|
-
# Point cloud file name
|
|
328
|
-
csv_pc_dir_name = os.path.join(
|
|
329
|
-
self.orchestrator.out_dir,
|
|
330
|
-
"dump_dir",
|
|
331
|
-
"point_cloud_fusion",
|
|
332
|
-
"csv",
|
|
333
|
-
)
|
|
334
|
-
safe_makedirs(csv_pc_dir_name)
|
|
335
|
-
self.orchestrator.add_to_compute_lists(
|
|
336
|
-
merged_point_cloud, cars_ds_name="merged_point_cloud_csv"
|
|
337
|
-
)
|
|
338
|
-
|
|
339
|
-
laz_pc_dir_name = None
|
|
340
|
-
if save_point_cloud_as_laz:
|
|
341
|
-
# Point cloud file name
|
|
342
|
-
if save_laz_output:
|
|
343
|
-
laz_pc_dir_name = os.path.join(
|
|
344
|
-
self.orchestrator.out_dir, "point_cloud"
|
|
345
|
-
)
|
|
346
|
-
else:
|
|
347
|
-
laz_pc_dir_name = os.path.join(
|
|
348
|
-
self.orchestrator.out_dir,
|
|
349
|
-
"dump_dir",
|
|
350
|
-
"point_cloud_fusion",
|
|
351
|
-
"laz",
|
|
352
|
-
)
|
|
353
|
-
safe_makedirs(laz_pc_dir_name)
|
|
354
|
-
self.orchestrator.add_to_compute_lists(
|
|
355
|
-
merged_point_cloud, cars_ds_name="merged_point_cloud"
|
|
356
|
-
)
|
|
357
|
-
|
|
358
|
-
# Get saving infos in order to save tiles when they are computed
|
|
359
|
-
[saving_info] = self.orchestrator.get_saving_infos(
|
|
360
|
-
[merged_point_cloud]
|
|
361
|
-
)
|
|
362
|
-
pc_index = {}
|
|
363
|
-
for col in range(merged_point_cloud.shape[1]):
|
|
364
|
-
for row in range(merged_point_cloud.shape[0]):
|
|
365
|
-
# update saving infos for potential replacement
|
|
366
|
-
full_saving_info = ocht.update_saving_infos(
|
|
367
|
-
saving_info, row=row, col=col
|
|
368
|
-
)
|
|
369
|
-
if pc_dataset_type in (
|
|
370
|
-
"arrays",
|
|
371
|
-
"points",
|
|
372
|
-
):
|
|
373
|
-
# Get required point clouds
|
|
374
|
-
(
|
|
375
|
-
terrain_region,
|
|
376
|
-
required_point_clouds,
|
|
377
|
-
_rank,
|
|
378
|
-
_pos,
|
|
379
|
-
) = tiling.get_corresponding_tiles_row_col(
|
|
380
|
-
terrain_tiling_grid,
|
|
381
|
-
row,
|
|
382
|
-
col,
|
|
383
|
-
list_epipolar_point_clouds,
|
|
384
|
-
list_points_min,
|
|
385
|
-
list_points_max,
|
|
386
|
-
)
|
|
387
|
-
else:
|
|
388
|
-
# Get correspondances previously computed
|
|
389
|
-
terrain_region = corresponding_tiles_cars_ds[row, col][
|
|
390
|
-
"terrain_region"
|
|
391
|
-
]
|
|
392
|
-
required_point_clouds = corresponding_tiles_cars_ds[
|
|
393
|
-
row, col
|
|
394
|
-
]["required_point_clouds"]
|
|
395
|
-
|
|
396
|
-
terrain_region_poly = Polygon(
|
|
397
|
-
[
|
|
398
|
-
[terrain_region[0], terrain_region[1]],
|
|
399
|
-
[terrain_region[0], terrain_region[3]],
|
|
400
|
-
[terrain_region[2], terrain_region[3]],
|
|
401
|
-
[terrain_region[2], terrain_region[1]],
|
|
402
|
-
[terrain_region[0], terrain_region[1]],
|
|
403
|
-
]
|
|
404
|
-
)
|
|
405
|
-
if len(
|
|
406
|
-
[
|
|
407
|
-
value
|
|
408
|
-
for value, _ in required_point_clouds
|
|
409
|
-
if not isinstance(value, type(None))
|
|
410
|
-
]
|
|
411
|
-
) > 0 and (
|
|
412
|
-
roi is None or terrain_region_poly.intersects(roi)
|
|
413
|
-
):
|
|
414
|
-
logging.debug(
|
|
415
|
-
"Number of clouds to process for this terrain"
|
|
416
|
-
" tile: {}".format(len(required_point_clouds))
|
|
417
|
-
)
|
|
418
|
-
number_of_epipolar_tiles_per_terrain_tiles.append(
|
|
419
|
-
len(required_point_clouds)
|
|
420
|
-
)
|
|
421
|
-
|
|
422
|
-
csv_pc_file_name, laz_pc_file_name = (
|
|
423
|
-
generate_point_cloud_file_names(
|
|
424
|
-
csv_pc_dir_name,
|
|
425
|
-
laz_pc_dir_name,
|
|
426
|
-
row,
|
|
427
|
-
col,
|
|
428
|
-
pc_index,
|
|
429
|
-
pair_key=(
|
|
430
|
-
source_pc_names if save_by_pair else None
|
|
431
|
-
),
|
|
432
|
-
)
|
|
433
|
-
)
|
|
434
|
-
|
|
435
|
-
# Delayed call to rasterization operations using all
|
|
436
|
-
# required point clouds
|
|
437
|
-
merged_point_cloud[
|
|
438
|
-
row, col
|
|
439
|
-
] = self.orchestrator.cluster.create_task(
|
|
440
|
-
compute_point_cloud_wrapper
|
|
441
|
-
)(
|
|
442
|
-
required_point_clouds,
|
|
443
|
-
epsg,
|
|
444
|
-
xmin=terrain_region[0],
|
|
445
|
-
ymin=terrain_region[1],
|
|
446
|
-
xmax=terrain_region[2],
|
|
447
|
-
ymax=terrain_region[3],
|
|
448
|
-
margins=margins,
|
|
449
|
-
save_by_pair=save_by_pair,
|
|
450
|
-
point_cloud_csv_file_name=csv_pc_file_name,
|
|
451
|
-
point_cloud_laz_file_name=laz_pc_file_name,
|
|
452
|
-
saving_info=full_saving_info,
|
|
453
|
-
source_pc_names=source_pc_names,
|
|
454
|
-
)
|
|
455
|
-
|
|
456
|
-
# update point cloud index
|
|
457
|
-
if save_laz_output:
|
|
458
|
-
self.orchestrator.update_index(pc_index)
|
|
459
|
-
|
|
460
|
-
# Sort tiles according to rank TODO remove or implement it ?
|
|
461
|
-
|
|
462
|
-
# Raise an error if no tiles has been found
|
|
463
|
-
if len(number_of_epipolar_tiles_per_terrain_tiles) < 1:
|
|
464
|
-
raise RuntimeError(
|
|
465
|
-
"No epipolar tiles has been found inside the ROI! "
|
|
466
|
-
"Please try with an other ROI."
|
|
467
|
-
)
|
|
468
|
-
|
|
469
|
-
# Add delayed_dsm_tiles to orchestrator
|
|
470
|
-
logging.info(
|
|
471
|
-
"Submitting {} tasks to dask".format(number_of_terrain_tiles)
|
|
472
|
-
)
|
|
473
|
-
|
|
474
|
-
logging.info(
|
|
475
|
-
"Number of epipolar tiles "
|
|
476
|
-
"for each terrain tile (counter): {}".format(
|
|
477
|
-
sorted(
|
|
478
|
-
Counter(
|
|
479
|
-
number_of_epipolar_tiles_per_terrain_tiles
|
|
480
|
-
).items()
|
|
481
|
-
)
|
|
482
|
-
)
|
|
483
|
-
)
|
|
484
|
-
|
|
485
|
-
logging.info(
|
|
486
|
-
"Average number of epipolar tiles "
|
|
487
|
-
"for each terrain tile: {}".format(
|
|
488
|
-
int(
|
|
489
|
-
np.round(
|
|
490
|
-
np.mean(number_of_epipolar_tiles_per_terrain_tiles)
|
|
491
|
-
)
|
|
492
|
-
)
|
|
493
|
-
)
|
|
494
|
-
)
|
|
495
|
-
|
|
496
|
-
logging.info(
|
|
497
|
-
"Max number of epipolar tiles "
|
|
498
|
-
"for each terrain tile: {}".format(
|
|
499
|
-
np.max(number_of_epipolar_tiles_per_terrain_tiles)
|
|
500
|
-
)
|
|
501
|
-
)
|
|
502
|
-
|
|
503
|
-
else:
|
|
504
|
-
logging.error(
|
|
505
|
-
"PointCloudRasterisation application doesn't "
|
|
506
|
-
"support this input data format"
|
|
507
|
-
)
|
|
508
|
-
|
|
509
|
-
return merged_point_cloud
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
def compute_point_cloud_wrapper(
|
|
513
|
-
point_clouds,
|
|
514
|
-
epsg,
|
|
515
|
-
xmin: float = None,
|
|
516
|
-
ymin: float = None,
|
|
517
|
-
xmax: float = None,
|
|
518
|
-
ymax: float = None,
|
|
519
|
-
margins: float = 0,
|
|
520
|
-
save_by_pair: bool = False,
|
|
521
|
-
point_cloud_csv_file_name=None,
|
|
522
|
-
point_cloud_laz_file_name=None,
|
|
523
|
-
saving_info=None,
|
|
524
|
-
source_pc_names=None,
|
|
525
|
-
):
|
|
526
|
-
"""
|
|
527
|
-
Wrapper for point clouds fusion step :
|
|
528
|
-
- Convert a list of clouds to correct epsg
|
|
529
|
-
|
|
530
|
-
:param point_clouds: list of clouds, list of (dataset, dataset_id) with :
|
|
531
|
-
- cst.X
|
|
532
|
-
- cst.Y
|
|
533
|
-
- cst.Z
|
|
534
|
-
- cst.EPI_TEXTURE
|
|
535
|
-
:type point_clouds: list((xr.Dataset, int))
|
|
536
|
-
:param epsg_code: epsg code for the CRS of the output DSM
|
|
537
|
-
:type epsg_code: int
|
|
538
|
-
:param stereo_out_epsg: epsg code to convert point cloud to, if needed
|
|
539
|
-
:type stereo_out_epsg: int
|
|
540
|
-
:param xmin: xmin of the rasterization grid
|
|
541
|
-
(if None, will be estimated by the function)
|
|
542
|
-
:param xmin: xmin of the rasterization grid
|
|
543
|
-
(if None, will be estimated by the function)
|
|
544
|
-
:param xmax: xmax of the rasterization grid
|
|
545
|
-
(if None, will be estimated by the function)
|
|
546
|
-
:param ymax: ymax of the rasterization grid
|
|
547
|
-
(if None, will be estimated by the function)
|
|
548
|
-
:param margins: margins needed for tiles, meter or degree
|
|
549
|
-
:type margins: float
|
|
550
|
-
:param save_by_pair: save point cloud as pair
|
|
551
|
-
:type save_by_pair: bool
|
|
552
|
-
:param point_cloud_csv_file_name: write point cloud as CSV in filename
|
|
553
|
-
(if None, the point cloud is not written as csv)
|
|
554
|
-
:type point_cloud_csv_file_name: str
|
|
555
|
-
:param point_cloud_laz_file_name: write point cloud as laz in filename
|
|
556
|
-
(if None, the point cloud is not written as laz)
|
|
557
|
-
:type point_cloud_laz_file_name: str
|
|
558
|
-
:param saving_info: informations about CarsDataset ID.
|
|
559
|
-
:type saving_info: dict
|
|
560
|
-
:param source_pc_names: source point cloud name (correspond to pair_key)
|
|
561
|
-
:type source_pc_names: list str
|
|
562
|
-
|
|
563
|
-
:return: merged point cloud dataframe with:
|
|
564
|
-
- cst.X
|
|
565
|
-
- cst.Y
|
|
566
|
-
- cst.Z
|
|
567
|
-
- cst.EPI_TEXTURE
|
|
568
|
-
- attrs : xmin, xmax, ymin, ymax, saving_info
|
|
569
|
-
:rtype: pandas.DataFrame
|
|
570
|
-
"""
|
|
571
|
-
# Remove None tiles
|
|
572
|
-
clouds = []
|
|
573
|
-
clouds_ids = []
|
|
574
|
-
disparity_range_is_cropped = False
|
|
575
|
-
for value, pc_id in point_clouds:
|
|
576
|
-
if value is not None:
|
|
577
|
-
clouds.append(value)
|
|
578
|
-
clouds_ids.append(pc_id)
|
|
579
|
-
# Check if disparity range was cropped during process
|
|
580
|
-
if ocht.get_disparity_range_cropped(value):
|
|
581
|
-
disparity_range_is_cropped = True
|
|
582
|
-
if len(clouds) == 0:
|
|
583
|
-
raise RuntimeError("All clouds are None")
|
|
584
|
-
|
|
585
|
-
# combine clouds
|
|
586
|
-
if not isinstance(clouds[0], dict):
|
|
587
|
-
pc_pandas, cloud_epsg = pc_fusion_algo.create_combined_cloud(
|
|
588
|
-
clouds,
|
|
589
|
-
clouds_ids,
|
|
590
|
-
epsg,
|
|
591
|
-
xmin=xmin,
|
|
592
|
-
xmax=xmax,
|
|
593
|
-
ymin=ymin,
|
|
594
|
-
ymax=ymax,
|
|
595
|
-
margin=margins,
|
|
596
|
-
with_coords=True,
|
|
597
|
-
)
|
|
598
|
-
# get color type list
|
|
599
|
-
color_type = pc_fusion_wrappers.get_color_type(clouds)
|
|
600
|
-
else:
|
|
601
|
-
# combined pc from tif files
|
|
602
|
-
(
|
|
603
|
-
pc_pandas,
|
|
604
|
-
cloud_epsg,
|
|
605
|
-
color_type,
|
|
606
|
-
) = pc_fusion_algo.create_combined_cloud_from_tif(
|
|
607
|
-
clouds,
|
|
608
|
-
clouds_ids,
|
|
609
|
-
epsg,
|
|
610
|
-
xmin=xmin,
|
|
611
|
-
xmax=xmax,
|
|
612
|
-
ymin=ymin,
|
|
613
|
-
ymax=ymax,
|
|
614
|
-
margin=margins,
|
|
615
|
-
)
|
|
616
|
-
|
|
617
|
-
# Conversion to UTM
|
|
618
|
-
if cloud_epsg != epsg:
|
|
619
|
-
projection.point_cloud_conversion_dataframe(pc_pandas, cloud_epsg, epsg)
|
|
620
|
-
cloud_epsg = epsg
|
|
621
|
-
|
|
622
|
-
# Fill attributes for rasterization
|
|
623
|
-
attributes = {
|
|
624
|
-
"epsg": cloud_epsg,
|
|
625
|
-
"xmin": xmin,
|
|
626
|
-
"xmax": xmax,
|
|
627
|
-
"ymin": ymin,
|
|
628
|
-
"ymax": ymax,
|
|
629
|
-
"color_type": color_type,
|
|
630
|
-
"source_pc_names": source_pc_names,
|
|
631
|
-
"number_of_pc": len(source_pc_names),
|
|
632
|
-
cst.CROPPED_DISPARITY_RANGE: disparity_range_is_cropped,
|
|
633
|
-
}
|
|
634
|
-
cars_dataset.fill_dataframe(
|
|
635
|
-
pc_pandas, saving_info=saving_info, attributes=attributes
|
|
636
|
-
)
|
|
637
|
-
|
|
638
|
-
# save point cloud in worker
|
|
639
|
-
if point_cloud_csv_file_name:
|
|
640
|
-
cars_dataset.run_save_points(
|
|
641
|
-
pc_pandas,
|
|
642
|
-
point_cloud_csv_file_name,
|
|
643
|
-
save_by_pair=save_by_pair,
|
|
644
|
-
overwrite=True,
|
|
645
|
-
point_cloud_format="csv",
|
|
646
|
-
overwrite_file_name=False,
|
|
647
|
-
)
|
|
648
|
-
if point_cloud_laz_file_name:
|
|
649
|
-
cars_dataset.run_save_points(
|
|
650
|
-
pc_pandas,
|
|
651
|
-
point_cloud_laz_file_name,
|
|
652
|
-
save_by_pair=save_by_pair,
|
|
653
|
-
overwrite=True,
|
|
654
|
-
point_cloud_format="laz",
|
|
655
|
-
overwrite_file_name=False,
|
|
656
|
-
)
|
|
657
|
-
|
|
658
|
-
return pc_pandas
|