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.

Files changed (144) hide show
  1. cars/__init__.py +3 -3
  2. cars/applications/__init__.py +0 -3
  3. cars/applications/application.py +14 -6
  4. cars/applications/application_template.py +42 -0
  5. cars/applications/auxiliary_filling/abstract_auxiliary_filling_app.py +12 -2
  6. cars/applications/auxiliary_filling/auxiliary_filling_algo.py +2 -2
  7. cars/applications/auxiliary_filling/auxiliary_filling_from_sensors_app.py +95 -46
  8. cars/applications/auxiliary_filling/auxiliary_filling_wrappers.py +7 -6
  9. cars/applications/dem_generation/abstract_dem_generation_app.py +9 -5
  10. cars/applications/dem_generation/dem_generation_algo.py +1 -1
  11. cars/applications/dem_generation/dem_generation_wrappers.py +44 -59
  12. cars/applications/dem_generation/dichotomic_generation_app.py +9 -6
  13. cars/applications/dem_generation/rasterization_app.py +112 -43
  14. cars/applications/dense_match_filling/__init__.py +1 -1
  15. cars/applications/dense_match_filling/abstract_dense_match_filling_app.py +2 -15
  16. cars/applications/dense_match_filling/fill_disp_algo.py +32 -373
  17. cars/applications/dense_match_filling/fill_disp_wrappers.py +0 -343
  18. cars/applications/dense_match_filling/zero_padding_app.py +10 -5
  19. cars/applications/dense_matching/abstract_dense_matching_app.py +2 -1
  20. cars/applications/dense_matching/census_mccnn_sgm_app.py +48 -60
  21. cars/applications/dense_matching/cpp/dense_matching_cpp.cp310-win_amd64.dll.a +0 -0
  22. cars/applications/dense_matching/cpp/dense_matching_cpp.cp310-win_amd64.pyd +0 -0
  23. cars/applications/dense_matching/dense_matching_algo.py +48 -14
  24. cars/applications/dense_matching/dense_matching_wrappers.py +11 -3
  25. cars/applications/dense_matching/disparity_grid_algo.py +95 -79
  26. cars/applications/dense_matching/loaders/config_mapping.json +13 -0
  27. cars/applications/dense_matching/loaders/global_land_cover_map.tif +0 -0
  28. cars/applications/dense_matching/loaders/pandora_loader.py +169 -34
  29. cars/applications/dsm_filling/border_interpolation_app.py +11 -12
  30. cars/applications/dsm_filling/bulldozer_filling_app.py +16 -15
  31. cars/applications/dsm_filling/exogenous_filling_app.py +14 -14
  32. cars/applications/grid_generation/abstract_grid_generation_app.py +1 -1
  33. cars/applications/grid_generation/epipolar_grid_generation_app.py +4 -2
  34. cars/applications/grid_generation/grid_correction_app.py +4 -1
  35. cars/applications/grid_generation/grid_generation_algo.py +7 -2
  36. cars/applications/ground_truth_reprojection/abstract_ground_truth_reprojection_app.py +1 -1
  37. cars/applications/ground_truth_reprojection/direct_localization_app.py +2 -2
  38. cars/applications/ground_truth_reprojection/ground_truth_reprojection_algo.py +2 -1
  39. cars/applications/point_cloud_fusion/abstract_pc_fusion_app.py +0 -155
  40. cars/applications/point_cloud_fusion/mapping_to_terrain_tiles_app.py +0 -658
  41. cars/applications/point_cloud_fusion/pc_fusion_algo.py +0 -1339
  42. cars/applications/point_cloud_fusion/pc_fusion_wrappers.py +0 -869
  43. cars/applications/point_cloud_outlier_removal/abstract_outlier_removal_app.py +11 -6
  44. cars/applications/point_cloud_outlier_removal/outlier_removal_algo.py +9 -8
  45. cars/applications/point_cloud_outlier_removal/small_components_app.py +101 -270
  46. cars/applications/point_cloud_outlier_removal/statistical_app.py +120 -277
  47. cars/applications/rasterization/abstract_pc_rasterization_app.py +2 -1
  48. cars/applications/rasterization/rasterization_algo.py +18 -6
  49. cars/applications/rasterization/rasterization_wrappers.py +2 -1
  50. cars/applications/rasterization/simple_gaussian_app.py +88 -116
  51. cars/applications/resampling/abstract_resampling_app.py +1 -1
  52. cars/applications/resampling/bicubic_resampling_app.py +3 -1
  53. cars/applications/resampling/resampling_algo.py +60 -53
  54. cars/applications/resampling/resampling_wrappers.py +3 -1
  55. cars/applications/sparse_matching/abstract_sparse_matching_app.py +1 -1
  56. cars/applications/sparse_matching/sift_app.py +5 -25
  57. cars/applications/sparse_matching/sparse_matching_algo.py +3 -2
  58. cars/applications/sparse_matching/sparse_matching_wrappers.py +1 -1
  59. cars/applications/triangulation/abstract_triangulation_app.py +1 -1
  60. cars/applications/triangulation/line_of_sight_intersection_app.py +13 -11
  61. cars/applications/triangulation/pc_transform.py +552 -0
  62. cars/applications/triangulation/triangulation_algo.py +6 -4
  63. cars/applications/triangulation/triangulation_wrappers.py +1 -0
  64. cars/bundleadjustment.py +6 -6
  65. cars/cars.py +11 -9
  66. cars/core/cars_logging.py +80 -49
  67. cars/core/constants.py +0 -1
  68. cars/core/datasets.py +5 -2
  69. cars/core/geometry/abstract_geometry.py +364 -22
  70. cars/core/geometry/shareloc_geometry.py +112 -82
  71. cars/core/inputs.py +72 -19
  72. cars/core/outputs.py +1 -1
  73. cars/core/preprocessing.py +17 -3
  74. cars/core/projection.py +126 -6
  75. cars/core/tiling.py +10 -3
  76. cars/data_structures/cars_dataset.py +12 -10
  77. cars/data_structures/corresponding_tiles_tools.py +0 -103
  78. cars/data_structures/format_transformation.py +4 -1
  79. cars/devibrate.py +6 -3
  80. cars/extractroi.py +20 -21
  81. cars/orchestrator/cluster/abstract_cluster.py +15 -5
  82. cars/orchestrator/cluster/abstract_dask_cluster.py +6 -2
  83. cars/orchestrator/cluster/dask_jobqueue_utils.py +1 -1
  84. cars/orchestrator/cluster/log_wrapper.py +149 -22
  85. cars/orchestrator/cluster/mp_cluster/multiprocessing_cluster.py +12 -4
  86. cars/orchestrator/cluster/mp_cluster/multiprocessing_profiler.py +2 -2
  87. cars/orchestrator/cluster/pbs_dask_cluster.py +1 -1
  88. cars/orchestrator/cluster/sequential_cluster.py +5 -4
  89. cars/orchestrator/cluster/slurm_dask_cluster.py +1 -1
  90. cars/orchestrator/orchestrator.py +15 -4
  91. cars/orchestrator/registry/id_generator.py +1 -0
  92. cars/orchestrator/registry/saver_registry.py +2 -2
  93. cars/pipelines/conf_resolution/conf_final_resolution.json +5 -3
  94. cars/pipelines/default/default_pipeline.py +461 -1052
  95. cars/pipelines/parameters/advanced_parameters.py +91 -64
  96. cars/pipelines/parameters/advanced_parameters_constants.py +6 -5
  97. cars/pipelines/parameters/application_parameters.py +71 -0
  98. cars/pipelines/parameters/depth_map_inputs.py +0 -314
  99. cars/pipelines/parameters/dsm_inputs.py +40 -4
  100. cars/pipelines/parameters/output_parameters.py +44 -8
  101. cars/pipelines/parameters/sensor_inputs.py +122 -73
  102. cars/pipelines/parameters/sensor_inputs_constants.py +0 -2
  103. cars/pipelines/parameters/sensor_loaders/__init__.py +4 -3
  104. cars/pipelines/parameters/sensor_loaders/basic_classif_loader.py +106 -0
  105. cars/pipelines/parameters/sensor_loaders/{basic_sensor_loader.py → basic_image_loader.py} +16 -22
  106. cars/pipelines/parameters/sensor_loaders/pivot_classif_loader.py +121 -0
  107. cars/pipelines/parameters/sensor_loaders/{pivot_sensor_loader.py → pivot_image_loader.py} +10 -21
  108. cars/pipelines/parameters/sensor_loaders/sensor_loader.py +4 -6
  109. cars/pipelines/parameters/sensor_loaders/sensor_loader_template.py +1 -3
  110. cars/pipelines/pipeline_template.py +1 -3
  111. cars/pipelines/unit/unit_pipeline.py +676 -1070
  112. cars/starter.py +4 -3
  113. cars-1.0.0a4.dist-info/DELVEWHEEL +2 -0
  114. {cars-1.0.0a2.dist-info → cars-1.0.0a4.dist-info}/METADATA +135 -53
  115. {cars-1.0.0a2.dist-info → cars-1.0.0a4.dist-info}/RECORD +120 -134
  116. cars.libs/libgcc_s_seh-1-b2494fcbd4d80cf2c98fdd5261f6d850.dll +0 -0
  117. cars.libs/libstdc++-6-e9b0d12ae0e9555bbae55e8dfd08c3f7.dll +0 -0
  118. cars.libs/libwinpthread-1-7882d1b093714ccdfaf4e0789a817792.dll +0 -0
  119. cars/applications/dense_match_filling/cpp/__init__.py +0 -0
  120. cars/applications/dense_match_filling/cpp/dense_match_filling_cpp.cp310-win_amd64.dll.a +0 -0
  121. cars/applications/dense_match_filling/cpp/dense_match_filling_cpp.cp310-win_amd64.pyd +0 -0
  122. cars/applications/dense_match_filling/cpp/dense_match_filling_cpp.py +0 -72
  123. cars/applications/dense_match_filling/cpp/includes/dense_match_filling.hpp +0 -46
  124. cars/applications/dense_match_filling/cpp/meson.build +0 -9
  125. cars/applications/dense_match_filling/cpp/src/bindings.cpp +0 -11
  126. cars/applications/dense_match_filling/cpp/src/dense_match_filling.cpp +0 -142
  127. cars/applications/dense_match_filling/plane_app.py +0 -556
  128. cars/applications/hole_detection/__init__.py +0 -30
  129. cars/applications/hole_detection/abstract_hole_detection_app.py +0 -125
  130. cars/applications/hole_detection/cloud_to_bbox_app.py +0 -346
  131. cars/applications/hole_detection/hole_detection_algo.py +0 -144
  132. cars/applications/hole_detection/hole_detection_wrappers.py +0 -53
  133. cars/applications/point_cloud_denoising/__init__.py +0 -29
  134. cars/applications/point_cloud_denoising/abstract_pc_denoising_app.py +0 -273
  135. cars/applications/point_cloud_fusion/__init__.py +0 -30
  136. cars/applications/point_cloud_fusion/cloud_fusion_constants.py +0 -39
  137. cars/applications/sparse_matching/pandora_sparse_matching_app.py +0 -0
  138. cars/pipelines/parameters/depth_map_inputs_constants.py +0 -25
  139. cars-1.0.0a2.dist-info/DELVEWHEEL +0 -2
  140. cars.libs/libgcc_s_seh-1-f2b6825d483bdf14050493af93b5997d.dll +0 -0
  141. cars.libs/libstdc++-6-6b0059df6bc601df5a0f18a5805eea05.dll +0 -0
  142. cars.libs/libwinpthread-1-e01b8e85fd67c2b861f64d4ccc7df607.dll +0 -0
  143. {cars-1.0.0a2.dist-info → cars-1.0.0a4.dist-info}/WHEEL +0 -0
  144. {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
- classif_index=self.classification,
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
- classif_index,
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 class_index: class index according to the classification tag
270
- :type class_index: list
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, classif_index, fill_valid_pixels)
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", "census_sgm_default"
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["loader_conf"] = self.corr_config
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
- geotransform = (
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) or None not in (
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) or None not in (
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) or None not in (
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) or None not in (
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,