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
|
@@ -24,134 +24,13 @@ thus it fills the disparity map with values estimated according to
|
|
|
24
24
|
their neighbourhood.
|
|
25
25
|
"""
|
|
26
26
|
|
|
27
|
-
import copy
|
|
28
|
-
|
|
29
|
-
# Standard imports
|
|
30
|
-
import logging
|
|
31
|
-
import math
|
|
32
|
-
from typing import Tuple
|
|
33
|
-
|
|
34
27
|
# Third party imports
|
|
35
|
-
import matplotlib.pyplot as plt
|
|
36
28
|
import numpy as np
|
|
37
29
|
import xarray as xr
|
|
38
|
-
from rasterio.fill import fillnodata
|
|
39
|
-
from scipy.ndimage import (
|
|
40
|
-
generate_binary_structure,
|
|
41
|
-
label,
|
|
42
|
-
measurements,
|
|
43
|
-
median_filter,
|
|
44
|
-
)
|
|
45
|
-
from scipy.spatial.distance import cdist
|
|
46
|
-
from shapely import affinity
|
|
47
|
-
from skimage.segmentation import find_boundaries
|
|
48
30
|
|
|
49
31
|
# Cars import
|
|
50
32
|
from cars.core import constants as cst
|
|
51
33
|
|
|
52
|
-
from .cpp import dense_match_filling_cpp
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
def add_surrounding_nodata_to_roi(
|
|
56
|
-
roi_mask,
|
|
57
|
-
disp,
|
|
58
|
-
disp_mask,
|
|
59
|
-
):
|
|
60
|
-
"""
|
|
61
|
-
Add surounding nodata to invalidity region
|
|
62
|
-
|
|
63
|
-
:param roi_mask: invalidity mask (values to fill)
|
|
64
|
-
:type roi_mask: 2D np.array (row, col)
|
|
65
|
-
:param disp: disparity values
|
|
66
|
-
:type disp: 2D np.array (row, col)
|
|
67
|
-
:param disp_mask: disparity values mask
|
|
68
|
-
:type disp_mask: 2D np.array (row, col)
|
|
69
|
-
"""
|
|
70
|
-
|
|
71
|
-
struct = generate_binary_structure(2, 2)
|
|
72
|
-
modified_nan_disp_mask = np.nan_to_num(disp_mask, nan=0, posinf=0)
|
|
73
|
-
|
|
74
|
-
all_mask = np.logical_or(
|
|
75
|
-
roi_mask.astype(bool), ~modified_nan_disp_mask.astype(bool)
|
|
76
|
-
)
|
|
77
|
-
|
|
78
|
-
# Added because zero values not included in disp_mask are present
|
|
79
|
-
all_mask = np.logical_or(all_mask, disp == np.nan)
|
|
80
|
-
labeled_msk_array, __ = label(all_mask.astype(int), structure=struct)
|
|
81
|
-
label_of_interest = np.unique(labeled_msk_array[np.where(roi_mask == 1)])
|
|
82
|
-
if len(label_of_interest) != 1:
|
|
83
|
-
logging.error(
|
|
84
|
-
"More than one label found for ROI :\
|
|
85
|
-
{}".format(
|
|
86
|
-
label_of_interest
|
|
87
|
-
)
|
|
88
|
-
)
|
|
89
|
-
|
|
90
|
-
for label_o_i in label_of_interest:
|
|
91
|
-
roi_mask[labeled_msk_array == label_o_i] = 1
|
|
92
|
-
|
|
93
|
-
else:
|
|
94
|
-
roi_mask[labeled_msk_array == label_of_interest] = 1
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
def define_interpolation_band_width(binary_image, percentage):
|
|
98
|
-
"""
|
|
99
|
-
Define number of pixel for later erosion operation
|
|
100
|
-
|
|
101
|
-
:param binary_image: invalidity mask (values to fill)
|
|
102
|
-
:type binary_image: 2D np.array (row, col)
|
|
103
|
-
:param percentage: percentage of border compared to center region
|
|
104
|
-
:type percentage: dict
|
|
105
|
-
|
|
106
|
-
:return: pixel number to erode
|
|
107
|
-
:rtype: int
|
|
108
|
-
"""
|
|
109
|
-
|
|
110
|
-
# Recherche des pixels de contour de la région masquée
|
|
111
|
-
contours = find_boundaries(binary_image, mode="inner")
|
|
112
|
-
# Localisation du centre de la zone masquée
|
|
113
|
-
# TODO: cas d'une zone bien concave --> résultat ok?
|
|
114
|
-
centroid = measurements.center_of_mass(binary_image)
|
|
115
|
-
# Recherche de la dist moy entre contours et centre de la zone
|
|
116
|
-
coords_contours = list(zip(*np.where(contours))) # noqa: B905
|
|
117
|
-
centroid_list = (centroid,) * len(coords_contours)
|
|
118
|
-
all_dist = cdist(centroid_list, coords_contours, "euclidean")
|
|
119
|
-
mean_dist = np.mean(all_dist)
|
|
120
|
-
erosion_value = np.round((percentage * mean_dist))
|
|
121
|
-
return int(erosion_value)
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
def plot_function(
|
|
125
|
-
data,
|
|
126
|
-
fit,
|
|
127
|
-
):
|
|
128
|
-
"""
|
|
129
|
-
Displays shape of plane/quadratic function used in region to fill.
|
|
130
|
-
|
|
131
|
-
:param data: coords and value of valid disparity values
|
|
132
|
-
:type data: 3D np.array (row, col)
|
|
133
|
-
:param fit: Least-squares solution.
|
|
134
|
-
:type fit: ndarray
|
|
135
|
-
|
|
136
|
-
:return: plot of function used in region to fill
|
|
137
|
-
:rtype: matplotlib plot
|
|
138
|
-
"""
|
|
139
|
-
|
|
140
|
-
plt.figure()
|
|
141
|
-
plt_ax = plt.subplot(111, projection="3d")
|
|
142
|
-
plt_ax.scatter(data[:, 0], data[:, 1], data[:, 2], color="b", alpha=0.5)
|
|
143
|
-
plt_ax.set_xlabel("x")
|
|
144
|
-
plt_ax.set_ylabel("y")
|
|
145
|
-
plt_ax.set_zlabel("z")
|
|
146
|
-
xlim = plt_ax.get_xlim()
|
|
147
|
-
ylim = plt_ax.get_ylim()
|
|
148
|
-
v_x, v_y = np.meshgrid(
|
|
149
|
-
np.arange(xlim[0], xlim[1]), np.arange(ylim[0], ylim[1])
|
|
150
|
-
)
|
|
151
|
-
val_ref = fit[0] * v_x + fit[1] * v_y + fit[2]
|
|
152
|
-
plt_ax.plot_wireframe(v_x, v_y, val_ref, color="r", alpha=0.5)
|
|
153
|
-
plt.show()
|
|
154
|
-
|
|
155
34
|
|
|
156
35
|
def add_empty_filling_band(
|
|
157
36
|
output_dataset: xr.Dataset,
|
|
@@ -202,225 +81,3 @@ def update_filling(
|
|
|
202
81
|
# Add True values from inputmask to output accurate band
|
|
203
82
|
filling = filling.astype(bool)
|
|
204
83
|
output_dataset[cst.EPI_FILLING].sel(**filling_type).values[filling] = True
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
# --------------------------------------------------------------------
|
|
208
|
-
# Global functions for interpolation process
|
|
209
|
-
# --------------------------------------------------------------------
|
|
210
|
-
def make_raster_interpolation(
|
|
211
|
-
raster: np.ndarray, mask: np.ndarray, options: dict
|
|
212
|
-
):
|
|
213
|
-
"""
|
|
214
|
-
Raster interpolation (scipy, rasterio or pandora)
|
|
215
|
-
:param raster: disparity values
|
|
216
|
-
:type raster: 2D np.array (row, col)
|
|
217
|
-
:param mask: invalidity mask (values to fill)
|
|
218
|
-
:type mask: 2D np.array (row, col)
|
|
219
|
-
:param options: parameters for interpolation methods
|
|
220
|
-
:type options: dict
|
|
221
|
-
:return: interpolated raster
|
|
222
|
-
:rtype: 2D np.array
|
|
223
|
-
"""
|
|
224
|
-
|
|
225
|
-
if options["type"] == "fillnodata":
|
|
226
|
-
interpol_raster_tmp = np.copy(raster)
|
|
227
|
-
interpol_raster_tmp = fillnodata(
|
|
228
|
-
interpol_raster_tmp,
|
|
229
|
-
mask=~mask,
|
|
230
|
-
max_search_distance=options["max_search_distance"],
|
|
231
|
-
smoothing_iterations=options["smoothing_iterations"],
|
|
232
|
-
)
|
|
233
|
-
interpol_raster = median_filter(interpol_raster_tmp, size=(3, 3))
|
|
234
|
-
elif options["type"] == "pandora" and options["method"] == "mc_cnn":
|
|
235
|
-
interpol_raster, __ = fill_disp_pandora(raster, mask, 16)
|
|
236
|
-
elif options["type"] == "pandora" and options["method"] == "sgm":
|
|
237
|
-
interpol_raster, __ = fill_disp_pandora(raster, mask, 8)
|
|
238
|
-
else:
|
|
239
|
-
raise RuntimeError("Invalid interpolation type.")
|
|
240
|
-
return interpol_raster
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
def fill_disp_pandora(
|
|
244
|
-
disp: np.ndarray, msk_fill_disp: np.ndarray, nb_directions: int
|
|
245
|
-
) -> Tuple[np.ndarray, np.ndarray]:
|
|
246
|
-
"""
|
|
247
|
-
Interpolation of the left disparity map to fill holes.
|
|
248
|
-
Interpolate invalid pixel by finding the nearest correct pixels in
|
|
249
|
-
8/16 different directions and use the median of their disparities.
|
|
250
|
-
?bontar, J., & LeCun, Y. (2016). Stereo matching by training
|
|
251
|
-
a convolutional neural network to compare image
|
|
252
|
-
patches. The journal of machine learning research, 17(1), 2287-2318.
|
|
253
|
-
HIRSCHMULLER, Heiko. Stereo processing by semiglobal matching
|
|
254
|
-
and mutual information.
|
|
255
|
-
IEEE Transactions on pattern analysis and machine intelligence,
|
|
256
|
-
2007, vol. 30, no 2, p. 328-341.
|
|
257
|
-
|
|
258
|
-
Copied/adapted fct from pandora/validation/interpolated_disparity.py
|
|
259
|
-
|
|
260
|
-
:param disp: disparity map
|
|
261
|
-
:type disp: 2D np.array (row, col)
|
|
262
|
-
:param msk_fill_disp: validity mask
|
|
263
|
-
:type msk_fill_disp: 2D np.array (row, col)
|
|
264
|
-
:param nb_directions: nb directions to explore
|
|
265
|
-
:type nb_directions: integer
|
|
266
|
-
|
|
267
|
-
:return: the interpolate left disparity map,
|
|
268
|
-
with the validity mask update :
|
|
269
|
-
:rtype: tuple(2D np.array (row, col), 2D np.array (row, col))
|
|
270
|
-
"""
|
|
271
|
-
return dense_match_filling_cpp.fill_disp_pandora(
|
|
272
|
-
disp, msk_fill_disp, nb_directions
|
|
273
|
-
)
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
def estimate_poly_with_disp(poly, dmin=0, dmax=0):
|
|
277
|
-
"""
|
|
278
|
-
Estimate new polygone using disparity range
|
|
279
|
-
|
|
280
|
-
:param poly: polygone to estimate
|
|
281
|
-
:type poly: Polygon
|
|
282
|
-
:param dmin: minimum disparity
|
|
283
|
-
:type dmin: int
|
|
284
|
-
:param dmax: maximum disparity
|
|
285
|
-
:type dmax: int
|
|
286
|
-
|
|
287
|
-
:return: polygon in disparity range
|
|
288
|
-
:rtype: Polygon
|
|
289
|
-
|
|
290
|
-
"""
|
|
291
|
-
|
|
292
|
-
dmin = int(math.floor(dmin))
|
|
293
|
-
dmax = int(math.ceil(dmax))
|
|
294
|
-
|
|
295
|
-
new_poly = copy.copy(poly)
|
|
296
|
-
for disp in range(dmin, dmax + 1):
|
|
297
|
-
translated_poly = affinity.translate(poly, xoff=0.0, yoff=disp)
|
|
298
|
-
new_poly = new_poly.union(translated_poly)
|
|
299
|
-
|
|
300
|
-
return poly
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
def get_corresponding_holes(tile_poly, holes_poly_list):
|
|
304
|
-
"""
|
|
305
|
-
Get list of holes situated in tile
|
|
306
|
-
|
|
307
|
-
:param tile_poly: envelop of tile
|
|
308
|
-
:type tile_poly: Polygon
|
|
309
|
-
:param holes_poly_list: envelop of holes
|
|
310
|
-
:type holes_poly_list: list(Polygon)
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
:return: list of holes envelops
|
|
314
|
-
:rtype: list(Polygon)
|
|
315
|
-
|
|
316
|
-
"""
|
|
317
|
-
|
|
318
|
-
corresponding_holes = []
|
|
319
|
-
for poly in holes_poly_list:
|
|
320
|
-
if tile_poly.intersects(poly):
|
|
321
|
-
corresponding_holes.append(poly)
|
|
322
|
-
|
|
323
|
-
return corresponding_holes
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
def get_corresponding_tiles(tiles_polygones, corresponding_holes, epi_disp_map):
|
|
327
|
-
"""
|
|
328
|
-
Get list of tiles intersecting with holes
|
|
329
|
-
|
|
330
|
-
:param tiles_polygones: envelop of tiles
|
|
331
|
-
:type tiles_polygones: list(Polygon)
|
|
332
|
-
:param corresponding_holes: envelop of holes
|
|
333
|
-
:type corresponding_holes: list(Polygon)
|
|
334
|
-
:param epi_disp_map: disparity map cars dataset
|
|
335
|
-
:type epi_disp_map: CarsDataset
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
:return: list of tiles to use (window, overlap, xr.Dataset)
|
|
339
|
-
:rtype: list(tuple)
|
|
340
|
-
|
|
341
|
-
"""
|
|
342
|
-
corresponding_tiles_row_col = []
|
|
343
|
-
corresponding_tiles = []
|
|
344
|
-
|
|
345
|
-
for key_tile, poly_tile in tiles_polygones.items():
|
|
346
|
-
for poly_hole in corresponding_holes:
|
|
347
|
-
if poly_tile.intersects(poly_hole):
|
|
348
|
-
if key_tile not in corresponding_tiles_row_col:
|
|
349
|
-
corresponding_tiles_row_col.append(key_tile)
|
|
350
|
-
|
|
351
|
-
for row, col in corresponding_tiles_row_col:
|
|
352
|
-
corresponding_tiles.append(
|
|
353
|
-
(
|
|
354
|
-
epi_disp_map.tiling_grid[row, col],
|
|
355
|
-
epi_disp_map.overlaps[row, col],
|
|
356
|
-
epi_disp_map[row, col],
|
|
357
|
-
)
|
|
358
|
-
)
|
|
359
|
-
|
|
360
|
-
return corresponding_tiles
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
def get_polygons_from_cars_ds(cars_ds):
|
|
364
|
-
"""
|
|
365
|
-
Get the holes envelops computed in holes detection application
|
|
366
|
-
cars_ds must contain dicts, and not delayed.
|
|
367
|
-
This function must be called after an orchestrator.breakpoint()
|
|
368
|
-
|
|
369
|
-
:param cars_ds: holes cars dataset
|
|
370
|
-
:type cars_ds: CarsDataset
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
:return: list of holes
|
|
374
|
-
:rtype: list(Polygon)
|
|
375
|
-
"""
|
|
376
|
-
|
|
377
|
-
list_poly = []
|
|
378
|
-
|
|
379
|
-
if cars_ds is not None:
|
|
380
|
-
for row in range(cars_ds.shape[0]):
|
|
381
|
-
for col in range(cars_ds.shape[1]):
|
|
382
|
-
if cars_ds[row, col] is not None:
|
|
383
|
-
list_poly += cars_ds[row, col].data["list_bbox"]
|
|
384
|
-
|
|
385
|
-
return list_poly
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
def merge_intersecting_polygones(list_poly):
|
|
389
|
-
"""
|
|
390
|
-
Merge polygons that intersects each other
|
|
391
|
-
|
|
392
|
-
:param list_poly: list of holes
|
|
393
|
-
:type list_poly: list(Polygon)
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
:return: list of holes
|
|
397
|
-
:rtype: list(Polygon)
|
|
398
|
-
"""
|
|
399
|
-
|
|
400
|
-
new_list_poly = list_poly
|
|
401
|
-
|
|
402
|
-
merged_list = []
|
|
403
|
-
|
|
404
|
-
while len(new_list_poly) > 0:
|
|
405
|
-
current_poly = new_list_poly[0]
|
|
406
|
-
|
|
407
|
-
new_poly = current_poly
|
|
408
|
-
to_delete = [0]
|
|
409
|
-
|
|
410
|
-
for element_id in range(1, len(new_list_poly)):
|
|
411
|
-
if new_poly.intersects(new_list_poly[element_id]):
|
|
412
|
-
# Delete from list
|
|
413
|
-
to_delete.append(element_id)
|
|
414
|
-
# Merge with current
|
|
415
|
-
new_poly = new_poly.union(new_list_poly[element_id])
|
|
416
|
-
|
|
417
|
-
# Add new poly to merged list
|
|
418
|
-
merged_list.append(new_poly)
|
|
419
|
-
|
|
420
|
-
# Delete element
|
|
421
|
-
for _ in range(len(to_delete)):
|
|
422
|
-
# Start with last ones
|
|
423
|
-
pos = to_delete.pop()
|
|
424
|
-
new_list_poly.pop(pos)
|
|
425
|
-
|
|
426
|
-
return merged_list
|
|
@@ -94,6 +94,10 @@ class ZerosPadding(
|
|
|
94
94
|
overloaded_conf["method"] = conf.get("method", "zero_padding")
|
|
95
95
|
|
|
96
96
|
overloaded_conf["classification"] = conf.get("classification", None)
|
|
97
|
+
if isinstance(overloaded_conf["classification"], str):
|
|
98
|
+
overloaded_conf["classification"] = [
|
|
99
|
+
overloaded_conf["classification"]
|
|
100
|
+
]
|
|
97
101
|
overloaded_conf["fill_valid_pixels"] = conf.get(
|
|
98
102
|
"fill_valid_pixels", True
|
|
99
103
|
)
|
|
@@ -234,7 +238,7 @@ class ZerosPadding(
|
|
|
234
238
|
epipolar_disparity_map[row, col],
|
|
235
239
|
window,
|
|
236
240
|
overlap,
|
|
237
|
-
|
|
241
|
+
classif=self.classification,
|
|
238
242
|
fill_valid_pixels=self.fill_valid_pixels,
|
|
239
243
|
saving_info=full_saving_info,
|
|
240
244
|
)
|
|
@@ -249,11 +253,12 @@ class ZerosPadding(
|
|
|
249
253
|
return res
|
|
250
254
|
|
|
251
255
|
|
|
256
|
+
# pylint: disable=too-many-positional-arguments
|
|
252
257
|
def fill_disparity_zeros_wrapper(
|
|
253
258
|
disp,
|
|
254
259
|
window,
|
|
255
260
|
overlap,
|
|
256
|
-
|
|
261
|
+
classif,
|
|
257
262
|
fill_valid_pixels,
|
|
258
263
|
saving_info=None,
|
|
259
264
|
):
|
|
@@ -266,8 +271,8 @@ def fill_disparity_zeros_wrapper(
|
|
|
266
271
|
:type window: list
|
|
267
272
|
:param overlap: overlap [row min, row max, col min col max]
|
|
268
273
|
:type overlap: list
|
|
269
|
-
:param
|
|
270
|
-
:type
|
|
274
|
+
:param classif: classification tags
|
|
275
|
+
:type classif: list
|
|
271
276
|
:param fill_valid_pixels: option to fill valid pixels
|
|
272
277
|
:type fill_valid_pixels: bool
|
|
273
278
|
:param saving_info: saving infos
|
|
@@ -278,7 +283,7 @@ def fill_disparity_zeros_wrapper(
|
|
|
278
283
|
"""
|
|
279
284
|
# Add a band to disparity dataset to memorize which pixels are filled
|
|
280
285
|
disp = fd_wrappers.add_empty_filling_band(disp, ["zeros_padding"])
|
|
281
|
-
fd_algo.fill_disp_using_zero_padding(disp,
|
|
286
|
+
fd_algo.fill_disp_using_zero_padding(disp, classif, fill_valid_pixels)
|
|
282
287
|
result = copy.copy(disp)
|
|
283
288
|
|
|
284
289
|
# Fill with attributes
|
|
@@ -126,6 +126,7 @@ class DenseMatching(ApplicationTemplate, metaclass=ABCMeta):
|
|
|
126
126
|
|
|
127
127
|
"""
|
|
128
128
|
|
|
129
|
+
# pylint: disable=too-many-positional-arguments
|
|
129
130
|
@abstractmethod
|
|
130
131
|
def generate_disparity_grids(
|
|
131
132
|
self,
|
|
@@ -184,7 +185,7 @@ class DenseMatching(ApplicationTemplate, metaclass=ABCMeta):
|
|
|
184
185
|
"""
|
|
185
186
|
|
|
186
187
|
@abstractmethod
|
|
187
|
-
def run(
|
|
188
|
+
def run( # pylint: disable=too-many-positional-arguments
|
|
188
189
|
self,
|
|
189
190
|
epipolar_images_left,
|
|
190
191
|
epipolar_images_right,
|
|
@@ -35,11 +35,11 @@ from typing import Dict, Tuple
|
|
|
35
35
|
import numpy as np
|
|
36
36
|
import pandora
|
|
37
37
|
import xarray as xr
|
|
38
|
-
from affine import Affine
|
|
39
38
|
from json_checker import And, Checker, Or
|
|
40
39
|
from pandora.check_configuration import check_pipeline_section
|
|
41
40
|
from pandora.img_tools import add_global_disparity
|
|
42
41
|
from pandora.state_machine import PandoraMachine
|
|
42
|
+
from rasterio.profiles import DefaultGTiffProfile
|
|
43
43
|
from scipy.ndimage import maximum_filter, minimum_filter
|
|
44
44
|
|
|
45
45
|
import cars.applications.dense_matching.dense_matching_constants as dm_cst
|
|
@@ -78,8 +78,10 @@ class CensusMccnnSgm(
|
|
|
78
78
|
"census_sgm_mountain_and_vegetation",
|
|
79
79
|
"census_sgm_homogeneous",
|
|
80
80
|
"mccnn_sgm",
|
|
81
|
+
"auto",
|
|
82
|
+
"custom",
|
|
81
83
|
],
|
|
82
|
-
): # pylint: disable=R0903,disable=R0902
|
|
84
|
+
): # pylint: disable=R0903,disable=R0902,disable=C0302
|
|
83
85
|
"""
|
|
84
86
|
Census SGM & MCCNN SGM matching class
|
|
85
87
|
"""
|
|
@@ -168,7 +170,6 @@ class CensusMccnnSgm(
|
|
|
168
170
|
:rtype: dict
|
|
169
171
|
|
|
170
172
|
"""
|
|
171
|
-
|
|
172
173
|
# init conf
|
|
173
174
|
if conf is not None:
|
|
174
175
|
overloaded_conf = conf.copy()
|
|
@@ -177,9 +178,21 @@ class CensusMccnnSgm(
|
|
|
177
178
|
overloaded_conf = {}
|
|
178
179
|
|
|
179
180
|
# Overload conf
|
|
181
|
+
# check loader
|
|
182
|
+
loader_conf = conf.get("loader_conf", None)
|
|
183
|
+
default_method = "auto"
|
|
184
|
+
if loader_conf is not None:
|
|
185
|
+
default_method = "custom"
|
|
186
|
+
loader = conf.get("loader", "pandora")
|
|
180
187
|
overloaded_conf["method"] = conf.get(
|
|
181
|
-
"method",
|
|
188
|
+
"method", default_method
|
|
182
189
|
) # change it if census_sgm is not default
|
|
190
|
+
if overloaded_conf["method"] == "auto" and loader_conf is not None:
|
|
191
|
+
raise RuntimeError(
|
|
192
|
+
"It's not possible to use auto method with custom "
|
|
193
|
+
"loader configuration"
|
|
194
|
+
)
|
|
195
|
+
|
|
183
196
|
# method called in abstract_dense_matching_app.py
|
|
184
197
|
overloaded_conf["min_epi_tile_size"] = conf.get(
|
|
185
198
|
"min_epi_tile_size", 300
|
|
@@ -278,10 +291,6 @@ class CensusMccnnSgm(
|
|
|
278
291
|
|
|
279
292
|
overloaded_conf["performance_map_method"] = perf_map_method
|
|
280
293
|
|
|
281
|
-
# check loader
|
|
282
|
-
loader_conf = conf.get("loader_conf", None)
|
|
283
|
-
loader = conf.get("loader", "pandora")
|
|
284
|
-
|
|
285
294
|
if overloaded_conf["use_cross_validation"] is True:
|
|
286
295
|
overloaded_conf["use_cross_validation"] = "fast"
|
|
287
296
|
|
|
@@ -311,13 +320,20 @@ class CensusMccnnSgm(
|
|
|
311
320
|
# Get params from loader
|
|
312
321
|
self.loader = pandora_loader
|
|
313
322
|
self.corr_config = collections.OrderedDict(pandora_loader.get_conf())
|
|
314
|
-
|
|
315
323
|
# Instantiate margins from pandora check conf
|
|
316
324
|
# create the dataset
|
|
325
|
+
classif_bands = pandora_loader.get_classif_bands()
|
|
317
326
|
fake_dataset = xr.Dataset(
|
|
318
|
-
data_vars={
|
|
327
|
+
data_vars={
|
|
328
|
+
"image": (["row", "col"], np.zeros((10, 10))),
|
|
329
|
+
"classif": (
|
|
330
|
+
["row", "col", "band_classif"],
|
|
331
|
+
np.zeros((10, 10, len(classif_bands)), dtype=np.int32),
|
|
332
|
+
),
|
|
333
|
+
},
|
|
319
334
|
coords={
|
|
320
335
|
"band_im": [overloaded_conf["used_band"]],
|
|
336
|
+
"band_classif": classif_bands,
|
|
321
337
|
"row": np.arange(10),
|
|
322
338
|
"col": np.arange(10),
|
|
323
339
|
},
|
|
@@ -327,7 +343,6 @@ class CensusMccnnSgm(
|
|
|
327
343
|
pandora.import_plugin()
|
|
328
344
|
pandora_machine = PandoraMachine()
|
|
329
345
|
corr_config_pipeline = {"pipeline": dict(self.corr_config["pipeline"])}
|
|
330
|
-
|
|
331
346
|
saved_schema = copy.deepcopy(
|
|
332
347
|
pandora.matching_cost.matching_cost.AbstractMatchingCost.schema
|
|
333
348
|
)
|
|
@@ -340,7 +355,11 @@ class CensusMccnnSgm(
|
|
|
340
355
|
)
|
|
341
356
|
self.margins = pandora_machine.margins.global_margins
|
|
342
357
|
|
|
343
|
-
overloaded_conf["
|
|
358
|
+
if overloaded_conf["method"] != "auto":
|
|
359
|
+
# not final configuration
|
|
360
|
+
overloaded_conf["loader_conf"] = self.corr_config
|
|
361
|
+
else:
|
|
362
|
+
overloaded_conf["loader_conf"] = None
|
|
344
363
|
|
|
345
364
|
application_schema = {
|
|
346
365
|
"method": str,
|
|
@@ -417,7 +436,6 @@ class CensusMccnnSgm(
|
|
|
417
436
|
"Maximal disparity should be bigger than "
|
|
418
437
|
"minimal disparity for dense matching"
|
|
419
438
|
)
|
|
420
|
-
|
|
421
439
|
return overloaded_conf
|
|
422
440
|
|
|
423
441
|
def check_conf_confidence_filtering(self, overloaded_conf):
|
|
@@ -471,6 +489,7 @@ class CensusMccnnSgm(
|
|
|
471
489
|
overloaded_conf["confidence_filtering"]
|
|
472
490
|
)
|
|
473
491
|
|
|
492
|
+
@cars_profile(name="Get margin fun")
|
|
474
493
|
def get_margins_fun(self, grid_left, disp_range_grid):
|
|
475
494
|
"""
|
|
476
495
|
Get Margins function that generates margins needed by
|
|
@@ -597,6 +616,13 @@ class CensusMccnnSgm(
|
|
|
597
616
|
|
|
598
617
|
return margins_wrapper
|
|
599
618
|
|
|
619
|
+
def get_method(self):
|
|
620
|
+
"""
|
|
621
|
+
return the method that will be used in dense_matching
|
|
622
|
+
"""
|
|
623
|
+
|
|
624
|
+
return self.used_method
|
|
625
|
+
|
|
600
626
|
@cars_profile(name="Optimal size estimation")
|
|
601
627
|
def get_optimal_tile_size(self, disp_range_grid, max_ram_per_worker):
|
|
602
628
|
"""
|
|
@@ -706,6 +732,7 @@ class CensusMccnnSgm(
|
|
|
706
732
|
required_bands["right"] = self.required_bands
|
|
707
733
|
return required_bands
|
|
708
734
|
|
|
735
|
+
# pylint: disable=too-many-positional-arguments
|
|
709
736
|
@cars_profile(name="Disp Grid Generation")
|
|
710
737
|
def generate_disparity_grids( # noqa: C901
|
|
711
738
|
self,
|
|
@@ -714,8 +741,6 @@ class CensusMccnnSgm(
|
|
|
714
741
|
geom_plugin_with_dem_and_geoid,
|
|
715
742
|
dmin=None,
|
|
716
743
|
dmax=None,
|
|
717
|
-
altitude_delta_min=None,
|
|
718
|
-
altitude_delta_max=None,
|
|
719
744
|
dem_median=None,
|
|
720
745
|
dem_min=None,
|
|
721
746
|
dem_max=None,
|
|
@@ -740,10 +765,6 @@ class CensusMccnnSgm(
|
|
|
740
765
|
:type dmin: float
|
|
741
766
|
:param dmax: maximum disparity
|
|
742
767
|
:type dmax: float
|
|
743
|
-
:param altitude_delta_max: Delta max of altitude
|
|
744
|
-
:type altitude_delta_max: int
|
|
745
|
-
:param altitude_delta_min: Delta min of altitude
|
|
746
|
-
:type altitude_delta_min: int
|
|
747
768
|
:param dem_median: path to median dem
|
|
748
769
|
:type dem_median: str
|
|
749
770
|
:param dem_min: path to minimum dem
|
|
@@ -792,26 +813,7 @@ class CensusMccnnSgm(
|
|
|
792
813
|
global_infos_cars_ds = cars_dataset.CarsDataset("dict")
|
|
793
814
|
|
|
794
815
|
# Generate profile
|
|
795
|
-
|
|
796
|
-
epi_size_row,
|
|
797
|
-
step_row,
|
|
798
|
-
0.0,
|
|
799
|
-
epi_size_col,
|
|
800
|
-
0.0,
|
|
801
|
-
step_col,
|
|
802
|
-
)
|
|
803
|
-
|
|
804
|
-
transform = Affine.from_gdal(*geotransform)
|
|
805
|
-
raster_profile = collections.OrderedDict(
|
|
806
|
-
{
|
|
807
|
-
"height": nb_rows,
|
|
808
|
-
"width": nb_cols,
|
|
809
|
-
"driver": "GTiff",
|
|
810
|
-
"dtype": "float32",
|
|
811
|
-
"transform": transform,
|
|
812
|
-
"tiled": True,
|
|
813
|
-
}
|
|
814
|
-
)
|
|
816
|
+
raster_profile = DefaultGTiffProfile(count=1)
|
|
815
817
|
|
|
816
818
|
# saving infos
|
|
817
819
|
# disp grids
|
|
@@ -832,19 +834,13 @@ class CensusMccnnSgm(
|
|
|
832
834
|
|
|
833
835
|
if None not in (dmin, dmax):
|
|
834
836
|
# use global disparity range
|
|
835
|
-
if None not in (dem_min, dem_max)
|
|
836
|
-
altitude_delta_min,
|
|
837
|
-
altitude_delta_max,
|
|
838
|
-
):
|
|
837
|
+
if None not in (dem_min, dem_max):
|
|
839
838
|
raise RuntimeError("Mix between local and global mode")
|
|
840
839
|
|
|
841
840
|
# Only one tile
|
|
842
841
|
grid_disp_range.tiling_grid = np.array([[[0, nb_rows, 0, nb_cols]]])
|
|
843
842
|
|
|
844
|
-
elif None not in (dem_min, dem_max, dem_median)
|
|
845
|
-
altitude_delta_min,
|
|
846
|
-
altitude_delta_max,
|
|
847
|
-
):
|
|
843
|
+
elif None not in (dem_min, dem_max, dem_median):
|
|
848
844
|
|
|
849
845
|
# Generate multiple tiles
|
|
850
846
|
grid_tile_size = self.epi_disp_grid_tile_size
|
|
@@ -902,10 +898,7 @@ class CensusMccnnSgm(
|
|
|
902
898
|
|
|
903
899
|
if None not in (dmin, dmax):
|
|
904
900
|
# use global disparity range
|
|
905
|
-
if None not in (dem_min, dem_max)
|
|
906
|
-
altitude_delta_min,
|
|
907
|
-
altitude_delta_max,
|
|
908
|
-
):
|
|
901
|
+
if None not in (dem_min, dem_max):
|
|
909
902
|
raise RuntimeError("Mix between local and global mode")
|
|
910
903
|
|
|
911
904
|
saving_info_global_infos_full = ocht.update_saving_infos(
|
|
@@ -930,10 +923,7 @@ class CensusMccnnSgm(
|
|
|
930
923
|
saving_info_global_infos_full,
|
|
931
924
|
)
|
|
932
925
|
|
|
933
|
-
elif None not in (dem_min, dem_max, dem_median)
|
|
934
|
-
altitude_delta_min,
|
|
935
|
-
altitude_delta_max,
|
|
936
|
-
):
|
|
926
|
+
elif None not in (dem_min, dem_max, dem_median):
|
|
937
927
|
|
|
938
928
|
# use filter to propagate min and max
|
|
939
929
|
filter_overlap = (
|
|
@@ -970,8 +960,6 @@ class CensusMccnnSgm(
|
|
|
970
960
|
dem_median,
|
|
971
961
|
dem_min,
|
|
972
962
|
dem_max,
|
|
973
|
-
altitude_delta_min,
|
|
974
|
-
altitude_delta_max,
|
|
975
963
|
raster_profile,
|
|
976
964
|
full_saving_info,
|
|
977
965
|
saving_info_global_infos_full,
|
|
@@ -1002,7 +990,7 @@ class CensusMccnnSgm(
|
|
|
1002
990
|
|
|
1003
991
|
return grid_disp_range_dict
|
|
1004
992
|
|
|
1005
|
-
def run(
|
|
993
|
+
def run( # pylint: disable=too-many-positional-arguments
|
|
1006
994
|
self,
|
|
1007
995
|
epipolar_images_left,
|
|
1008
996
|
epipolar_images_right,
|
|
@@ -1075,7 +1063,6 @@ class CensusMccnnSgm(
|
|
|
1075
1063
|
|
|
1076
1064
|
:rtype: CarsDataset
|
|
1077
1065
|
"""
|
|
1078
|
-
|
|
1079
1066
|
# Default orchestrator
|
|
1080
1067
|
if orchestrator is None:
|
|
1081
1068
|
# Create default sequential orchestrator for current application
|
|
@@ -1221,6 +1208,7 @@ class CensusMccnnSgm(
|
|
|
1221
1208
|
for col in range(epipolar_disparity_map.shape[1]):
|
|
1222
1209
|
for row in range(epipolar_disparity_map.shape[0]):
|
|
1223
1210
|
use_tile = False
|
|
1211
|
+
crop_with_range = None
|
|
1224
1212
|
if type(None) not in (
|
|
1225
1213
|
type(epipolar_images_left[row, col]),
|
|
1226
1214
|
type(epipolar_images_right[row, col]),
|
|
@@ -1287,7 +1275,7 @@ class CensusMccnnSgm(
|
|
|
1287
1275
|
return epipolar_disparity_map
|
|
1288
1276
|
|
|
1289
1277
|
|
|
1290
|
-
def compute_disparity_wrapper(
|
|
1278
|
+
def compute_disparity_wrapper( # pylint: disable=too-many-positional-arguments
|
|
1291
1279
|
left_image_object: xr.Dataset,
|
|
1292
1280
|
right_image_object: xr.Dataset,
|
|
1293
1281
|
corr_cfg: dict,
|