cars 1.0.0a3__cp313-cp313-win_amd64.whl → 1.0.0a4__cp313-cp313-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_template.py +20 -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 +80 -36
- cars/applications/dem_generation/dem_generation_algo.py +1 -1
- cars/applications/dem_generation/dem_generation_wrappers.py +23 -57
- cars/applications/dem_generation/dichotomic_generation_app.py +3 -3
- cars/applications/dem_generation/rasterization_app.py +100 -41
- 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 +38 -39
- cars/applications/dense_matching/cpp/dense_matching_cpp.cp313-win_amd64.dll.a +0 -0
- cars/applications/dense_matching/cpp/dense_matching_cpp.cp313-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 +84 -62
- cars/applications/dense_matching/loaders/pandora_loader.py +91 -33
- cars/applications/dsm_filling/border_interpolation_app.py +1 -7
- cars/applications/dsm_filling/bulldozer_filling_app.py +2 -8
- cars/applications/dsm_filling/exogenous_filling_app.py +4 -9
- 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 +2 -1
- cars/applications/point_cloud_outlier_removal/outlier_removal_algo.py +9 -8
- cars/applications/point_cloud_outlier_removal/small_components_app.py +96 -267
- cars/applications/point_cloud_outlier_removal/statistical_app.py +116 -275
- cars/applications/rasterization/abstract_pc_rasterization_app.py +1 -1
- cars/applications/rasterization/rasterization_algo.py +18 -6
- cars/applications/rasterization/rasterization_wrappers.py +2 -1
- cars/applications/rasterization/simple_gaussian_app.py +60 -113
- cars/applications/resampling/abstract_resampling_app.py +1 -1
- cars/applications/resampling/bicubic_resampling_app.py +3 -1
- cars/applications/resampling/resampling_algo.py +16 -4
- 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 +3 -3
- 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 +256 -25
- cars/core/geometry/shareloc_geometry.py +110 -82
- cars/core/inputs.py +57 -19
- cars/core/outputs.py +1 -1
- cars/core/preprocessing.py +17 -3
- cars/core/projection.py +9 -6
- cars/core/tiling.py +10 -3
- cars/data_structures/cars_dataset.py +5 -5
- 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 +148 -21
- cars/orchestrator/cluster/mp_cluster/multiprocessing_cluster.py +11 -3
- 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 +14 -3
- 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 +462 -1073
- cars/pipelines/parameters/advanced_parameters.py +74 -64
- cars/pipelines/parameters/advanced_parameters_constants.py +2 -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 +2 -2
- cars/pipelines/parameters/sensor_inputs.py +30 -75
- 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 +527 -1016
- cars/starter.py +4 -3
- cars-1.0.0a4.dist-info/DELVEWHEEL +2 -0
- {cars-1.0.0a3.dist-info → cars-1.0.0a4.dist-info}/METADATA +135 -53
- {cars-1.0.0a3.dist-info → cars-1.0.0a4.dist-info}/RECORD +115 -131
- 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.cp313-win_amd64.dll.a +0 -0
- cars/applications/dense_match_filling/cpp/dense_match_filling_cpp.cp313-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.0a3.dist-info/DELVEWHEEL +0 -2
- cars.libs/libgcc_s_seh-1-ca70890bbc5723b6d0ea31e9c9cded2b.dll +0 -0
- cars.libs/libstdc++-6-00ee19f73d5122a1277c137b1c218401.dll +0 -0
- cars.libs/libwinpthread-1-f5042e8e3d21edce20c1bc99445f551b.dll +0 -0
- {cars-1.0.0a3.dist-info → cars-1.0.0a4.dist-info}/WHEEL +0 -0
- {cars-1.0.0a3.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,
|
|
@@ -79,8 +79,9 @@ class CensusMccnnSgm(
|
|
|
79
79
|
"census_sgm_homogeneous",
|
|
80
80
|
"mccnn_sgm",
|
|
81
81
|
"auto",
|
|
82
|
+
"custom",
|
|
82
83
|
],
|
|
83
|
-
): # pylint: disable=R0903,disable=R0902
|
|
84
|
+
): # pylint: disable=R0903,disable=R0902,disable=C0302
|
|
84
85
|
"""
|
|
85
86
|
Census SGM & MCCNN SGM matching class
|
|
86
87
|
"""
|
|
@@ -169,7 +170,6 @@ class CensusMccnnSgm(
|
|
|
169
170
|
:rtype: dict
|
|
170
171
|
|
|
171
172
|
"""
|
|
172
|
-
|
|
173
173
|
# init conf
|
|
174
174
|
if conf is not None:
|
|
175
175
|
overloaded_conf = conf.copy()
|
|
@@ -178,9 +178,21 @@ class CensusMccnnSgm(
|
|
|
178
178
|
overloaded_conf = {}
|
|
179
179
|
|
|
180
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")
|
|
181
187
|
overloaded_conf["method"] = conf.get(
|
|
182
|
-
"method",
|
|
188
|
+
"method", default_method
|
|
183
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
|
+
|
|
184
196
|
# method called in abstract_dense_matching_app.py
|
|
185
197
|
overloaded_conf["min_epi_tile_size"] = conf.get(
|
|
186
198
|
"min_epi_tile_size", 300
|
|
@@ -279,10 +291,6 @@ class CensusMccnnSgm(
|
|
|
279
291
|
|
|
280
292
|
overloaded_conf["performance_map_method"] = perf_map_method
|
|
281
293
|
|
|
282
|
-
# check loader
|
|
283
|
-
loader_conf = conf.get("loader_conf", None)
|
|
284
|
-
loader = conf.get("loader", "pandora")
|
|
285
|
-
|
|
286
294
|
if overloaded_conf["use_cross_validation"] is True:
|
|
287
295
|
overloaded_conf["use_cross_validation"] = "fast"
|
|
288
296
|
|
|
@@ -312,13 +320,20 @@ class CensusMccnnSgm(
|
|
|
312
320
|
# Get params from loader
|
|
313
321
|
self.loader = pandora_loader
|
|
314
322
|
self.corr_config = collections.OrderedDict(pandora_loader.get_conf())
|
|
315
|
-
|
|
316
323
|
# Instantiate margins from pandora check conf
|
|
317
324
|
# create the dataset
|
|
325
|
+
classif_bands = pandora_loader.get_classif_bands()
|
|
318
326
|
fake_dataset = xr.Dataset(
|
|
319
|
-
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
|
+
},
|
|
320
334
|
coords={
|
|
321
335
|
"band_im": [overloaded_conf["used_band"]],
|
|
336
|
+
"band_classif": classif_bands,
|
|
322
337
|
"row": np.arange(10),
|
|
323
338
|
"col": np.arange(10),
|
|
324
339
|
},
|
|
@@ -328,7 +343,6 @@ class CensusMccnnSgm(
|
|
|
328
343
|
pandora.import_plugin()
|
|
329
344
|
pandora_machine = PandoraMachine()
|
|
330
345
|
corr_config_pipeline = {"pipeline": dict(self.corr_config["pipeline"])}
|
|
331
|
-
|
|
332
346
|
saved_schema = copy.deepcopy(
|
|
333
347
|
pandora.matching_cost.matching_cost.AbstractMatchingCost.schema
|
|
334
348
|
)
|
|
@@ -341,7 +355,11 @@ class CensusMccnnSgm(
|
|
|
341
355
|
)
|
|
342
356
|
self.margins = pandora_machine.margins.global_margins
|
|
343
357
|
|
|
344
|
-
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
|
|
345
363
|
|
|
346
364
|
application_schema = {
|
|
347
365
|
"method": str,
|
|
@@ -418,7 +436,6 @@ class CensusMccnnSgm(
|
|
|
418
436
|
"Maximal disparity should be bigger than "
|
|
419
437
|
"minimal disparity for dense matching"
|
|
420
438
|
)
|
|
421
|
-
|
|
422
439
|
return overloaded_conf
|
|
423
440
|
|
|
424
441
|
def check_conf_confidence_filtering(self, overloaded_conf):
|
|
@@ -472,6 +489,7 @@ class CensusMccnnSgm(
|
|
|
472
489
|
overloaded_conf["confidence_filtering"]
|
|
473
490
|
)
|
|
474
491
|
|
|
492
|
+
@cars_profile(name="Get margin fun")
|
|
475
493
|
def get_margins_fun(self, grid_left, disp_range_grid):
|
|
476
494
|
"""
|
|
477
495
|
Get Margins function that generates margins needed by
|
|
@@ -714,6 +732,7 @@ class CensusMccnnSgm(
|
|
|
714
732
|
required_bands["right"] = self.required_bands
|
|
715
733
|
return required_bands
|
|
716
734
|
|
|
735
|
+
# pylint: disable=too-many-positional-arguments
|
|
717
736
|
@cars_profile(name="Disp Grid Generation")
|
|
718
737
|
def generate_disparity_grids( # noqa: C901
|
|
719
738
|
self,
|
|
@@ -722,8 +741,6 @@ class CensusMccnnSgm(
|
|
|
722
741
|
geom_plugin_with_dem_and_geoid,
|
|
723
742
|
dmin=None,
|
|
724
743
|
dmax=None,
|
|
725
|
-
altitude_delta_min=None,
|
|
726
|
-
altitude_delta_max=None,
|
|
727
744
|
dem_median=None,
|
|
728
745
|
dem_min=None,
|
|
729
746
|
dem_max=None,
|
|
@@ -748,10 +765,6 @@ class CensusMccnnSgm(
|
|
|
748
765
|
:type dmin: float
|
|
749
766
|
:param dmax: maximum disparity
|
|
750
767
|
:type dmax: float
|
|
751
|
-
:param altitude_delta_max: Delta max of altitude
|
|
752
|
-
:type altitude_delta_max: int
|
|
753
|
-
:param altitude_delta_min: Delta min of altitude
|
|
754
|
-
:type altitude_delta_min: int
|
|
755
768
|
:param dem_median: path to median dem
|
|
756
769
|
:type dem_median: str
|
|
757
770
|
:param dem_min: path to minimum dem
|
|
@@ -821,19 +834,13 @@ class CensusMccnnSgm(
|
|
|
821
834
|
|
|
822
835
|
if None not in (dmin, dmax):
|
|
823
836
|
# use global disparity range
|
|
824
|
-
if None not in (dem_min, dem_max)
|
|
825
|
-
altitude_delta_min,
|
|
826
|
-
altitude_delta_max,
|
|
827
|
-
):
|
|
837
|
+
if None not in (dem_min, dem_max):
|
|
828
838
|
raise RuntimeError("Mix between local and global mode")
|
|
829
839
|
|
|
830
840
|
# Only one tile
|
|
831
841
|
grid_disp_range.tiling_grid = np.array([[[0, nb_rows, 0, nb_cols]]])
|
|
832
842
|
|
|
833
|
-
elif None not in (dem_min, dem_max, dem_median)
|
|
834
|
-
altitude_delta_min,
|
|
835
|
-
altitude_delta_max,
|
|
836
|
-
):
|
|
843
|
+
elif None not in (dem_min, dem_max, dem_median):
|
|
837
844
|
|
|
838
845
|
# Generate multiple tiles
|
|
839
846
|
grid_tile_size = self.epi_disp_grid_tile_size
|
|
@@ -891,10 +898,7 @@ class CensusMccnnSgm(
|
|
|
891
898
|
|
|
892
899
|
if None not in (dmin, dmax):
|
|
893
900
|
# use global disparity range
|
|
894
|
-
if None not in (dem_min, dem_max)
|
|
895
|
-
altitude_delta_min,
|
|
896
|
-
altitude_delta_max,
|
|
897
|
-
):
|
|
901
|
+
if None not in (dem_min, dem_max):
|
|
898
902
|
raise RuntimeError("Mix between local and global mode")
|
|
899
903
|
|
|
900
904
|
saving_info_global_infos_full = ocht.update_saving_infos(
|
|
@@ -919,10 +923,7 @@ class CensusMccnnSgm(
|
|
|
919
923
|
saving_info_global_infos_full,
|
|
920
924
|
)
|
|
921
925
|
|
|
922
|
-
elif None not in (dem_min, dem_max, dem_median)
|
|
923
|
-
altitude_delta_min,
|
|
924
|
-
altitude_delta_max,
|
|
925
|
-
):
|
|
926
|
+
elif None not in (dem_min, dem_max, dem_median):
|
|
926
927
|
|
|
927
928
|
# use filter to propagate min and max
|
|
928
929
|
filter_overlap = (
|
|
@@ -959,8 +960,6 @@ class CensusMccnnSgm(
|
|
|
959
960
|
dem_median,
|
|
960
961
|
dem_min,
|
|
961
962
|
dem_max,
|
|
962
|
-
altitude_delta_min,
|
|
963
|
-
altitude_delta_max,
|
|
964
963
|
raster_profile,
|
|
965
964
|
full_saving_info,
|
|
966
965
|
saving_info_global_infos_full,
|
|
@@ -991,7 +990,7 @@ class CensusMccnnSgm(
|
|
|
991
990
|
|
|
992
991
|
return grid_disp_range_dict
|
|
993
992
|
|
|
994
|
-
def run(
|
|
993
|
+
def run( # pylint: disable=too-many-positional-arguments
|
|
995
994
|
self,
|
|
996
995
|
epipolar_images_left,
|
|
997
996
|
epipolar_images_right,
|
|
@@ -1064,7 +1063,6 @@ class CensusMccnnSgm(
|
|
|
1064
1063
|
|
|
1065
1064
|
:rtype: CarsDataset
|
|
1066
1065
|
"""
|
|
1067
|
-
|
|
1068
1066
|
# Default orchestrator
|
|
1069
1067
|
if orchestrator is None:
|
|
1070
1068
|
# Create default sequential orchestrator for current application
|
|
@@ -1210,6 +1208,7 @@ class CensusMccnnSgm(
|
|
|
1210
1208
|
for col in range(epipolar_disparity_map.shape[1]):
|
|
1211
1209
|
for row in range(epipolar_disparity_map.shape[0]):
|
|
1212
1210
|
use_tile = False
|
|
1211
|
+
crop_with_range = None
|
|
1213
1212
|
if type(None) not in (
|
|
1214
1213
|
type(epipolar_images_left[row, col]),
|
|
1215
1214
|
type(epipolar_images_right[row, col]),
|
|
@@ -1276,7 +1275,7 @@ class CensusMccnnSgm(
|
|
|
1276
1275
|
return epipolar_disparity_map
|
|
1277
1276
|
|
|
1278
1277
|
|
|
1279
|
-
def compute_disparity_wrapper(
|
|
1278
|
+
def compute_disparity_wrapper( # pylint: disable=too-many-positional-arguments
|
|
1280
1279
|
left_image_object: xr.Dataset,
|
|
1281
1280
|
right_image_object: xr.Dataset,
|
|
1282
1281
|
corr_cfg: dict,
|
|
Binary file
|
|
Binary file
|