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.
- cars/__init__.py +86 -0
- cars/applications/__init__.py +40 -0
- cars/applications/application.py +117 -0
- cars/applications/application_constants.py +29 -0
- cars/applications/application_template.py +146 -0
- cars/applications/auxiliary_filling/__init__.py +29 -0
- cars/applications/auxiliary_filling/abstract_auxiliary_filling_app.py +105 -0
- cars/applications/auxiliary_filling/auxiliary_filling_algo.py +475 -0
- cars/applications/auxiliary_filling/auxiliary_filling_from_sensors_app.py +632 -0
- cars/applications/auxiliary_filling/auxiliary_filling_wrappers.py +90 -0
- cars/applications/dem_generation/__init__.py +30 -0
- cars/applications/dem_generation/abstract_dem_generation_app.py +116 -0
- cars/applications/dem_generation/bulldozer_config/base_config.yaml +42 -0
- cars/applications/dem_generation/bulldozer_dem_app.py +641 -0
- cars/applications/dem_generation/bulldozer_memory.py +55 -0
- cars/applications/dem_generation/dem_generation_algo.py +107 -0
- cars/applications/dem_generation/dem_generation_constants.py +32 -0
- cars/applications/dem_generation/dem_generation_wrappers.py +323 -0
- cars/applications/dense_match_filling/__init__.py +30 -0
- cars/applications/dense_match_filling/abstract_dense_match_filling_app.py +242 -0
- cars/applications/dense_match_filling/fill_disp_algo.py +113 -0
- cars/applications/dense_match_filling/fill_disp_constants.py +39 -0
- cars/applications/dense_match_filling/fill_disp_wrappers.py +83 -0
- cars/applications/dense_match_filling/zero_padding_app.py +302 -0
- cars/applications/dense_matching/__init__.py +30 -0
- cars/applications/dense_matching/abstract_dense_matching_app.py +261 -0
- cars/applications/dense_matching/census_mccnn_sgm_app.py +1461 -0
- cars/applications/dense_matching/cpp/__init__.py +0 -0
- cars/applications/dense_matching/cpp/dense_matching_cpp.cp312-win_amd64.dll.a +0 -0
- cars/applications/dense_matching/cpp/dense_matching_cpp.cp312-win_amd64.pyd +0 -0
- cars/applications/dense_matching/cpp/dense_matching_cpp.py +94 -0
- cars/applications/dense_matching/cpp/includes/dense_matching.hpp +58 -0
- cars/applications/dense_matching/cpp/meson.build +9 -0
- cars/applications/dense_matching/cpp/src/bindings.cpp +13 -0
- cars/applications/dense_matching/cpp/src/dense_matching.cpp +207 -0
- cars/applications/dense_matching/dense_matching_algo.py +401 -0
- cars/applications/dense_matching/dense_matching_constants.py +89 -0
- cars/applications/dense_matching/dense_matching_wrappers.py +951 -0
- cars/applications/dense_matching/disparity_grid_algo.py +597 -0
- cars/applications/dense_matching/loaders/__init__.py +23 -0
- cars/applications/dense_matching/loaders/config_census_sgm_default.json +31 -0
- cars/applications/dense_matching/loaders/config_census_sgm_homogeneous.json +30 -0
- cars/applications/dense_matching/loaders/config_census_sgm_mountain_and_vegetation.json +30 -0
- cars/applications/dense_matching/loaders/config_census_sgm_shadow.json +30 -0
- cars/applications/dense_matching/loaders/config_census_sgm_sparse.json +36 -0
- cars/applications/dense_matching/loaders/config_census_sgm_urban.json +30 -0
- cars/applications/dense_matching/loaders/config_mapping.json +13 -0
- cars/applications/dense_matching/loaders/config_mccnn.json +28 -0
- cars/applications/dense_matching/loaders/global_land_cover_map.tif +0 -0
- cars/applications/dense_matching/loaders/pandora_loader.py +593 -0
- cars/applications/dsm_filling/__init__.py +32 -0
- cars/applications/dsm_filling/abstract_dsm_filling_app.py +101 -0
- cars/applications/dsm_filling/border_interpolation_app.py +278 -0
- cars/applications/dsm_filling/bulldozer_config/base_config.yaml +44 -0
- cars/applications/dsm_filling/bulldozer_filling_app.py +288 -0
- cars/applications/dsm_filling/exogenous_filling_app.py +341 -0
- cars/applications/dsm_merging/__init__.py +28 -0
- cars/applications/dsm_merging/abstract_dsm_merging_app.py +101 -0
- cars/applications/dsm_merging/weighted_fusion_app.py +639 -0
- cars/applications/grid_correction/__init__.py +30 -0
- cars/applications/grid_correction/abstract_grid_correction_app.py +103 -0
- cars/applications/grid_correction/grid_correction_app.py +557 -0
- cars/applications/grid_generation/__init__.py +30 -0
- cars/applications/grid_generation/abstract_grid_generation_app.py +142 -0
- cars/applications/grid_generation/epipolar_grid_generation_app.py +327 -0
- cars/applications/grid_generation/grid_generation_algo.py +388 -0
- cars/applications/grid_generation/grid_generation_constants.py +46 -0
- cars/applications/grid_generation/transform_grid.py +88 -0
- cars/applications/ground_truth_reprojection/__init__.py +30 -0
- cars/applications/ground_truth_reprojection/abstract_ground_truth_reprojection_app.py +137 -0
- cars/applications/ground_truth_reprojection/direct_localization_app.py +629 -0
- cars/applications/ground_truth_reprojection/ground_truth_reprojection_algo.py +275 -0
- cars/applications/point_cloud_outlier_removal/__init__.py +30 -0
- cars/applications/point_cloud_outlier_removal/abstract_outlier_removal_app.py +385 -0
- cars/applications/point_cloud_outlier_removal/outlier_removal_algo.py +392 -0
- cars/applications/point_cloud_outlier_removal/outlier_removal_constants.py +43 -0
- cars/applications/point_cloud_outlier_removal/small_components_app.py +522 -0
- cars/applications/point_cloud_outlier_removal/statistical_app.py +528 -0
- cars/applications/rasterization/__init__.py +30 -0
- cars/applications/rasterization/abstract_pc_rasterization_app.py +183 -0
- cars/applications/rasterization/rasterization_algo.py +534 -0
- cars/applications/rasterization/rasterization_constants.py +38 -0
- cars/applications/rasterization/rasterization_wrappers.py +639 -0
- cars/applications/rasterization/simple_gaussian_app.py +1152 -0
- cars/applications/resampling/__init__.py +28 -0
- cars/applications/resampling/abstract_resampling_app.py +187 -0
- cars/applications/resampling/bicubic_resampling_app.py +760 -0
- cars/applications/resampling/resampling_algo.py +590 -0
- cars/applications/resampling/resampling_constants.py +36 -0
- cars/applications/resampling/resampling_wrappers.py +309 -0
- cars/applications/sensors_subsampling/__init__.py +32 -0
- cars/applications/sensors_subsampling/abstract_subsampling_app.py +109 -0
- cars/applications/sensors_subsampling/rasterio_subsampling_app.py +420 -0
- cars/applications/sensors_subsampling/subsampling_algo.py +108 -0
- cars/applications/sparse_matching/__init__.py +30 -0
- cars/applications/sparse_matching/abstract_sparse_matching_app.py +599 -0
- cars/applications/sparse_matching/sift_app.py +724 -0
- cars/applications/sparse_matching/sparse_matching_algo.py +360 -0
- cars/applications/sparse_matching/sparse_matching_constants.py +66 -0
- cars/applications/sparse_matching/sparse_matching_wrappers.py +282 -0
- cars/applications/triangulation/__init__.py +32 -0
- cars/applications/triangulation/abstract_triangulation_app.py +227 -0
- cars/applications/triangulation/line_of_sight_intersection_app.py +1243 -0
- cars/applications/triangulation/pc_transform.py +552 -0
- cars/applications/triangulation/triangulation_algo.py +371 -0
- cars/applications/triangulation/triangulation_constants.py +38 -0
- cars/applications/triangulation/triangulation_wrappers.py +259 -0
- cars/bundleadjustment.py +750 -0
- cars/cars.py +179 -0
- cars/conf/__init__.py +23 -0
- cars/conf/geoid/egm96.grd +0 -0
- cars/conf/geoid/egm96.grd.hdr +15 -0
- cars/conf/input_parameters.py +156 -0
- cars/conf/mask_cst.py +35 -0
- cars/core/__init__.py +23 -0
- cars/core/cars_logging.py +402 -0
- cars/core/constants.py +191 -0
- cars/core/constants_disparity.py +50 -0
- cars/core/datasets.py +140 -0
- cars/core/geometry/__init__.py +27 -0
- cars/core/geometry/abstract_geometry.py +1119 -0
- cars/core/geometry/shareloc_geometry.py +598 -0
- cars/core/inputs.py +568 -0
- cars/core/outputs.py +176 -0
- cars/core/preprocessing.py +722 -0
- cars/core/projection.py +843 -0
- cars/core/roi_tools.py +215 -0
- cars/core/tiling.py +774 -0
- cars/core/utils.py +164 -0
- cars/data_structures/__init__.py +23 -0
- cars/data_structures/cars_dataset.py +1544 -0
- cars/data_structures/cars_dict.py +74 -0
- cars/data_structures/corresponding_tiles_tools.py +186 -0
- cars/data_structures/dataframe_converter.py +185 -0
- cars/data_structures/format_transformation.py +297 -0
- cars/devibrate.py +689 -0
- cars/extractroi.py +264 -0
- cars/orchestrator/__init__.py +23 -0
- cars/orchestrator/achievement_tracker.py +125 -0
- cars/orchestrator/cluster/__init__.py +37 -0
- cars/orchestrator/cluster/abstract_cluster.py +250 -0
- cars/orchestrator/cluster/abstract_dask_cluster.py +381 -0
- cars/orchestrator/cluster/dask_cluster_tools.py +103 -0
- cars/orchestrator/cluster/dask_config/README.md +94 -0
- cars/orchestrator/cluster/dask_config/dask.yaml +21 -0
- cars/orchestrator/cluster/dask_config/distributed.yaml +70 -0
- cars/orchestrator/cluster/dask_config/jobqueue.yaml +26 -0
- cars/orchestrator/cluster/dask_config/reference_confs/dask-schema.yaml +137 -0
- cars/orchestrator/cluster/dask_config/reference_confs/dask.yaml +26 -0
- cars/orchestrator/cluster/dask_config/reference_confs/distributed-schema.yaml +1009 -0
- cars/orchestrator/cluster/dask_config/reference_confs/distributed.yaml +273 -0
- cars/orchestrator/cluster/dask_config/reference_confs/jobqueue.yaml +212 -0
- cars/orchestrator/cluster/dask_jobqueue_utils.py +204 -0
- cars/orchestrator/cluster/local_dask_cluster.py +116 -0
- cars/orchestrator/cluster/log_wrapper.py +728 -0
- cars/orchestrator/cluster/mp_cluster/__init__.py +27 -0
- cars/orchestrator/cluster/mp_cluster/mp_factorizer.py +212 -0
- cars/orchestrator/cluster/mp_cluster/mp_objects.py +535 -0
- cars/orchestrator/cluster/mp_cluster/mp_tools.py +93 -0
- cars/orchestrator/cluster/mp_cluster/mp_wrapper.py +505 -0
- cars/orchestrator/cluster/mp_cluster/multiprocessing_cluster.py +986 -0
- cars/orchestrator/cluster/mp_cluster/multiprocessing_profiler.py +399 -0
- cars/orchestrator/cluster/pbs_dask_cluster.py +207 -0
- cars/orchestrator/cluster/sequential_cluster.py +139 -0
- cars/orchestrator/cluster/slurm_dask_cluster.py +234 -0
- cars/orchestrator/memory_tools.py +47 -0
- cars/orchestrator/orchestrator.py +755 -0
- cars/orchestrator/orchestrator_constants.py +29 -0
- cars/orchestrator/registry/__init__.py +23 -0
- cars/orchestrator/registry/abstract_registry.py +143 -0
- cars/orchestrator/registry/compute_registry.py +106 -0
- cars/orchestrator/registry/id_generator.py +116 -0
- cars/orchestrator/registry/replacer_registry.py +213 -0
- cars/orchestrator/registry/saver_registry.py +363 -0
- cars/orchestrator/registry/unseen_registry.py +118 -0
- cars/orchestrator/tiles_profiler.py +279 -0
- cars/pipelines/__init__.py +26 -0
- cars/pipelines/conf_resolution/conf_final_resolution.yaml +5 -0
- cars/pipelines/conf_resolution/conf_first_resolution.yaml +4 -0
- cars/pipelines/conf_resolution/conf_intermediate_resolution.yaml +2 -0
- cars/pipelines/default/__init__.py +26 -0
- cars/pipelines/default/default_pipeline.py +1088 -0
- cars/pipelines/filling/__init__.py +26 -0
- cars/pipelines/filling/filling.py +981 -0
- cars/pipelines/formatting/__init__.py +26 -0
- cars/pipelines/formatting/formatting.py +186 -0
- cars/pipelines/merging/__init__.py +26 -0
- cars/pipelines/merging/merging.py +439 -0
- cars/pipelines/parameters/__init__.py +0 -0
- cars/pipelines/parameters/advanced_parameters.py +256 -0
- cars/pipelines/parameters/advanced_parameters_constants.py +68 -0
- cars/pipelines/parameters/application_parameters.py +72 -0
- cars/pipelines/parameters/depth_map_inputs.py +0 -0
- cars/pipelines/parameters/dsm_inputs.py +349 -0
- cars/pipelines/parameters/dsm_inputs_constants.py +25 -0
- cars/pipelines/parameters/output_constants.py +52 -0
- cars/pipelines/parameters/output_parameters.py +438 -0
- cars/pipelines/parameters/sensor_inputs.py +859 -0
- cars/pipelines/parameters/sensor_inputs_constants.py +51 -0
- cars/pipelines/parameters/sensor_loaders/__init__.py +29 -0
- cars/pipelines/parameters/sensor_loaders/basic_classif_loader.py +86 -0
- cars/pipelines/parameters/sensor_loaders/basic_image_loader.py +98 -0
- cars/pipelines/parameters/sensor_loaders/pivot_classif_loader.py +90 -0
- cars/pipelines/parameters/sensor_loaders/pivot_image_loader.py +105 -0
- cars/pipelines/parameters/sensor_loaders/sensor_loader.py +93 -0
- cars/pipelines/parameters/sensor_loaders/sensor_loader_template.py +71 -0
- cars/pipelines/parameters/sensor_loaders/slurp_classif_loader.py +86 -0
- cars/pipelines/pipeline.py +119 -0
- cars/pipelines/pipeline_constants.py +38 -0
- cars/pipelines/pipeline_template.py +135 -0
- cars/pipelines/subsampling/__init__.py +26 -0
- cars/pipelines/subsampling/subsampling.py +358 -0
- cars/pipelines/surface_modeling/__init__.py +26 -0
- cars/pipelines/surface_modeling/surface_modeling.py +2098 -0
- cars/pipelines/tie_points/__init__.py +26 -0
- cars/pipelines/tie_points/tie_points.py +536 -0
- cars/starter.py +167 -0
- cars-1.0.0rc2.dist-info/DELVEWHEEL +2 -0
- cars-1.0.0rc2.dist-info/METADATA +289 -0
- cars-1.0.0rc2.dist-info/RECORD +225 -0
- cars-1.0.0rc2.dist-info/WHEEL +4 -0
- cars-1.0.0rc2.dist-info/entry_points.txt +8 -0
- 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
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
# coding: utf8
|
|
3
|
+
#
|
|
4
|
+
# Copyright (c) 2024 Centre National d'Etudes Spatiales (CNES).
|
|
5
|
+
#
|
|
6
|
+
# This file is part of CARS
|
|
7
|
+
# (see https://github.com/CNES/cars).
|
|
8
|
+
#
|
|
9
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
10
|
+
# you may not use this file except in compliance with the License.
|
|
11
|
+
# You may obtain a copy of the License at
|
|
12
|
+
#
|
|
13
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
14
|
+
#
|
|
15
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
16
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
17
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
18
|
+
# See the License for the specific language governing permissions and
|
|
19
|
+
# limitations under the License.
|
|
20
|
+
#
|
|
21
|
+
"""
|
|
22
|
+
This module contains the abstract direct_localization application class.
|
|
23
|
+
"""
|
|
24
|
+
import numpy as np
|
|
25
|
+
import rasterio as rio
|
|
26
|
+
from rasterio.windows import Window
|
|
27
|
+
from scipy.interpolate import interpn
|
|
28
|
+
from shareloc.proj_utils import transform_physical_point_to_index
|
|
29
|
+
|
|
30
|
+
from cars.core import inputs
|
|
31
|
+
from cars.core.projection import point_cloud_conversion
|
|
32
|
+
from cars.pipelines.parameters import sensor_inputs_constants as sens_cst
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def get_ground_truth( # pylint: disable=too-many-positional-arguments
|
|
36
|
+
geom_plugin,
|
|
37
|
+
grid,
|
|
38
|
+
sensor,
|
|
39
|
+
disp_to_alt_ratio,
|
|
40
|
+
target,
|
|
41
|
+
window,
|
|
42
|
+
geom_plugin_dem_median=None,
|
|
43
|
+
reverse=False,
|
|
44
|
+
):
|
|
45
|
+
"""
|
|
46
|
+
Computes ground truth in epipolar and sensor geometry.
|
|
47
|
+
|
|
48
|
+
:param geom_plugin_dem_median: path to initial dem
|
|
49
|
+
:type geom_plugin_dem_median: str
|
|
50
|
+
:param geom_plugin: Geometry plugin with user's DSM used to
|
|
51
|
+
generate epipolar grids.
|
|
52
|
+
:type geom_plugin: GeometryPlugin
|
|
53
|
+
:param grid: Grid left.
|
|
54
|
+
:type grid: CarsDataset
|
|
55
|
+
:param sensor: sensor data
|
|
56
|
+
Dict must contain keys: "image", "texture", "geomodel",
|
|
57
|
+
"no_data", "mask". Paths must be absolute.
|
|
58
|
+
:type sensor: dict
|
|
59
|
+
:param disp_to_alt_ratio: Disp to altitude ratio used for performance map.
|
|
60
|
+
:type disp_to_alt_ratio: float
|
|
61
|
+
:param target: sensor, epipolar or both outputs geometry
|
|
62
|
+
:type target: str
|
|
63
|
+
:param window: size of tile
|
|
64
|
+
:type window: np.ndarray
|
|
65
|
+
:param geom_plugin_dem_median: Geometry plugin with dem median
|
|
66
|
+
:type geom_plugin_dem_median: geometry_plugin
|
|
67
|
+
:param reverse: true if right-> left
|
|
68
|
+
:type reverse: bool
|
|
69
|
+
"""
|
|
70
|
+
|
|
71
|
+
sensor_data_im = sensor[sens_cst.INPUT_IMG]["bands"]["b0"]["path"]
|
|
72
|
+
geomodel = sensor[sens_cst.INPUT_GEO_MODEL]
|
|
73
|
+
|
|
74
|
+
rows = np.arange(window[0], window[1])
|
|
75
|
+
cols = np.arange(window[2], window[3])
|
|
76
|
+
|
|
77
|
+
(positions_col, positions_row) = np.meshgrid(cols, rows)
|
|
78
|
+
|
|
79
|
+
direct_loc = None
|
|
80
|
+
if target == "epipolar":
|
|
81
|
+
|
|
82
|
+
positions = np.stack([positions_col, positions_row], axis=2)
|
|
83
|
+
sensor_positions = geom_plugin.sensor_position_from_grid(
|
|
84
|
+
grid,
|
|
85
|
+
np.reshape(
|
|
86
|
+
positions,
|
|
87
|
+
(
|
|
88
|
+
positions.shape[0] * positions.shape[1],
|
|
89
|
+
2,
|
|
90
|
+
),
|
|
91
|
+
),
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
transform = inputs.rasterio_get_transform(sensor_data_im)
|
|
95
|
+
row, col = transform_physical_point_to_index(
|
|
96
|
+
~transform, sensor_positions[:, 1], sensor_positions[:, 0]
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
_, _, alt = geom_plugin.direct_loc(
|
|
100
|
+
sensor_data_im,
|
|
101
|
+
geomodel,
|
|
102
|
+
col,
|
|
103
|
+
row,
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
alt = np.reshape(alt, (rows.shape[0], cols.shape[0]))
|
|
107
|
+
|
|
108
|
+
lat, lon, alt_ref = geom_plugin_dem_median.direct_loc(
|
|
109
|
+
sensor_data_im,
|
|
110
|
+
geomodel,
|
|
111
|
+
col,
|
|
112
|
+
row,
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
alt_ref = np.reshape(alt_ref, (rows.shape[0], cols.shape[0]))
|
|
116
|
+
|
|
117
|
+
ground_truth = -(alt - alt_ref) / disp_to_alt_ratio
|
|
118
|
+
if reverse:
|
|
119
|
+
ground_truth *= -1
|
|
120
|
+
|
|
121
|
+
direct_loc = np.column_stack((lon, lat, np.ravel(ground_truth)))
|
|
122
|
+
|
|
123
|
+
if target == "sensor":
|
|
124
|
+
|
|
125
|
+
lat, lon, alt = geom_plugin.direct_loc(
|
|
126
|
+
sensor_data_im,
|
|
127
|
+
geomodel,
|
|
128
|
+
positions_col.ravel(),
|
|
129
|
+
positions_row.ravel(),
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
ground_truth = np.reshape(alt, (rows.shape[0], cols.shape[0]))
|
|
133
|
+
direct_loc = np.column_stack((lon, lat, alt))
|
|
134
|
+
|
|
135
|
+
return ground_truth, direct_loc
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
def resample_auxiliary_values(
|
|
139
|
+
ground_position,
|
|
140
|
+
auxiliary_input,
|
|
141
|
+
window,
|
|
142
|
+
interpolation_method="nearest",
|
|
143
|
+
keep_band=False,
|
|
144
|
+
):
|
|
145
|
+
"""
|
|
146
|
+
Resample classification map in epipolar geometry
|
|
147
|
+
|
|
148
|
+
:param ground_position: Direct localization result (lon, lat, alt)
|
|
149
|
+
:type ground_position: 2D np.darray
|
|
150
|
+
:param auxiliary_input: Path to auxiliary_value
|
|
151
|
+
:type auxiliary_input: string
|
|
152
|
+
:param window: the tile window
|
|
153
|
+
:type window: list
|
|
154
|
+
:param interpolation_method: interpolation method
|
|
155
|
+
:type interpolation_method: string
|
|
156
|
+
:param keep_band: bool to see if we keep the band
|
|
157
|
+
:type keep_band: bool
|
|
158
|
+
"""
|
|
159
|
+
|
|
160
|
+
# get the shape of the tile
|
|
161
|
+
shape = (window[1] - window[0], window[3] - window[2])
|
|
162
|
+
|
|
163
|
+
# Convert shareloc output in degree in UTM
|
|
164
|
+
auxiliary_epsg = inputs.rasterio_get_epsg(auxiliary_input)
|
|
165
|
+
utm_array = point_cloud_conversion(ground_position, 4326, auxiliary_epsg)
|
|
166
|
+
|
|
167
|
+
# Keep auxiliary input information
|
|
168
|
+
transform = inputs.rasterio_get_transform(auxiliary_input)
|
|
169
|
+
nb_bands = inputs.rasterio_get_nb_bands(auxiliary_input)
|
|
170
|
+
outside_interpolated_value = inputs.rasterio_get_nodata(auxiliary_input)
|
|
171
|
+
|
|
172
|
+
# Convert georef coordinates to pixel coordinates (x,y) -> (row,col)
|
|
173
|
+
rows_geo, cols_geo = transform_physical_point_to_index(
|
|
174
|
+
~transform, utm_array[:, 1], utm_array[:, 0]
|
|
175
|
+
)
|
|
176
|
+
|
|
177
|
+
# Find the right window
|
|
178
|
+
with rio.open(auxiliary_input) as src:
|
|
179
|
+
width = src.width
|
|
180
|
+
height = src.height
|
|
181
|
+
|
|
182
|
+
# Put extreme values to nan
|
|
183
|
+
rows_geo[(rows_geo > height) | (rows_geo < 0)] = np.nan
|
|
184
|
+
cols_geo[(cols_geo > width) | (cols_geo < 0)] = np.nan
|
|
185
|
+
|
|
186
|
+
row_min, row_max = int(np.floor(np.nanmin(rows_geo))), int(
|
|
187
|
+
np.ceil(np.nanmax(rows_geo))
|
|
188
|
+
)
|
|
189
|
+
col_min, col_max = int(np.floor(np.nanmin(cols_geo))), int(
|
|
190
|
+
np.ceil(np.nanmax(cols_geo))
|
|
191
|
+
)
|
|
192
|
+
|
|
193
|
+
# put margin to ensure that the window englobe the coord to interp
|
|
194
|
+
margin = 2
|
|
195
|
+
row_min, row_max = max(0, row_min - margin), min(
|
|
196
|
+
src.height, row_max + margin
|
|
197
|
+
)
|
|
198
|
+
col_min, col_max = max(0, col_min - margin), min(
|
|
199
|
+
src.width, col_max + margin
|
|
200
|
+
)
|
|
201
|
+
|
|
202
|
+
# Construct the window and read the data
|
|
203
|
+
window = Window(col_min, row_min, col_max - col_min, row_max - row_min)
|
|
204
|
+
|
|
205
|
+
if keep_band:
|
|
206
|
+
data = src.read(window=window)
|
|
207
|
+
height = data.shape[1]
|
|
208
|
+
width = data.shape[2]
|
|
209
|
+
else:
|
|
210
|
+
data = src.read(1, window=window)
|
|
211
|
+
height = data.shape[0]
|
|
212
|
+
width = data.shape[1]
|
|
213
|
+
|
|
214
|
+
# Construct the grid that corresponds
|
|
215
|
+
grid_rows = np.linspace(row_min, row_max, height)
|
|
216
|
+
grid_cols = np.linspace(col_min, col_max, width)
|
|
217
|
+
grid = (grid_rows, grid_cols)
|
|
218
|
+
|
|
219
|
+
index = np.column_stack((rows_geo, cols_geo))
|
|
220
|
+
|
|
221
|
+
# Interpolation step
|
|
222
|
+
interpolated_points = interpolate(
|
|
223
|
+
grid,
|
|
224
|
+
data,
|
|
225
|
+
index,
|
|
226
|
+
method=interpolation_method,
|
|
227
|
+
fill_value=outside_interpolated_value,
|
|
228
|
+
)
|
|
229
|
+
|
|
230
|
+
if keep_band:
|
|
231
|
+
output_array = interpolated_points.reshape((nb_bands, *shape))
|
|
232
|
+
else:
|
|
233
|
+
output_array = interpolated_points.reshape(shape)
|
|
234
|
+
|
|
235
|
+
return output_array
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
def interpolate(points, values, positions, method="linear", fill_value=None):
|
|
239
|
+
"""
|
|
240
|
+
Interpolate position
|
|
241
|
+
|
|
242
|
+
:param points: Points defining the grid
|
|
243
|
+
:type points: np.darray
|
|
244
|
+
:param values: Data
|
|
245
|
+
:type values: 2D np.darray, or 3D np.darray (band, row, col)
|
|
246
|
+
:param positions: Positions to interpolate
|
|
247
|
+
:type positions: np.darray
|
|
248
|
+
:param method: interpolation method
|
|
249
|
+
:type method: string : {'linear', 'nearest'}
|
|
250
|
+
:param fill_value: value to use for points outside of the interp domain
|
|
251
|
+
:type fill_value: float
|
|
252
|
+
:return: interpolated positions
|
|
253
|
+
:rtype: 1D np.darray or 2D np.darray (band, interpolated positions)
|
|
254
|
+
"""
|
|
255
|
+
if len(values.shape) > 2:
|
|
256
|
+
interp_point = np.zeros((values.shape[0], positions.shape[0]))
|
|
257
|
+
for band in range(values.shape[0]):
|
|
258
|
+
interp_point[band, :] = interpn(
|
|
259
|
+
points,
|
|
260
|
+
values[band, :, :],
|
|
261
|
+
positions,
|
|
262
|
+
method=method,
|
|
263
|
+
bounds_error=False,
|
|
264
|
+
fill_value=fill_value,
|
|
265
|
+
)
|
|
266
|
+
else:
|
|
267
|
+
interp_point = interpn(
|
|
268
|
+
points,
|
|
269
|
+
values,
|
|
270
|
+
positions,
|
|
271
|
+
method=method,
|
|
272
|
+
bounds_error=False,
|
|
273
|
+
fill_value=fill_value,
|
|
274
|
+
)
|
|
275
|
+
return interp_point
|
|
@@ -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 cloud outlier removing module init file
|
|
23
|
+
"""
|
|
24
|
+
# flake8: noqa: F401
|
|
25
|
+
|
|
26
|
+
from cars.applications.point_cloud_outlier_removal.abstract_outlier_removal_app import ( # pylint: disable=C0301
|
|
27
|
+
PointCloudOutlierRemoval,
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
from . import small_components_app, statistical_app
|
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
# coding: utf8
|
|
3
|
+
#
|
|
4
|
+
# Copyright (c) 2020 Centre National d'Etudes Spatiales (CNES).
|
|
5
|
+
#
|
|
6
|
+
# This file is part of CARS
|
|
7
|
+
# (see https://github.com/CNES/cars).
|
|
8
|
+
#
|
|
9
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
10
|
+
# you may not use this file except in compliance with the License.
|
|
11
|
+
# You may obtain a copy of the License at
|
|
12
|
+
#
|
|
13
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
14
|
+
#
|
|
15
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
16
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
17
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
18
|
+
# See the License for the specific language governing permissions and
|
|
19
|
+
# limitations under the License.
|
|
20
|
+
#
|
|
21
|
+
"""
|
|
22
|
+
this module contains the abstract PointsCloudOutlierRemoval application class.
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
import logging
|
|
26
|
+
import os
|
|
27
|
+
from abc import ABCMeta, abstractmethod
|
|
28
|
+
from typing import Dict
|
|
29
|
+
|
|
30
|
+
import numpy as np
|
|
31
|
+
|
|
32
|
+
from cars.applications import application_constants
|
|
33
|
+
from cars.applications.application import Application
|
|
34
|
+
from cars.applications.application_template import ScalingApplicationTemplate
|
|
35
|
+
from cars.applications.point_cloud_outlier_removal import (
|
|
36
|
+
outlier_removal_constants as pr_cst,
|
|
37
|
+
)
|
|
38
|
+
from cars.core import constants as cst
|
|
39
|
+
from cars.core.utils import safe_makedirs
|
|
40
|
+
from cars.data_structures import cars_dataset
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
@Application.register("point_cloud_outlier_removal")
|
|
44
|
+
class PointCloudOutlierRemoval(ScalingApplicationTemplate, metaclass=ABCMeta):
|
|
45
|
+
"""
|
|
46
|
+
PointCloudOutlierRemoval
|
|
47
|
+
"""
|
|
48
|
+
|
|
49
|
+
available_applications: Dict = {}
|
|
50
|
+
default_application = "statistical"
|
|
51
|
+
|
|
52
|
+
def __new__(cls, scaling_coeff, conf=None): # pylint: disable=W0613
|
|
53
|
+
"""
|
|
54
|
+
Return the required application
|
|
55
|
+
:raises:
|
|
56
|
+
- KeyError when the required application is not registered
|
|
57
|
+
|
|
58
|
+
:param scaling_coeff: scaling factor for resolution
|
|
59
|
+
:type scaling_coeff: float
|
|
60
|
+
:param conf: configuration for points removal
|
|
61
|
+
:return: a application_to_use object
|
|
62
|
+
"""
|
|
63
|
+
|
|
64
|
+
points_removal_method = cls.default_application
|
|
65
|
+
if bool(conf) is False or "method" not in conf:
|
|
66
|
+
logging.info(
|
|
67
|
+
"Points removal method not specified, "
|
|
68
|
+
"default {} is used".format(points_removal_method)
|
|
69
|
+
)
|
|
70
|
+
else:
|
|
71
|
+
points_removal_method = conf.get("method", cls.default_application)
|
|
72
|
+
|
|
73
|
+
if points_removal_method not in cls.available_applications:
|
|
74
|
+
logging.error(
|
|
75
|
+
"No Points removal application named {} registered".format(
|
|
76
|
+
points_removal_method
|
|
77
|
+
)
|
|
78
|
+
)
|
|
79
|
+
raise KeyError(
|
|
80
|
+
"No Points removal application named {} registered".format(
|
|
81
|
+
points_removal_method
|
|
82
|
+
)
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
logging.info(
|
|
86
|
+
"The PointCloudOutlierRemoval({}) application"
|
|
87
|
+
" will be used".format(points_removal_method)
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
return super(PointCloudOutlierRemoval, cls).__new__(
|
|
91
|
+
cls.available_applications[points_removal_method]
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
def __init_subclass__(cls, short_name, **kwargs): # pylint: disable=E0302
|
|
95
|
+
super().__init_subclass__(**kwargs)
|
|
96
|
+
# init orchestrator
|
|
97
|
+
cls.orchestrator = None
|
|
98
|
+
cls.available_applications[short_name] = cls
|
|
99
|
+
|
|
100
|
+
def __init__(self, scaling_coeff, conf=None):
|
|
101
|
+
"""
|
|
102
|
+
Init function of PointCloudOutlierRemoval
|
|
103
|
+
|
|
104
|
+
:param scaling_coeff: scaling factor for resolution
|
|
105
|
+
:type scaling_coeff: float
|
|
106
|
+
:param conf: configuration
|
|
107
|
+
:return: an application_to_use object
|
|
108
|
+
"""
|
|
109
|
+
|
|
110
|
+
super().__init__(scaling_coeff, conf=conf)
|
|
111
|
+
|
|
112
|
+
@abstractmethod
|
|
113
|
+
def get_on_ground_margin(self, resolution=0.5):
|
|
114
|
+
"""
|
|
115
|
+
Get margins to use during point clouds fusion
|
|
116
|
+
|
|
117
|
+
:return: margin
|
|
118
|
+
:rtype: float
|
|
119
|
+
|
|
120
|
+
"""
|
|
121
|
+
|
|
122
|
+
@abstractmethod
|
|
123
|
+
def get_epipolar_margin(self):
|
|
124
|
+
"""
|
|
125
|
+
Get epipolar margin to use
|
|
126
|
+
|
|
127
|
+
:return: margin
|
|
128
|
+
:rtype: int
|
|
129
|
+
"""
|
|
130
|
+
|
|
131
|
+
@abstractmethod
|
|
132
|
+
def get_method(self):
|
|
133
|
+
"""
|
|
134
|
+
Get margins to use during point clouds fusion
|
|
135
|
+
|
|
136
|
+
:return: algorithm method
|
|
137
|
+
:rtype: string
|
|
138
|
+
|
|
139
|
+
"""
|
|
140
|
+
|
|
141
|
+
@abstractmethod
|
|
142
|
+
def get_optimal_tile_size(
|
|
143
|
+
self,
|
|
144
|
+
max_ram_per_worker,
|
|
145
|
+
superposing_point_clouds=1,
|
|
146
|
+
point_cloud_resolution=0.5,
|
|
147
|
+
):
|
|
148
|
+
"""
|
|
149
|
+
Get the optimal tile size to use, depending on memory available
|
|
150
|
+
|
|
151
|
+
:param max_ram_per_worker: maximum ram available
|
|
152
|
+
:type max_ram_per_worker: int
|
|
153
|
+
:param superposing_point_clouds: number of point clouds superposing
|
|
154
|
+
:type superposing_point_clouds: int
|
|
155
|
+
:param point_cloud_resolution: resolution of point cloud
|
|
156
|
+
:type point_cloud_resolution: float
|
|
157
|
+
|
|
158
|
+
:return: optimal tile size in meter
|
|
159
|
+
:rtype: float
|
|
160
|
+
|
|
161
|
+
"""
|
|
162
|
+
|
|
163
|
+
# pylint: disable=too-many-positional-arguments
|
|
164
|
+
def __register_epipolar_dataset__(
|
|
165
|
+
self,
|
|
166
|
+
epipolar_point_cloud,
|
|
167
|
+
depth_map_dir=None,
|
|
168
|
+
dump_dir=None,
|
|
169
|
+
app_name="",
|
|
170
|
+
pair_key="PAIR_0",
|
|
171
|
+
):
|
|
172
|
+
"""
|
|
173
|
+
Create dataset and registered the output in the orchestrator. the output
|
|
174
|
+
X, Y and Z ground coordinates will be saved in depth_map_dir if the
|
|
175
|
+
parameter is no None. Alternatively it will be saved to dump_dir if
|
|
176
|
+
save_intermediate_data is set and depth_map_dir is None.
|
|
177
|
+
|
|
178
|
+
:param epipolar_point_cloud: Merged point cloud
|
|
179
|
+
:type epipolar_point_cloud: CarsDataset
|
|
180
|
+
:param depth_map_dir: output depth map directory. If None output will be
|
|
181
|
+
written in dump_dir if intermediate data is requested
|
|
182
|
+
:type depth_map_dir: str
|
|
183
|
+
:param dump_dir: dump dir for output (except depth map) if intermediate
|
|
184
|
+
data is requested
|
|
185
|
+
:type dump_dir: str
|
|
186
|
+
:param app_name: application name for file names
|
|
187
|
+
:type app_name: str
|
|
188
|
+
:param pair_key: name of current pair for index registration
|
|
189
|
+
:type pair_key: str
|
|
190
|
+
|
|
191
|
+
:return: Filtered point cloud
|
|
192
|
+
:rtype: CarsDataset
|
|
193
|
+
|
|
194
|
+
"""
|
|
195
|
+
|
|
196
|
+
# Create epipolar point cloud CarsDataset
|
|
197
|
+
filtered_point_cloud = cars_dataset.CarsDataset(
|
|
198
|
+
epipolar_point_cloud.dataset_type, name=app_name
|
|
199
|
+
)
|
|
200
|
+
|
|
201
|
+
filtered_point_cloud.create_empty_copy(epipolar_point_cloud)
|
|
202
|
+
|
|
203
|
+
# Update attributes to get epipolar info
|
|
204
|
+
filtered_point_cloud.attributes.update(epipolar_point_cloud.attributes)
|
|
205
|
+
|
|
206
|
+
if depth_map_dir or self.used_config.get(
|
|
207
|
+
application_constants.SAVE_INTERMEDIATE_DATA
|
|
208
|
+
):
|
|
209
|
+
filtered_dir = (
|
|
210
|
+
depth_map_dir if depth_map_dir is not None else dump_dir
|
|
211
|
+
)
|
|
212
|
+
safe_makedirs(filtered_dir)
|
|
213
|
+
self.orchestrator.add_to_save_lists(
|
|
214
|
+
os.path.join(filtered_dir, "X.tif"),
|
|
215
|
+
cst.X,
|
|
216
|
+
filtered_point_cloud,
|
|
217
|
+
cars_ds_name="depth_map_x_filtered_" + app_name,
|
|
218
|
+
dtype=np.float64,
|
|
219
|
+
)
|
|
220
|
+
|
|
221
|
+
self.orchestrator.add_to_save_lists(
|
|
222
|
+
os.path.join(filtered_dir, "Y.tif"),
|
|
223
|
+
cst.Y,
|
|
224
|
+
filtered_point_cloud,
|
|
225
|
+
cars_ds_name="depth_map_y_filtered_" + app_name,
|
|
226
|
+
dtype=np.float64,
|
|
227
|
+
)
|
|
228
|
+
self.orchestrator.add_to_save_lists(
|
|
229
|
+
os.path.join(filtered_dir, "Z.tif"),
|
|
230
|
+
cst.Z,
|
|
231
|
+
filtered_point_cloud,
|
|
232
|
+
cars_ds_name="depth_map_z_filtered_" + app_name,
|
|
233
|
+
dtype=np.float64,
|
|
234
|
+
)
|
|
235
|
+
|
|
236
|
+
# update depth map index if required
|
|
237
|
+
if depth_map_dir:
|
|
238
|
+
index = {
|
|
239
|
+
cst.INDEX_DEPTH_MAP_X: os.path.join(pair_key, "X.tif"),
|
|
240
|
+
cst.INDEX_DEPTH_MAP_Y: os.path.join(pair_key, "Y.tif"),
|
|
241
|
+
cst.INDEX_DEPTH_MAP_Z: os.path.join(pair_key, "Z.tif"),
|
|
242
|
+
}
|
|
243
|
+
self.orchestrator.update_index({"depth_map": {pair_key: index}})
|
|
244
|
+
|
|
245
|
+
# Get saving infos in order to save tiles when they are computed
|
|
246
|
+
[saving_info] = self.orchestrator.get_saving_infos(
|
|
247
|
+
[filtered_point_cloud]
|
|
248
|
+
)
|
|
249
|
+
|
|
250
|
+
# Add infos to orchestrator.out_json
|
|
251
|
+
updating_dict = {
|
|
252
|
+
application_constants.APPLICATION_TAG: {
|
|
253
|
+
pr_cst.CLOUD_OUTLIER_REMOVAL_RUN_TAG: {app_name: {}},
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
self.orchestrator.update_out_info(updating_dict)
|
|
257
|
+
|
|
258
|
+
return filtered_point_cloud, saving_info
|
|
259
|
+
|
|
260
|
+
def __register_pc_dataset__(
|
|
261
|
+
self,
|
|
262
|
+
merged_point_cloud=None,
|
|
263
|
+
point_cloud_dir=None,
|
|
264
|
+
dump_dir=None,
|
|
265
|
+
app_name=None,
|
|
266
|
+
):
|
|
267
|
+
"""
|
|
268
|
+
Create dataset and registered the output in the orchestrator. The
|
|
269
|
+
point cloud dataset can be saved as laz using the save_laz_output
|
|
270
|
+
option. Alternatively, the point cloud will be saved as laz and csv
|
|
271
|
+
in the dump directory if the application save_intermediate data
|
|
272
|
+
configuration parameter is set.
|
|
273
|
+
|
|
274
|
+
:param merged_point_cloud: Merged point cloud
|
|
275
|
+
:type merged_point_cloud: CarsDataset
|
|
276
|
+
:param point_cloud_dir: output depth map directory. If None output will
|
|
277
|
+
be written in dump_dir if intermediate data is requested
|
|
278
|
+
:type point_cloud_dir: str
|
|
279
|
+
:param dump_dir: dump dir for output (except depth map) if intermediate
|
|
280
|
+
data is requested
|
|
281
|
+
:type dump_dir: str
|
|
282
|
+
:param app_name: application name for file names
|
|
283
|
+
:type app_name: str
|
|
284
|
+
|
|
285
|
+
:return: Filtered point cloud
|
|
286
|
+
:rtype: CarsDataset
|
|
287
|
+
|
|
288
|
+
"""
|
|
289
|
+
if app_name is None:
|
|
290
|
+
app_name = ""
|
|
291
|
+
|
|
292
|
+
save_point_cloud_as_csv = self.used_config.get(
|
|
293
|
+
application_constants.SAVE_INTERMEDIATE_DATA, False
|
|
294
|
+
)
|
|
295
|
+
# Save laz point cloud if save_intermediate_date is activated (dump_dir)
|
|
296
|
+
# or if point_cloud_dir is provided (save as official product)
|
|
297
|
+
save_point_cloud_as_laz = (
|
|
298
|
+
point_cloud_dir is not None
|
|
299
|
+
or self.used_config.get(
|
|
300
|
+
application_constants.SAVE_INTERMEDIATE_DATA, False
|
|
301
|
+
)
|
|
302
|
+
)
|
|
303
|
+
|
|
304
|
+
# Create CarsDataset
|
|
305
|
+
filtered_point_cloud = cars_dataset.CarsDataset(
|
|
306
|
+
"points", name="point_cloud_removal_" + app_name
|
|
307
|
+
)
|
|
308
|
+
|
|
309
|
+
# Get tiling grid
|
|
310
|
+
filtered_point_cloud.create_empty_copy(merged_point_cloud)
|
|
311
|
+
filtered_point_cloud.attributes = merged_point_cloud.attributes.copy()
|
|
312
|
+
|
|
313
|
+
laz_pc_dir_name = None
|
|
314
|
+
if save_point_cloud_as_laz:
|
|
315
|
+
if point_cloud_dir is not None:
|
|
316
|
+
laz_pc_dir_name = point_cloud_dir
|
|
317
|
+
else:
|
|
318
|
+
laz_pc_dir_name = os.path.join(dump_dir, "laz")
|
|
319
|
+
safe_makedirs(laz_pc_dir_name)
|
|
320
|
+
self.orchestrator.add_to_compute_lists(
|
|
321
|
+
filtered_point_cloud,
|
|
322
|
+
cars_ds_name="filtered_point_cloud_laz_" + app_name,
|
|
323
|
+
)
|
|
324
|
+
csv_pc_dir_name = None
|
|
325
|
+
if save_point_cloud_as_csv:
|
|
326
|
+
csv_pc_dir_name = os.path.join(dump_dir, "csv")
|
|
327
|
+
safe_makedirs(csv_pc_dir_name)
|
|
328
|
+
self.orchestrator.add_to_compute_lists(
|
|
329
|
+
filtered_point_cloud,
|
|
330
|
+
cars_ds_name="filtered_point_cloud_csv_" + app_name,
|
|
331
|
+
)
|
|
332
|
+
|
|
333
|
+
# Get saving infos in order to save tiles when they are computed
|
|
334
|
+
[saving_info] = self.orchestrator.get_saving_infos(
|
|
335
|
+
[filtered_point_cloud]
|
|
336
|
+
)
|
|
337
|
+
|
|
338
|
+
# Add infos to orchestrator.out_json
|
|
339
|
+
updating_dict = {
|
|
340
|
+
application_constants.APPLICATION_TAG: {
|
|
341
|
+
pr_cst.CLOUD_OUTLIER_REMOVAL_RUN_TAG: {},
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
self.orchestrator.update_out_info(updating_dict)
|
|
345
|
+
|
|
346
|
+
return (
|
|
347
|
+
filtered_point_cloud,
|
|
348
|
+
laz_pc_dir_name,
|
|
349
|
+
csv_pc_dir_name,
|
|
350
|
+
saving_info,
|
|
351
|
+
)
|
|
352
|
+
|
|
353
|
+
@abstractmethod
|
|
354
|
+
def run( # pylint: disable=too-many-positional-arguments
|
|
355
|
+
self,
|
|
356
|
+
merged_point_cloud,
|
|
357
|
+
orchestrator=None,
|
|
358
|
+
save_laz_output=False,
|
|
359
|
+
depth_map_dir=None,
|
|
360
|
+
point_cloud_dir=None,
|
|
361
|
+
dump_dir=None,
|
|
362
|
+
epsg=None,
|
|
363
|
+
):
|
|
364
|
+
"""
|
|
365
|
+
Run PointCloudOutlierRemoval application.
|
|
366
|
+
|
|
367
|
+
Creates a CarsDataset filled with new point cloud tiles.
|
|
368
|
+
|
|
369
|
+
:param merged_point_cloud: merged point cloud
|
|
370
|
+
:type merged_point_cloud: CarsDataset filled with pandas.DataFrame
|
|
371
|
+
:param orchestrator: orchestrator used
|
|
372
|
+
:param save_laz_output: save output point cloud as laz
|
|
373
|
+
:type save_laz_output: bool
|
|
374
|
+
:param output_dir: output depth map directory. If None output will be
|
|
375
|
+
written in dump_dir if intermediate data is requested
|
|
376
|
+
:type output_dir: str
|
|
377
|
+
:param dump_dir: dump dir for output (except depth map) if intermediate
|
|
378
|
+
data is requested
|
|
379
|
+
:type dump_dir: str
|
|
380
|
+
:param epsg: cartographic reference for the point cloud (array input)
|
|
381
|
+
:type epsg: int
|
|
382
|
+
|
|
383
|
+
:return: filtered merged point cloud
|
|
384
|
+
:rtype: CarsDataset filled with xr.Dataset
|
|
385
|
+
"""
|