cars 1.0.0a2__cp39-cp39-win_amd64.whl → 1.0.0a3__cp39-cp39-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 (56) hide show
  1. cars/__init__.py +2 -2
  2. cars/applications/application.py +14 -6
  3. cars/applications/application_template.py +22 -0
  4. cars/applications/auxiliary_filling/auxiliary_filling_from_sensors_app.py +15 -10
  5. cars/applications/auxiliary_filling/auxiliary_filling_wrappers.py +7 -6
  6. cars/applications/dem_generation/abstract_dem_generation_app.py +9 -5
  7. cars/applications/dem_generation/dem_generation_wrappers.py +46 -27
  8. cars/applications/dem_generation/dichotomic_generation_app.py +6 -3
  9. cars/applications/dem_generation/rasterization_app.py +15 -5
  10. cars/applications/dense_match_filling/cpp/dense_match_filling_cpp.cp39-win_amd64.dll.a +0 -0
  11. cars/applications/dense_match_filling/cpp/dense_match_filling_cpp.cp39-win_amd64.pyd +0 -0
  12. cars/applications/dense_matching/census_mccnn_sgm_app.py +11 -22
  13. cars/applications/dense_matching/cpp/dense_matching_cpp.cp39-win_amd64.dll.a +0 -0
  14. cars/applications/dense_matching/cpp/dense_matching_cpp.cp39-win_amd64.pyd +0 -0
  15. cars/applications/dense_matching/disparity_grid_algo.py +26 -32
  16. cars/applications/dense_matching/loaders/config_mapping.json +13 -0
  17. cars/applications/dense_matching/loaders/global_land_cover_map.tif +0 -0
  18. cars/applications/dense_matching/loaders/pandora_loader.py +78 -1
  19. cars/applications/dsm_filling/border_interpolation_app.py +10 -5
  20. cars/applications/dsm_filling/bulldozer_filling_app.py +14 -7
  21. cars/applications/dsm_filling/exogenous_filling_app.py +10 -5
  22. cars/applications/point_cloud_outlier_removal/abstract_outlier_removal_app.py +9 -5
  23. cars/applications/point_cloud_outlier_removal/small_components_app.py +5 -3
  24. cars/applications/point_cloud_outlier_removal/statistical_app.py +4 -2
  25. cars/applications/rasterization/abstract_pc_rasterization_app.py +1 -0
  26. cars/applications/rasterization/simple_gaussian_app.py +28 -3
  27. cars/applications/resampling/resampling_algo.py +44 -49
  28. cars/applications/sparse_matching/sift_app.py +2 -22
  29. cars/core/geometry/abstract_geometry.py +113 -2
  30. cars/core/geometry/shareloc_geometry.py +2 -0
  31. cars/core/inputs.py +15 -0
  32. cars/core/projection.py +117 -0
  33. cars/data_structures/cars_dataset.py +7 -5
  34. cars/orchestrator/cluster/log_wrapper.py +1 -1
  35. cars/orchestrator/cluster/mp_cluster/multiprocessing_cluster.py +1 -1
  36. cars/orchestrator/orchestrator.py +1 -1
  37. cars/pipelines/default/default_pipeline.py +46 -26
  38. cars/pipelines/parameters/advanced_parameters.py +17 -0
  39. cars/pipelines/parameters/advanced_parameters_constants.py +4 -0
  40. cars/pipelines/parameters/output_parameters.py +44 -8
  41. cars/pipelines/parameters/sensor_inputs.py +97 -3
  42. cars/pipelines/unit/unit_pipeline.py +194 -99
  43. cars-1.0.0a3.dist-info/DELVEWHEEL +2 -0
  44. {cars-1.0.0a2.dist-info → cars-1.0.0a3.dist-info}/METADATA +1 -1
  45. {cars-1.0.0a2.dist-info → cars-1.0.0a3.dist-info}/RECORD +51 -49
  46. cars.libs/.load-order-cars-1.0.0a3 +3 -0
  47. cars.libs/libgcc_s_seh-1-ca70890bbc5723b6d0ea31e9c9cded2b.dll +0 -0
  48. cars.libs/libstdc++-6-00ee19f73d5122a1277c137b1c218401.dll +0 -0
  49. cars.libs/libwinpthread-1-f5042e8e3d21edce20c1bc99445f551b.dll +0 -0
  50. cars-1.0.0a2.dist-info/DELVEWHEEL +0 -2
  51. cars.libs/.load-order-cars-1.0.0a2 +0 -3
  52. cars.libs/libgcc_s_seh-1-f2b6825d483bdf14050493af93b5997d.dll +0 -0
  53. cars.libs/libstdc++-6-6b0059df6bc601df5a0f18a5805eea05.dll +0 -0
  54. cars.libs/libwinpthread-1-e01b8e85fd67c2b861f64d4ccc7df607.dll +0 -0
  55. {cars-1.0.0a2.dist-info → cars-1.0.0a3.dist-info}/WHEEL +0 -0
  56. {cars-1.0.0a2.dist-info → cars-1.0.0a3.dist-info}/entry_points.txt +0 -0
cars/__init__.py CHANGED
@@ -35,10 +35,10 @@ def _delvewheel_patch_1_11_1():
35
35
  if os.path.isdir(libs_dir):
36
36
  os.add_dll_directory(libs_dir)
37
37
  else:
38
- load_order_filepath = os.path.join(libs_dir, '.load-order-cars-1.0.0a2')
38
+ load_order_filepath = os.path.join(libs_dir, '.load-order-cars-1.0.0a3')
39
39
  if os.path.isfile(load_order_filepath):
40
40
  import ctypes.wintypes
41
- with open(os.path.join(libs_dir, '.load-order-cars-1.0.0a2')) as file:
41
+ with open(os.path.join(libs_dir, '.load-order-cars-1.0.0a3')) as file:
42
42
  load_order = file.read().split()
43
43
  kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)
44
44
  kernel32.LoadLibraryExW.restype = ctypes.wintypes.HMODULE
@@ -26,6 +26,8 @@ This module contains class application factory.
26
26
  # Standard imports
27
27
  import logging
28
28
 
29
+ from cars.applications.application_template import ScalingApplicationTemplate
30
+
29
31
  # CARS imports
30
32
  from cars.conf.input_parameters import ConfigType
31
33
 
@@ -46,6 +48,7 @@ class Application:
46
48
  cls,
47
49
  app_name: str,
48
50
  cfg: ConfigType = None,
51
+ scaling_coeff: float = 1,
49
52
  ):
50
53
  """
51
54
  Return the instance of application associated with the application
@@ -55,12 +58,14 @@ class Application:
55
58
  :type app_name: str
56
59
  :param cfg: configuration {'matching_cost_method': value}
57
60
  :type cfg: dictionary
61
+ :param scaling_coeff: scaling factor for resolution
62
+ :type scaling_coeff: float
58
63
  """
59
64
 
60
- return cls.create_app(app_name, cfg)
65
+ return cls.create_app(app_name, cfg, scaling_coeff)
61
66
 
62
67
  @classmethod
63
- def create_app(cls, name: str, cfg: ConfigType):
68
+ def create_app(cls, name: str, cfg: ConfigType, scaling_coeff: float = 1):
64
69
  """Factory command to create the application
65
70
  Return the instance of application associated with the application
66
71
  name given as parameter
@@ -69,16 +74,19 @@ class Application:
69
74
  :type app_name: str
70
75
  :param cfg: configuration {'matching_cost_method': value}
71
76
  :type cfg: dictionary
77
+ :param scaling_coeff: scaling factor for resolution
78
+ :type scaling_coeff: float
72
79
  """
73
- app = None
74
-
75
80
  try:
76
81
  app_class = cls.available_applications[name]
77
82
  except KeyError:
78
83
  logging.error("No application named {0} supported".format(name))
79
84
  return None
80
- app = app_class(conf=cfg)
81
- return app
85
+
86
+ if issubclass(app_class, ScalingApplicationTemplate):
87
+ return app_class(scaling_coeff=scaling_coeff, conf=cfg)
88
+
89
+ return app_class(conf=cfg)
82
90
 
83
91
  @classmethod
84
92
  def print_applications(cls):
@@ -102,3 +102,25 @@ class ApplicationTemplate(metaclass=ABCMeta):
102
102
  """
103
103
 
104
104
  return self.used_config
105
+
106
+
107
+ class ScalingApplicationTemplate(ApplicationTemplate, metaclass=ABCMeta):
108
+ """
109
+ Template for applications requiring resolution scaling.
110
+
111
+ Inherits from ApplicationTemplate and adds the scaling coefficient
112
+ as a required argument.
113
+ """
114
+
115
+ def __init__(self, scaling_coeff, conf=None):
116
+ """
117
+ Init function of ScalingApplicationTemplate
118
+
119
+ :param scaling_coeff: scaling factor for resolution
120
+ :type scaling_coeff: float
121
+
122
+ :param conf: configuration for application
123
+ :type conf: dict
124
+ """
125
+ self.scaling_coeff = scaling_coeff
126
+ super().__init__(conf=conf)
@@ -30,6 +30,7 @@ import numpy as np
30
30
  import rasterio as rio
31
31
  import xarray as xr
32
32
  from json_checker import Checker
33
+ from pyproj import CRS
33
34
  from shapely.geometry import Polygon
34
35
 
35
36
  import cars.orchestrator.orchestrator as ocht
@@ -191,12 +192,15 @@ class AuxiliaryFillingFromSensors(
191
192
  shutil.move(color_file, color_not_filled_file)
192
193
 
193
194
  classification_not_filled_file = None
195
+ # classif_file could be defined without data attached
196
+ if classif_file is not None and not os.path.exists(classif_file):
197
+ classif_file = None
198
+
194
199
  if classif_file is not None:
195
200
  classification_not_filled_file = os.path.join(
196
201
  dump_dir, "classification_not_filled.tif"
197
202
  )
198
- if os.path.exists(classif_file):
199
- shutil.move(classif_file, classification_not_filled_file)
203
+ shutil.move(classif_file, classification_not_filled_file)
200
204
 
201
205
  # Clean dump_dir at the end of processing if required
202
206
  if not self.used_config["save_intermediate_data"]:
@@ -264,12 +268,12 @@ class AuxiliaryFillingFromSensors(
264
268
  [saving_info] = self.orchestrator.get_saving_infos([aux_filled_image])
265
269
 
266
270
  reference_transform = inputs.rasterio_get_transform(dsm_file)
267
- reference_epsg = inputs.rasterio_get_epsg(dsm_file)
271
+ reference_crs = inputs.rasterio_get_crs(dsm_file)
268
272
 
269
273
  # Pre-compute sensor bounds of all sensors to filter sensors that do
270
274
  # not intersect with tile in tasks
271
275
  sensor_bounds = auxiliary_filling_wrappers.compute_sensor_bounds(
272
- sensor_inputs, geom_plugin, reference_epsg
276
+ sensor_inputs, geom_plugin, reference_crs
273
277
  )
274
278
 
275
279
  for row in range(aux_filled_image.shape[0]):
@@ -296,7 +300,7 @@ class AuxiliaryFillingFromSensors(
296
300
  pairing,
297
301
  window,
298
302
  reference_transform,
299
- reference_epsg,
303
+ reference_crs,
300
304
  full_saving_info,
301
305
  geom_plugin,
302
306
  texture_bands,
@@ -324,7 +328,7 @@ def filling_from_sensor_wrapper(
324
328
  pairing,
325
329
  window,
326
330
  transform,
327
- epsg,
331
+ crs,
328
332
  saving_info,
329
333
  geom_plugin,
330
334
  texture_bands,
@@ -351,8 +355,8 @@ def filling_from_sensor_wrapper(
351
355
  :type window: dict
352
356
  :param transform: input geo transform
353
357
  :type transform: tuple
354
- :param epsg: input epsg
355
- :type epsg: int
358
+ :param crs: input crs
359
+ :type crs: CRS
356
360
  :param saving_info: saving info for cars orchestrator
357
361
  :type saving_info: dict
358
362
  :param geom_plugin: geometry plugin used for inverse locations
@@ -399,8 +403,8 @@ def filling_from_sensor_wrapper(
399
403
 
400
404
  stacked_values = np.vstack([cols_values_2d.ravel(), rows_values_2d.ravel()])
401
405
 
402
- lon_lat = projection.point_cloud_conversion(
403
- stacked_values.transpose(), epsg, 4326
406
+ lon_lat = projection.point_cloud_conversion_crs(
407
+ stacked_values.transpose(), crs, CRS(4326)
404
408
  )
405
409
 
406
410
  rio_window = rio.windows.Window.from_slices(
@@ -458,6 +462,7 @@ def filling_from_sensor_wrapper(
458
462
  number_of_classification_bands = 0
459
463
  classification_values = None
460
464
  classification_band_names = None
465
+
461
466
  if classification_file is not None:
462
467
  if os.path.exists(classification_file):
463
468
  with rio.open(classification_file) as classification_image:
@@ -22,12 +22,13 @@
22
22
  this module contains the AuxiliaryFillingFromSensors application class.
23
23
  """
24
24
 
25
+ from pyproj import CRS
25
26
  from shapely.geometry import Polygon
26
27
 
27
- from cars.core.projection import polygon_projection
28
+ from cars.core.projection import polygon_projection_crs
28
29
 
29
30
 
30
- def compute_sensor_bounds(sensor_inputs, geom_plugin, output_epsg):
31
+ def compute_sensor_bounds(sensor_inputs, geom_plugin, output_crs):
31
32
  """
32
33
  Compute bounds of each input sensor that have an associated color or
33
34
  classification image
@@ -38,8 +39,8 @@ def compute_sensor_bounds(sensor_inputs, geom_plugin, output_epsg):
38
39
  :type geom_plugin: AbstractGeometry
39
40
  :param geom_plugin: geometry plugin used for inverse locations
40
41
  :type geom_plugin: AbstractGeometry
41
- :param output_epsg: epsg of the output polygons
42
- :type output_epsg: int
42
+ :param output_crs: crs of the output polygons
43
+ :type output_crs: CRS
43
44
 
44
45
  :return: a dictionary containing a Polygon in output geometry for each
45
46
  valid input sensor
@@ -59,8 +60,8 @@ def compute_sensor_bounds(sensor_inputs, geom_plugin, output_epsg):
59
60
 
60
61
  poly_geo = Polygon([u_l, u_r, l_r, l_l, u_l])
61
62
 
62
- sensor_bounds[sensor_name] = polygon_projection(
63
- poly_geo, 4326, output_epsg
63
+ sensor_bounds[sensor_name] = polygon_projection_crs(
64
+ poly_geo, CRS(4326), output_crs
64
65
  )
65
66
 
66
67
  return sensor_bounds
@@ -26,11 +26,11 @@ from abc import ABCMeta, abstractmethod
26
26
  from typing import Dict
27
27
 
28
28
  from cars.applications.application import Application
29
- from cars.applications.application_template import ApplicationTemplate
29
+ from cars.applications.application_template import ScalingApplicationTemplate
30
30
 
31
31
 
32
32
  @Application.register("dem_generation")
33
- class DemGeneration(ApplicationTemplate, metaclass=ABCMeta):
33
+ class DemGeneration(ScalingApplicationTemplate, metaclass=ABCMeta):
34
34
  """
35
35
  DemGeneration
36
36
  """
@@ -38,13 +38,15 @@ class DemGeneration(ApplicationTemplate, metaclass=ABCMeta):
38
38
  available_applications: Dict = {}
39
39
  default_application = "bulldozer_on_raster"
40
40
 
41
- def __new__(cls, conf=None): # pylint: disable=W0613
41
+ def __new__(cls, scaling_coeff, conf=None): # pylint: disable=W0613
42
42
  """
43
43
  Return the required application
44
44
  :raises:
45
45
  - KeyError when the required application is not registered
46
46
 
47
47
  :param orchestrator: orchestrator used
48
+ :param scaling_coeff: scaling factor for resolution
49
+ :type scaling_coeff: float
48
50
  :param conf: configuration for resampling
49
51
  :return: an application_to_use object
50
52
  """
@@ -84,15 +86,17 @@ class DemGeneration(ApplicationTemplate, metaclass=ABCMeta):
84
86
  super().__init_subclass__(**kwargs)
85
87
  cls.available_applications[short_name] = cls
86
88
 
87
- def __init__(self, conf=None):
89
+ def __init__(self, scaling_coeff, conf=None):
88
90
  """
89
91
  Init function of MntGeneration
90
92
 
93
+ :param scaling_coeff: scaling factor for resolution
94
+ :type scaling_coeff: float
91
95
  :param conf: configuration
92
96
  :return: an application_to_use object
93
97
  """
94
98
 
95
- super().__init__(conf=conf)
99
+ super().__init__(scaling_coeff, conf=conf)
96
100
 
97
101
  @abstractmethod
98
102
  def run(self, triangulated_matches_list, output_dir):
@@ -244,7 +244,12 @@ def reverse_dem(input_dem):
244
244
  out_dem.nodata = -nodata
245
245
 
246
246
 
247
- def downsample_dem(input_dem, scale, median_filter_size=7):
247
+ def downsample_dem(
248
+ input_dem,
249
+ scale,
250
+ median_filter_size=7,
251
+ default_alt=0,
252
+ ):
248
253
  """
249
254
  Downsample median DEM with median resampling
250
255
 
@@ -266,10 +271,10 @@ def downsample_dem(input_dem, scale, median_filter_size=7):
266
271
  metadata["transform"] = dst_transform
267
272
  metadata["height"] = dst_height
268
273
  metadata["width"] = dst_width
269
- output = np.zeros((dst_height, dst_width))
274
+ dem_data = np.zeros((dst_height, dst_width))
270
275
  reproject(
271
276
  data,
272
- output,
277
+ dem_data,
273
278
  src_transform=src_transform,
274
279
  src_crs=crs,
275
280
  dst_transform=dst_transform,
@@ -278,26 +283,39 @@ def downsample_dem(input_dem, scale, median_filter_size=7):
278
283
  resampling=Resampling.med,
279
284
  )
280
285
 
281
- # Median filter as post-processing
282
- output = median_filter(output, size=median_filter_size)
286
+ # Post-processing
287
+
288
+ # Median filter
289
+ dem_data = median_filter(dem_data, size=median_filter_size)
290
+
291
+ # Fill nodata
292
+ dem_data = rio.fill.fillnodata(
293
+ dem_data,
294
+ mask=~(dem_data == nodata),
295
+ )
296
+
297
+ dem_data[dem_data == nodata] = default_alt
283
298
 
284
299
  with rio.open(input_dem, "w", **metadata) as dst:
285
- dst.write(output, 1)
300
+ dst.write(dem_data, 1)
286
301
 
287
302
 
288
- def modify_terrain_bounds(dem_roi_to_use, epsg, margin):
303
+ def modify_terrain_bounds(
304
+ bounds_poly, in_epsg, out_epsg, constant_margin, linear_margin=0
305
+ ):
289
306
  """
290
307
  Modify the terrain bounds
291
308
 
292
- :param dem_roi_to_use: the dem roi
293
- :type dem_roi_to_use: polygon
294
- :param epsg: the epsg code
295
- :type epsg: int
296
- :param margin: the margin
309
+ :param bounds_poly: Input region of interest for DEM
310
+ :type bounds_poly: list
311
+ :param in_epsg: EPSG code of dem_roi_to_use
312
+ :type in_epsg: int
313
+ :param out_epsg: EPSG code of dem_roi_to_use
314
+ :type out_epsg: int
315
+ :param margin: Margin of the output ROI in meters
297
316
  :type margin: int
298
317
  """
299
318
  # Get bounds
300
- bounds_poly = dem_roi_to_use.bounds
301
319
  xmin = min(bounds_poly[0], bounds_poly[2])
302
320
  xmax = max(bounds_poly[0], bounds_poly[2])
303
321
  ymin = min(bounds_poly[1], bounds_poly[3])
@@ -305,24 +323,25 @@ def modify_terrain_bounds(dem_roi_to_use, epsg, margin):
305
323
 
306
324
  bounds_cloud = [xmin, ymin, xmax, ymax]
307
325
 
308
- # Convert resolution and margin to degrees
309
- utm_epsg = preprocessing.get_utm_zone_as_epsg_code(xmin, ymin)
310
- conversion_factor = preprocessing.get_conversion_factor(
311
- bounds_cloud, 4326, utm_epsg
312
- )
313
- margin_in_degrees = margin * conversion_factor
326
+ if in_epsg == 4326:
327
+ # Convert resolution and margin to degrees
328
+ utm_epsg = preprocessing.get_utm_zone_as_epsg_code(xmin, ymin)
329
+ conversion_factor = preprocessing.get_conversion_factor(
330
+ bounds_cloud, 4326, utm_epsg
331
+ )
332
+ constant_margin *= conversion_factor
314
333
 
315
334
  # Get borders, adding margin
316
- xmin = xmin - margin_in_degrees
317
- ymin = ymin - margin_in_degrees
318
- xmax = xmax + margin_in_degrees
319
- ymax = ymax + margin_in_degrees
335
+ xmin = xmin - constant_margin - linear_margin * (xmax - xmin)
336
+ ymin = ymin - constant_margin - linear_margin * (ymax - ymin)
337
+ xmax = xmax + constant_margin + linear_margin * (xmax - xmin)
338
+ ymax = ymax + constant_margin + linear_margin * (ymax - ymin)
320
339
 
321
340
  terrain_bounds = [xmin, ymin, xmax, ymax]
322
341
 
323
- if epsg != 4326:
324
- crs_in = pyproj.CRS.from_epsg(4326)
325
- crs_out = pyproj.CRS.from_epsg(epsg)
342
+ if out_epsg != in_epsg:
343
+ crs_in = pyproj.CRS.from_epsg(in_epsg)
344
+ crs_out = pyproj.CRS.from_epsg(out_epsg)
326
345
 
327
346
  transformer = pyproj.Transformer.from_crs(
328
347
  crs_in, crs_out, always_xy=True
@@ -344,7 +363,7 @@ def modify_terrain_bounds(dem_roi_to_use, epsg, margin):
344
363
 
345
364
  def reproject_dem(dsm_file_name, epsg_out, out_file_name):
346
365
  """
347
- Reproject the dem
366
+ Reproject the DEM
348
367
 
349
368
  :param dsm_file_name: the path to dsm
350
369
  :type dsm_file_name: str
@@ -64,14 +64,16 @@ class DichotomicGeneration(DemGeneration, short_name="dichotomic"):
64
64
 
65
65
  # pylint: disable=too-many-instance-attributes
66
66
 
67
- def __init__(self, conf=None):
67
+ def __init__(self, scaling_coeff, conf=None):
68
68
  """
69
69
  Init function of DichotomicGeneration
70
70
 
71
+ :param scaling_coeff: scaling factor for resolution
72
+ :type scaling_coeff: float
71
73
  :param conf: configuration for DichotomicGeneration
72
74
  :return: an application_to_use object
73
75
  """
74
- super().__init__(conf=conf)
76
+ super().__init__(scaling_coeff, conf=conf)
75
77
 
76
78
  # check conf
77
79
  self.used_method = self.used_config["method"]
@@ -179,8 +181,9 @@ class DichotomicGeneration(DemGeneration, short_name="dichotomic"):
179
181
  output_geoid,
180
182
  dem_roi_to_use=None,
181
183
  initial_elevation=None,
184
+ default_alt=0,
182
185
  cars_orchestrator=None,
183
- ):
186
+ ): # pylint: disable=W0613
184
187
  """
185
188
  Run dichotomic dem generation using matches
186
189
 
@@ -63,14 +63,16 @@ class Rasterization(DemGeneration, short_name="bulldozer_on_raster"):
63
63
 
64
64
  # pylint: disable=too-many-instance-attributes
65
65
 
66
- def __init__(self, conf=None):
66
+ def __init__(self, scaling_coeff, conf=None):
67
67
  """
68
68
  Init function of Rasterization
69
69
 
70
+ :param scaling_coeff: scaling factor for resolution
71
+ :type scaling_coeff: float
70
72
  :param conf: configuration for Rasterization
71
73
  :return: an application_to_use object
72
74
  """
73
- super().__init__(conf=conf)
75
+ super().__init__(scaling_coeff, conf=conf)
74
76
 
75
77
  # check conf
76
78
  self.used_method = self.used_config["method"]
@@ -134,8 +136,12 @@ class Rasterization(DemGeneration, short_name="bulldozer_on_raster"):
134
136
 
135
137
  # Overload conf
136
138
  overloaded_conf["method"] = conf.get("method", "bulldozer_on_raster")
137
- overloaded_conf["resolution"] = conf.get("resolution", 2)
138
- overloaded_conf["margin"] = conf.get("margin", 500)
139
+ overloaded_conf["resolution"] = conf.get(
140
+ "resolution", float(self.scaling_coeff * 2)
141
+ )
142
+ overloaded_conf["margin"] = conf.get(
143
+ "margin", float(self.scaling_coeff * 500)
144
+ )
139
145
  overloaded_conf["morphological_filters_size"] = conf.get(
140
146
  "morphological_filters_size", 30
141
147
  )
@@ -153,7 +159,9 @@ class Rasterization(DemGeneration, short_name="bulldozer_on_raster"):
153
159
  )
154
160
  overloaded_conf["min_dem"] = conf.get("min_dem", -500)
155
161
  overloaded_conf["max_dem"] = conf.get("max_dem", 1000)
156
- overloaded_conf["height_margin"] = conf.get("height_margin", 20)
162
+ overloaded_conf["height_margin"] = conf.get(
163
+ "height_margin", float(self.scaling_coeff * 20)
164
+ )
157
165
  overloaded_conf["bulldozer_max_object_size"] = conf.get(
158
166
  "bulldozer_max_object_size", 8
159
167
  )
@@ -203,6 +211,7 @@ class Rasterization(DemGeneration, short_name="bulldozer_on_raster"):
203
211
  input_geoid,
204
212
  output_geoid,
205
213
  initial_elevation=None,
214
+ default_alt=0,
206
215
  cars_orchestrator=None,
207
216
  ):
208
217
  """
@@ -410,6 +419,7 @@ class Rasterization(DemGeneration, short_name="bulldozer_on_raster"):
410
419
  dem_median_path_out,
411
420
  scale=self.dem_median_output_resolution / resolution_in_meters,
412
421
  median_filter_size=self.postprocessing_median_filter_size,
422
+ default_alt=default_alt,
413
423
  )
414
424
 
415
425
  # Launch Bulldozer on dem min
@@ -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,6 +78,7 @@ class CensusMccnnSgm(
78
78
  "census_sgm_mountain_and_vegetation",
79
79
  "census_sgm_homogeneous",
80
80
  "mccnn_sgm",
81
+ "auto",
81
82
  ],
82
83
  ): # pylint: disable=R0903,disable=R0902
83
84
  """
@@ -178,7 +179,7 @@ class CensusMccnnSgm(
178
179
 
179
180
  # Overload conf
180
181
  overloaded_conf["method"] = conf.get(
181
- "method", "census_sgm_default"
182
+ "method", "auto"
182
183
  ) # change it if census_sgm is not default
183
184
  # method called in abstract_dense_matching_app.py
184
185
  overloaded_conf["min_epi_tile_size"] = conf.get(
@@ -597,6 +598,13 @@ class CensusMccnnSgm(
597
598
 
598
599
  return margins_wrapper
599
600
 
601
+ def get_method(self):
602
+ """
603
+ return the method that will be used in dense_matching
604
+ """
605
+
606
+ return self.used_method
607
+
600
608
  @cars_profile(name="Optimal size estimation")
601
609
  def get_optimal_tile_size(self, disp_range_grid, max_ram_per_worker):
602
610
  """
@@ -792,26 +800,7 @@ class CensusMccnnSgm(
792
800
  global_infos_cars_ds = cars_dataset.CarsDataset("dict")
793
801
 
794
802
  # 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
- )
803
+ raster_profile = DefaultGTiffProfile(count=1)
815
804
 
816
805
  # saving infos
817
806
  # disp grids
@@ -216,6 +216,25 @@ def generate_disp_range_from_dem_wrapper(
216
216
  :rtype: dict
217
217
  """
218
218
 
219
+ # compute reverse matrix
220
+ transform_sensor = rasterio.Affine(
221
+ *np.abs(
222
+ inputs.rasterio_get_transform(
223
+ sensor_image_right["image"]["main_file"]
224
+ )
225
+ )
226
+ )
227
+
228
+ trans_inv_sensor = ~transform_sensor
229
+ # Transform to positive values
230
+ trans_inv_sensor = np.array(trans_inv_sensor)
231
+ trans_inv_sensor = np.reshape(trans_inv_sensor, (3, 3))
232
+ if trans_inv_sensor[0, 0] < 0:
233
+ trans_inv_sensor[0, :] *= -1
234
+ if trans_inv_sensor[1, 1] < 0:
235
+ trans_inv_sensor[1, :] *= -1
236
+ trans_inv_sensor = affine.Affine(*list(trans_inv_sensor.flatten()))
237
+
219
238
  # Geometry plugin
220
239
  geo_plugin = geom_plugin_with_dem_and_geoid
221
240
 
@@ -276,14 +295,11 @@ def generate_disp_range_from_dem_wrapper(
276
295
  (np.max(col_range_with_margin), np.max(row_range_with_margin)),
277
296
  ]
278
297
  sensor_bbox = geo_plugin.sensor_position_from_grid(grid_right, epi_bbox)
279
- transform_sensor = inputs.rasterio_get_transform(
280
- sensor_image_right["image"]["main_file"]
281
- )
282
298
  row_sensor_bbox, col_sensor_bbox = transform_physical_point_to_index(
283
- ~transform_sensor, sensor_bbox[:, 1], sensor_bbox[:, 0]
299
+ trans_inv_sensor, sensor_bbox[:, 1], sensor_bbox[:, 0]
284
300
  )
285
301
 
286
- terrain_bbox = geo_plugin.direct_loc(
302
+ terrain_bbox = geo_plugin.safe_direct_loc(
287
303
  sensor_image_right["image"]["main_file"],
288
304
  sensor_image_right["geomodel"],
289
305
  col_sensor_bbox,
@@ -365,7 +381,7 @@ def generate_disp_range_from_dem_wrapper(
365
381
  ind_cols_sensor,
366
382
  ind_rows_sensor,
367
383
  _,
368
- ) = geom_plugin_with_dem_and_geoid.inverse_loc(
384
+ ) = geom_plugin_with_dem_and_geoid.safe_inverse_loc(
369
385
  sensor_image_right["image"]["main_file"],
370
386
  sensor_image_right["geomodel"],
371
387
  lat_mean,
@@ -397,35 +413,13 @@ def generate_disp_range_from_dem_wrapper(
397
413
  )
398
414
  )
399
415
 
400
- # compute reverse matrix
401
- transform_sensor = rasterio.Affine(
402
- *np.abs(
403
- inputs.rasterio_get_transform(
404
- sensor_image_right["image"]["main_file"]
405
- )
416
+ # Transform physical position to index
417
+ ind_rows_sensor_grid, ind_cols_sensor_grid = (
418
+ transform_physical_point_to_index(
419
+ trans_inv_sensor, sensors_positions[:, 1], sensors_positions[:, 0]
406
420
  )
407
421
  )
408
422
 
409
- trans_inv = ~transform_sensor
410
- # Transform to positive values
411
- trans_inv = np.array(trans_inv)
412
- trans_inv = np.reshape(trans_inv, (3, 3))
413
- if trans_inv[0, 0] < 0:
414
- trans_inv[0, :] *= -1
415
- if trans_inv[1, 1] < 0:
416
- trans_inv[1, :] *= -1
417
- trans_inv = affine.Affine(*list(trans_inv.flatten()))
418
-
419
- # Transform physical position to index
420
- index_positions = np.empty(sensors_positions.shape)
421
- for row_point in range(index_positions.shape[0]):
422
- row_geo, col_geo = sensors_positions[row_point, :]
423
- col, row = trans_inv * (row_geo, col_geo)
424
- index_positions[row_point, :] = (row, col)
425
-
426
- ind_rows_sensor_grid = index_positions[:, 0] - 0.5
427
- ind_cols_sensor_grid = index_positions[:, 1] - 0.5
428
-
429
423
  if len(ind_rows_sensor) < 5:
430
424
  # QH6214 needs at least 4 points for interpolation
431
425
 
@@ -0,0 +1,13 @@
1
+ {
2
+ "10": "census_sgm_mountain_and_vegetation",
3
+ "20": "census_sgm_mountain_and_vegetation",
4
+ "30": "census_sgm_mountain_and_vegetation",
5
+ "40": "census_sgm_mountain_and_vegetation",
6
+ "50": "census_sgm_urban",
7
+ "60": "census_sgm_homogeneous",
8
+ "70": "census_sgm_mountain_and_vegetation",
9
+ "80": "census_sgm_mountain_and_vegetation",
10
+ "90": "census_sgm_mountain_and_vegetation",
11
+ "95": "census_sgm_mountain_and_vegetation",
12
+ "100": "census_sgm_mountain_and_vegetation"
13
+ }