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.
- cars/__init__.py +74 -0
- cars/applications/__init__.py +37 -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 +104 -0
- cars/applications/auxiliary_filling/auxiliary_filling_algo.py +475 -0
- cars/applications/auxiliary_filling/auxiliary_filling_from_sensors_app.py +630 -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 +655 -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 +1460 -0
- cars/applications/dense_matching/cpp/__init__.py +0 -0
- cars/applications/dense_matching/cpp/dense_matching_cpp.cpython-312-i386-linux-gnu.so +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 +588 -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 +270 -0
- cars/applications/dsm_filling/bulldozer_config/base_config.yaml +44 -0
- cars/applications/dsm_filling/bulldozer_filling_app.py +279 -0
- cars/applications/dsm_filling/exogenous_filling_app.py +333 -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_correction_app.py +496 -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 +527 -0
- cars/applications/point_cloud_outlier_removal/statistical_app.py +531 -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 +634 -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 +762 -0
- cars/applications/resampling/resampling_algo.py +614 -0
- cars/applications/resampling/resampling_constants.py +36 -0
- cars/applications/resampling/resampling_wrappers.py +309 -0
- cars/applications/sparse_matching/__init__.py +30 -0
- cars/applications/sparse_matching/abstract_sparse_matching_app.py +498 -0
- cars/applications/sparse_matching/sift_app.py +735 -0
- cars/applications/sparse_matching/sparse_matching_algo.py +360 -0
- cars/applications/sparse_matching/sparse_matching_constants.py +68 -0
- cars/applications/sparse_matching/sparse_matching_wrappers.py +238 -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 +757 -0
- cars/cars.py +177 -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 +1541 -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 +244 -0
- cars/orchestrator/cluster/abstract_dask_cluster.py +375 -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 +1075 -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 +873 -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/orchestrator.py +905 -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 +2 -0
- cars/pipelines/conf_resolution/conf_intermediate_resolution.yaml +2 -0
- cars/pipelines/default/__init__.py +26 -0
- cars/pipelines/default/default_pipeline.py +786 -0
- cars/pipelines/parameters/__init__.py +0 -0
- cars/pipelines/parameters/advanced_parameters.py +417 -0
- cars/pipelines/parameters/advanced_parameters_constants.py +69 -0
- cars/pipelines/parameters/application_parameters.py +71 -0
- cars/pipelines/parameters/depth_map_inputs.py +0 -0
- cars/pipelines/parameters/dsm_inputs.py +918 -0
- cars/pipelines/parameters/dsm_inputs_constants.py +25 -0
- cars/pipelines/parameters/output_constants.py +52 -0
- cars/pipelines/parameters/output_parameters.py +454 -0
- cars/pipelines/parameters/sensor_inputs.py +842 -0
- cars/pipelines/parameters/sensor_inputs_constants.py +49 -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 +31 -0
- cars/pipelines/pipeline_template.py +139 -0
- cars/pipelines/unit/__init__.py +26 -0
- cars/pipelines/unit/unit_pipeline.py +2850 -0
- cars/starter.py +167 -0
- cars-1.0.0rc1.dist-info/METADATA +292 -0
- cars-1.0.0rc1.dist-info/RECORD +200 -0
- cars-1.0.0rc1.dist-info/WHEEL +6 -0
- cars-1.0.0rc1.dist-info/entry_points.txt +8 -0
|
@@ -0,0 +1,401 @@
|
|
|
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
|
+
This module is responsible for the dense matching algorithms:
|
|
22
|
+
- thus it creates a disparity map from a pair of images
|
|
23
|
+
"""
|
|
24
|
+
import copy
|
|
25
|
+
|
|
26
|
+
# Standard imports
|
|
27
|
+
import logging
|
|
28
|
+
from typing import Dict
|
|
29
|
+
|
|
30
|
+
import numpy as np
|
|
31
|
+
import pandora
|
|
32
|
+
import xarray as xr
|
|
33
|
+
|
|
34
|
+
# Third party imports
|
|
35
|
+
from pandora.check_configuration import check_datasets
|
|
36
|
+
from pandora.state_machine import PandoraMachine
|
|
37
|
+
from scipy.interpolate import (
|
|
38
|
+
LinearNDInterpolator,
|
|
39
|
+
NearestNDInterpolator,
|
|
40
|
+
RegularGridInterpolator,
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
from cars.applications.dense_matching import dense_matching_wrappers as dm_wrap
|
|
44
|
+
|
|
45
|
+
# CARS imports
|
|
46
|
+
from cars.core import constants as cst
|
|
47
|
+
from cars.core import inputs
|
|
48
|
+
|
|
49
|
+
# pylint: disable=too-many-lines
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def compute_disparity_grid(
|
|
53
|
+
disp_range_grid,
|
|
54
|
+
left_image_object,
|
|
55
|
+
right_image_object,
|
|
56
|
+
used_band,
|
|
57
|
+
threshold_disp_range_to_borders,
|
|
58
|
+
):
|
|
59
|
+
"""
|
|
60
|
+
Compute dense disparity grids min and max for pandora
|
|
61
|
+
superposable to left image
|
|
62
|
+
|
|
63
|
+
:param disp_range_grid: disp range grid with min and max grids
|
|
64
|
+
:type disp_range_grid: CarsDataset
|
|
65
|
+
:param left_image_object: left image
|
|
66
|
+
:type left_image_object: xr.Dataset
|
|
67
|
+
|
|
68
|
+
:return disp min map, disp_max_map
|
|
69
|
+
:rtype np.ndarray, np.ndarray
|
|
70
|
+
"""
|
|
71
|
+
|
|
72
|
+
disp_min_grid_arr, _ = inputs.rasterio_read_as_array(
|
|
73
|
+
disp_range_grid["grid_min_path"]
|
|
74
|
+
)
|
|
75
|
+
disp_max_grid_arr, _ = inputs.rasterio_read_as_array(
|
|
76
|
+
disp_range_grid["grid_max_path"]
|
|
77
|
+
)
|
|
78
|
+
row_range = disp_range_grid["row_range"]
|
|
79
|
+
col_range = disp_range_grid["col_range"]
|
|
80
|
+
|
|
81
|
+
# Create interpolators
|
|
82
|
+
interp_min = RegularGridInterpolator(
|
|
83
|
+
(
|
|
84
|
+
row_range,
|
|
85
|
+
col_range,
|
|
86
|
+
),
|
|
87
|
+
disp_min_grid_arr,
|
|
88
|
+
)
|
|
89
|
+
interp_max = RegularGridInterpolator(
|
|
90
|
+
(
|
|
91
|
+
row_range,
|
|
92
|
+
col_range,
|
|
93
|
+
),
|
|
94
|
+
disp_max_grid_arr,
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
# Interpolate disp on grid
|
|
98
|
+
roi_with_margins = left_image_object.attrs["roi_with_margins"]
|
|
99
|
+
|
|
100
|
+
row_range = np.arange(roi_with_margins[1], roi_with_margins[3])
|
|
101
|
+
col_range = np.arange(roi_with_margins[0], roi_with_margins[2])
|
|
102
|
+
|
|
103
|
+
row_grid, col_grid = np.meshgrid(row_range, col_range, indexing="ij")
|
|
104
|
+
|
|
105
|
+
disp_min_grid = interp_min((row_grid, col_grid)).astype("float32")
|
|
106
|
+
disp_max_grid = interp_max((row_grid, col_grid)).astype("float32")
|
|
107
|
+
|
|
108
|
+
# Compute extremums of disparity considering left image borders
|
|
109
|
+
if threshold_disp_range_to_borders:
|
|
110
|
+
disp_min_from_borders = np.zeros_like(disp_min_grid)
|
|
111
|
+
disp_max_from_borders = np.zeros_like(disp_max_grid)
|
|
112
|
+
right_msk = (
|
|
113
|
+
np.array(right_image_object[cst.EPI_MSK].loc[used_band]) == 0
|
|
114
|
+
)
|
|
115
|
+
index_of_first_valid_pixel = np.argmax(right_msk, axis=1)
|
|
116
|
+
index_of_last_valid_pixel = np.argmax(
|
|
117
|
+
np.flip(right_msk, axis=1), axis=1
|
|
118
|
+
)
|
|
119
|
+
index_of_last_valid_pixel = (
|
|
120
|
+
right_msk.shape[1] - index_of_last_valid_pixel
|
|
121
|
+
)
|
|
122
|
+
any_valid_pixel_exists = np.any(right_msk, axis=1)
|
|
123
|
+
right_msk_indices = zip( # noqa: B905
|
|
124
|
+
index_of_first_valid_pixel,
|
|
125
|
+
index_of_last_valid_pixel,
|
|
126
|
+
any_valid_pixel_exists,
|
|
127
|
+
)
|
|
128
|
+
for row_id, (first, last, exists) in enumerate(right_msk_indices):
|
|
129
|
+
if exists:
|
|
130
|
+
disp_min_from_borders[row_id, first:last] = np.flip(
|
|
131
|
+
np.arange(first - last, 0)
|
|
132
|
+
)
|
|
133
|
+
disp_max_from_borders[row_id, first:last] = np.flip(
|
|
134
|
+
np.arange(0, last - first)
|
|
135
|
+
)
|
|
136
|
+
disp_min_from_borders = np.minimum(disp_max_grid, disp_min_from_borders)
|
|
137
|
+
disp_max_from_borders = np.maximum(disp_min_grid, disp_max_from_borders)
|
|
138
|
+
disp_min_grid = np.maximum(disp_min_from_borders, disp_min_grid)
|
|
139
|
+
disp_max_grid = np.minimum(disp_max_from_borders, disp_max_grid)
|
|
140
|
+
|
|
141
|
+
# Interpolation might create min > max
|
|
142
|
+
disp_min_grid, disp_max_grid = dm_wrap.to_safe_disp_grid(
|
|
143
|
+
disp_min_grid, disp_max_grid
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
return disp_min_grid, disp_max_grid
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
def compute_disparity( # pylint: disable=too-many-positional-arguments
|
|
150
|
+
left_dataset,
|
|
151
|
+
right_dataset,
|
|
152
|
+
corr_cfg,
|
|
153
|
+
used_band=None,
|
|
154
|
+
disp_min_grid=None,
|
|
155
|
+
disp_max_grid=None,
|
|
156
|
+
compute_disparity_masks=False,
|
|
157
|
+
cropped_range=None,
|
|
158
|
+
margins_to_keep=0,
|
|
159
|
+
classification_fusion_margin=-1,
|
|
160
|
+
texture_bands=None,
|
|
161
|
+
filter_incomplete_disparity_range=True,
|
|
162
|
+
classif_bands_to_mask=None,
|
|
163
|
+
) -> Dict[str, xr.Dataset]:
|
|
164
|
+
"""
|
|
165
|
+
This function will compute disparity.
|
|
166
|
+
|
|
167
|
+
:param left_dataset: Dataset containing left image and mask
|
|
168
|
+
:type left_dataset: xarray.Dataset
|
|
169
|
+
:param right_dataset: Dataset containing right image and mask
|
|
170
|
+
:type right_dataset: xarray.Dataset
|
|
171
|
+
:param corr_cfg: Correlator configuration
|
|
172
|
+
:type corr_cfg: dict
|
|
173
|
+
:param used_band: name of band used for correlation
|
|
174
|
+
:type used_band: str
|
|
175
|
+
:param disp_min_grid: Minimum disparity grid
|
|
176
|
+
(if None, value is taken from left dataset)
|
|
177
|
+
:type disp_min_grid: np ndarray
|
|
178
|
+
:param disp_max_grid: Maximum disparity grid
|
|
179
|
+
(if None, value is taken from left dataset)
|
|
180
|
+
:type disp_max_grid: np ndarray
|
|
181
|
+
:param compute_disparity_masks: Activation of compute_disparity_masks mode
|
|
182
|
+
:type compute_disparity_masks: Boolean
|
|
183
|
+
:param cropped_range: true if disparity range was cropped
|
|
184
|
+
:type cropped_range: numpy array
|
|
185
|
+
:param margins_to_keep: margin to keep after dense matching
|
|
186
|
+
:type margins_to_keep: int
|
|
187
|
+
:param classification_fusion_margin: the margin to add for the fusion
|
|
188
|
+
:type classification_fusion_margin: int
|
|
189
|
+
:param classif_bands_to_mask: bands from classif to mask
|
|
190
|
+
:type classif_bands_to_mask: list of str / int
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
:return: Disparity dataset
|
|
194
|
+
"""
|
|
195
|
+
|
|
196
|
+
# Save dataset
|
|
197
|
+
saved_left_dataset = copy.deepcopy(left_dataset)
|
|
198
|
+
saved_right_dataset = copy.deepcopy(right_dataset)
|
|
199
|
+
|
|
200
|
+
# Check disp min and max bounds with respect to margin used for
|
|
201
|
+
# rectification
|
|
202
|
+
|
|
203
|
+
# Get tile global disp
|
|
204
|
+
disp_min = np.floor(np.min(disp_min_grid))
|
|
205
|
+
disp_max = np.ceil(np.max(disp_max_grid))
|
|
206
|
+
|
|
207
|
+
if disp_min < left_dataset.attrs[cst.EPI_DISP_MIN]:
|
|
208
|
+
logging.error(
|
|
209
|
+
"disp_min ({}) is lower than disp_min used to determine "
|
|
210
|
+
"margin during rectification ({})".format(
|
|
211
|
+
disp_min, left_dataset.attrs["disp_min"]
|
|
212
|
+
)
|
|
213
|
+
)
|
|
214
|
+
|
|
215
|
+
if disp_max > left_dataset.attrs[cst.EPI_DISP_MAX]:
|
|
216
|
+
logging.error(
|
|
217
|
+
"disp_max ({}) is greater than disp_max used to determine "
|
|
218
|
+
"margin during rectification ({})".format(
|
|
219
|
+
disp_max, left_dataset.attrs["disp_max"]
|
|
220
|
+
)
|
|
221
|
+
)
|
|
222
|
+
|
|
223
|
+
# Load pandora plugin
|
|
224
|
+
pandora.import_plugin()
|
|
225
|
+
|
|
226
|
+
# Update nodata values
|
|
227
|
+
left_dataset.attrs[cst.EPI_NO_DATA_IMG] = corr_cfg["input"]["nodata_left"]
|
|
228
|
+
right_dataset.attrs[cst.EPI_NO_DATA_IMG] = corr_cfg["input"]["nodata_right"]
|
|
229
|
+
|
|
230
|
+
# Put disparity in datasets
|
|
231
|
+
left_disparity = xr.DataArray(
|
|
232
|
+
data=np.array(
|
|
233
|
+
[disp_min_grid, disp_max_grid],
|
|
234
|
+
),
|
|
235
|
+
dims=["band_disp", "row", "col"],
|
|
236
|
+
coords={"band_disp": ["min", "max"]},
|
|
237
|
+
)
|
|
238
|
+
|
|
239
|
+
(disp_min_right_grid, disp_max_right_grid) = (
|
|
240
|
+
dm_wrap.estimate_right_grid_disp(disp_min_grid, disp_max_grid)
|
|
241
|
+
)
|
|
242
|
+
# estimation might create max < min
|
|
243
|
+
disp_min_right_grid, disp_max_right_grid = dm_wrap.to_safe_disp_grid(
|
|
244
|
+
disp_min_right_grid, disp_max_right_grid
|
|
245
|
+
)
|
|
246
|
+
|
|
247
|
+
right_disparity = xr.DataArray(
|
|
248
|
+
data=np.array(
|
|
249
|
+
[disp_min_right_grid, disp_max_right_grid],
|
|
250
|
+
),
|
|
251
|
+
dims=["band_disp", "row", "col"],
|
|
252
|
+
coords={"band_disp": ["min", "max"]},
|
|
253
|
+
)
|
|
254
|
+
|
|
255
|
+
left_dataset["disparity"] = left_disparity
|
|
256
|
+
right_dataset["disparity"] = right_disparity
|
|
257
|
+
|
|
258
|
+
# Update invalidity masks: all classes in classification should be 0
|
|
259
|
+
if (
|
|
260
|
+
cst.EPI_CLASSIFICATION in left_dataset
|
|
261
|
+
and classif_bands_to_mask not in (None, [])
|
|
262
|
+
):
|
|
263
|
+
classif_values = (
|
|
264
|
+
left_dataset[cst.EPI_CLASSIFICATION]
|
|
265
|
+
.sel(band_classif=classif_bands_to_mask)
|
|
266
|
+
.values
|
|
267
|
+
)
|
|
268
|
+
left_dataset[cst.EPI_MSK] = np.logical_or(
|
|
269
|
+
left_dataset[cst.EPI_MSK],
|
|
270
|
+
np.repeat(
|
|
271
|
+
np.any(classif_values != 0, axis=0)[np.newaxis, ...],
|
|
272
|
+
left_dataset.sizes["band_im"],
|
|
273
|
+
axis=0,
|
|
274
|
+
),
|
|
275
|
+
)
|
|
276
|
+
if (
|
|
277
|
+
cst.EPI_CLASSIFICATION in right_dataset
|
|
278
|
+
and classif_bands_to_mask not in (None, [])
|
|
279
|
+
):
|
|
280
|
+
classif_values = (
|
|
281
|
+
right_dataset[cst.EPI_CLASSIFICATION]
|
|
282
|
+
.sel(band_classif=classif_bands_to_mask)
|
|
283
|
+
.values
|
|
284
|
+
)
|
|
285
|
+
right_dataset[cst.EPI_MSK] = np.logical_or(
|
|
286
|
+
right_dataset[cst.EPI_MSK],
|
|
287
|
+
np.repeat(
|
|
288
|
+
np.any(classif_values != 0, axis=0)[np.newaxis, ...],
|
|
289
|
+
right_dataset.sizes["band_im"],
|
|
290
|
+
axis=0,
|
|
291
|
+
),
|
|
292
|
+
)
|
|
293
|
+
|
|
294
|
+
if used_band is not None:
|
|
295
|
+
|
|
296
|
+
def remove_band(current_dataset, used_band):
|
|
297
|
+
"""
|
|
298
|
+
Remove band_im dimension from mask
|
|
299
|
+
"""
|
|
300
|
+
current_mask = current_dataset[cst.EPI_MSK]
|
|
301
|
+
current_mask = current_mask.loc[used_band]
|
|
302
|
+
current_dataset = current_dataset.drop_vars([cst.EPI_MSK])
|
|
303
|
+
current_dataset[cst.EPI_MSK] = current_mask
|
|
304
|
+
return current_dataset
|
|
305
|
+
|
|
306
|
+
# remove band_im in masks
|
|
307
|
+
[
|
|
308
|
+
left_dataset,
|
|
309
|
+
saved_left_dataset,
|
|
310
|
+
right_dataset,
|
|
311
|
+
saved_right_dataset,
|
|
312
|
+
] = [
|
|
313
|
+
remove_band(current_dataset, used_band)
|
|
314
|
+
for current_dataset in [
|
|
315
|
+
left_dataset,
|
|
316
|
+
saved_left_dataset,
|
|
317
|
+
right_dataset,
|
|
318
|
+
saved_right_dataset,
|
|
319
|
+
]
|
|
320
|
+
]
|
|
321
|
+
|
|
322
|
+
# Check that the datasets are not full of nan (would crash later)
|
|
323
|
+
if left_dataset["msk"].all() or right_dataset["msk"].all():
|
|
324
|
+
height = left_dataset.sizes["row"]
|
|
325
|
+
width = left_dataset.sizes["col"]
|
|
326
|
+
ref = xr.Dataset(
|
|
327
|
+
coords={
|
|
328
|
+
"row": left_dataset.coords["row"],
|
|
329
|
+
"col": left_dataset.coords["col"],
|
|
330
|
+
"indicator": [
|
|
331
|
+
"confidence_from_ambiguity.cars_1",
|
|
332
|
+
"confidence_from_risk_max.cars_2",
|
|
333
|
+
"confidence_from_risk_min.cars_2",
|
|
334
|
+
"confidence_from_disp_sup_from_risk.cars_2",
|
|
335
|
+
"confidence_from_disp_inf_from_risk.cars_2",
|
|
336
|
+
"confidence_from_interval_bounds_inf.cars_3",
|
|
337
|
+
"confidence_from_interval_bounds_sup.cars_3",
|
|
338
|
+
"confidence_from_left_right_consistency",
|
|
339
|
+
],
|
|
340
|
+
},
|
|
341
|
+
data_vars={
|
|
342
|
+
"disparity_map": (
|
|
343
|
+
("row", "col"),
|
|
344
|
+
np.full((height, width), np.nan, dtype=np.float32),
|
|
345
|
+
),
|
|
346
|
+
"validity_mask": (
|
|
347
|
+
("row", "col"),
|
|
348
|
+
np.ones((height, width), dtype=np.int64),
|
|
349
|
+
),
|
|
350
|
+
"confidence_measure": (
|
|
351
|
+
("row", "col", "indicator"),
|
|
352
|
+
np.full((height, width, 8), np.nan, dtype=np.float32),
|
|
353
|
+
),
|
|
354
|
+
},
|
|
355
|
+
)
|
|
356
|
+
else:
|
|
357
|
+
# Instantiate pandora state machine
|
|
358
|
+
pandora_machine = PandoraMachine()
|
|
359
|
+
# check datasets
|
|
360
|
+
check_datasets(left_dataset, right_dataset)
|
|
361
|
+
|
|
362
|
+
# Run the Pandora pipeline
|
|
363
|
+
ref, _ = pandora.run(
|
|
364
|
+
pandora_machine,
|
|
365
|
+
left_dataset,
|
|
366
|
+
right_dataset,
|
|
367
|
+
corr_cfg,
|
|
368
|
+
)
|
|
369
|
+
|
|
370
|
+
disp_dataset = dm_wrap.create_disp_dataset(
|
|
371
|
+
ref,
|
|
372
|
+
saved_left_dataset,
|
|
373
|
+
saved_right_dataset,
|
|
374
|
+
compute_disparity_masks=compute_disparity_masks,
|
|
375
|
+
disp_min_grid=disp_min_grid,
|
|
376
|
+
disp_max_grid=disp_max_grid,
|
|
377
|
+
cropped_range=cropped_range,
|
|
378
|
+
margins_to_keep=margins_to_keep,
|
|
379
|
+
classification_fusion_margin=classification_fusion_margin,
|
|
380
|
+
texture_bands=texture_bands,
|
|
381
|
+
filter_incomplete_disparity_range=filter_incomplete_disparity_range,
|
|
382
|
+
)
|
|
383
|
+
|
|
384
|
+
return disp_dataset
|
|
385
|
+
|
|
386
|
+
|
|
387
|
+
class LinearInterpNearestExtrap: # pylint: disable=too-few-public-methods
|
|
388
|
+
"""
|
|
389
|
+
Linear interpolation and nearest neighbour extrapolation
|
|
390
|
+
"""
|
|
391
|
+
|
|
392
|
+
def __init__(self, points, values):
|
|
393
|
+
self.interp = LinearNDInterpolator(points, values)
|
|
394
|
+
self.extrap = NearestNDInterpolator(points, values)
|
|
395
|
+
|
|
396
|
+
def __call__(self, *args):
|
|
397
|
+
z_values = self.interp(*args)
|
|
398
|
+
nan_mask = np.isnan(z_values)
|
|
399
|
+
if nan_mask.any():
|
|
400
|
+
return np.where(nan_mask, self.extrap(*args), z_values)
|
|
401
|
+
return z_values
|
|
@@ -0,0 +1,89 @@
|
|
|
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 constants of dense_matching.
|
|
23
|
+
"""
|
|
24
|
+
from pandora import constants as pandora_cst
|
|
25
|
+
|
|
26
|
+
from cars.core import constants_disparity as disp_cst
|
|
27
|
+
|
|
28
|
+
# USED VARIABLES
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
DENSE_MATCHING_RUN_TAG = "dense_matching"
|
|
32
|
+
|
|
33
|
+
# grids disp
|
|
34
|
+
DISP_MIN_GRID = "disp_min_grid"
|
|
35
|
+
DISP_MAX_GRID = "disp_max_grid"
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
# PARAMS
|
|
39
|
+
METHOD = "method"
|
|
40
|
+
MIN_EPI_TILE_SIZE = "min_epi_tile_size"
|
|
41
|
+
MAX_EPI_TILE_SIZE = "max_epi_tile_size"
|
|
42
|
+
EPI_TILE_MARGIN_IN_PERCENT = "epipolar_tile_margin_in_percent"
|
|
43
|
+
MIN_ELEVATION_OFFSET = "min_elevation_offset"
|
|
44
|
+
MAX_ELEVATION_OFFSET = "max_elevation_offset"
|
|
45
|
+
|
|
46
|
+
# ABRIDGED PANDORA CONSTANTS
|
|
47
|
+
IN_VALIDITY_MASK_LEFT = "IN_VALIDITY_MASK_LEFT"
|
|
48
|
+
IN_VALIDITY_MASK_RIGHT = "IN_VALIDITY_MASK_RIGHT"
|
|
49
|
+
RIGHT_INCOMPLETE_DISPARITY_RANGE = "RIGHT_INCOMPLETE_DISPARITY_RANGE"
|
|
50
|
+
STOPPED_INTERPOLATION = "STOPPED_INTERPOLATION"
|
|
51
|
+
FILLED_OCCLUSION = "FILLED_OCCLUSION"
|
|
52
|
+
FILLED_MISMATCH = "FILLED_MISMATCH"
|
|
53
|
+
LEFT_NODATA_OR_BORDER = "LEFT_NODATA_OR_BORDER"
|
|
54
|
+
RIGHT_NODATA_OR_DISPARITY_RANGE_MISSING = (
|
|
55
|
+
"RIGHT_NODATA_OR_DISPARITY_RANGE_MISSING"
|
|
56
|
+
)
|
|
57
|
+
OCCLUSION = "OCCLUSION"
|
|
58
|
+
MISMATCH = "MISMATCH"
|
|
59
|
+
INCOMPLETE_VARIABLE_DISPARITY_RANGE = "INCOMPLETE_VARIABLE_DISPARITY_RANGE"
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def get_cst(key):
|
|
63
|
+
"""
|
|
64
|
+
get pandora constant from abridged key
|
|
65
|
+
|
|
66
|
+
:param key: abridged key of pandora mask
|
|
67
|
+
|
|
68
|
+
Returns:
|
|
69
|
+
_type_: pandora mask constant
|
|
70
|
+
"""
|
|
71
|
+
return pandora_cst.__dict__.get("PANDORA_MSK_PIXEL_" + key)
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
# CORRESPONDING MSK TABLE PANDORA CARS
|
|
75
|
+
MASK_HASH_TABLE = {
|
|
76
|
+
disp_cst.MASKED_REF: get_cst(IN_VALIDITY_MASK_LEFT),
|
|
77
|
+
disp_cst.MASKED_SEC: get_cst(IN_VALIDITY_MASK_RIGHT),
|
|
78
|
+
disp_cst.INCOMPLETE_DISP: get_cst(RIGHT_INCOMPLETE_DISPARITY_RANGE),
|
|
79
|
+
disp_cst.STOPPED_INTERP: get_cst(STOPPED_INTERPOLATION),
|
|
80
|
+
disp_cst.FILLED_OCCLUSION: get_cst(FILLED_OCCLUSION),
|
|
81
|
+
disp_cst.FILLED_FALSE_MATCH: get_cst(FILLED_MISMATCH),
|
|
82
|
+
disp_cst.INVALID_REF: get_cst(LEFT_NODATA_OR_BORDER),
|
|
83
|
+
disp_cst.INVALID_SEC: get_cst(RIGHT_NODATA_OR_DISPARITY_RANGE_MISSING),
|
|
84
|
+
disp_cst.OCCLUSION: get_cst(OCCLUSION),
|
|
85
|
+
disp_cst.FALSE_MATCH: get_cst(MISMATCH),
|
|
86
|
+
disp_cst.INCOMPLETE_VARIABLE_DISP: get_cst(
|
|
87
|
+
INCOMPLETE_VARIABLE_DISPARITY_RANGE
|
|
88
|
+
),
|
|
89
|
+
}
|