cars 1.0.0a2__cp312-cp312-win_amd64.whl → 1.0.0a3__cp312-cp312-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 (53) hide show
  1. cars/applications/application.py +14 -6
  2. cars/applications/application_template.py +22 -0
  3. cars/applications/auxiliary_filling/auxiliary_filling_from_sensors_app.py +15 -10
  4. cars/applications/auxiliary_filling/auxiliary_filling_wrappers.py +7 -6
  5. cars/applications/dem_generation/abstract_dem_generation_app.py +9 -5
  6. cars/applications/dem_generation/dem_generation_wrappers.py +46 -27
  7. cars/applications/dem_generation/dichotomic_generation_app.py +6 -3
  8. cars/applications/dem_generation/rasterization_app.py +15 -5
  9. cars/applications/dense_match_filling/cpp/dense_match_filling_cpp.cp312-win_amd64.dll.a +0 -0
  10. cars/applications/dense_match_filling/cpp/dense_match_filling_cpp.cp312-win_amd64.pyd +0 -0
  11. cars/applications/dense_matching/census_mccnn_sgm_app.py +11 -22
  12. cars/applications/dense_matching/cpp/dense_matching_cpp.cp312-win_amd64.dll.a +0 -0
  13. cars/applications/dense_matching/cpp/dense_matching_cpp.cp312-win_amd64.pyd +0 -0
  14. cars/applications/dense_matching/disparity_grid_algo.py +26 -32
  15. cars/applications/dense_matching/loaders/config_mapping.json +13 -0
  16. cars/applications/dense_matching/loaders/global_land_cover_map.tif +0 -0
  17. cars/applications/dense_matching/loaders/pandora_loader.py +78 -1
  18. cars/applications/dsm_filling/border_interpolation_app.py +10 -5
  19. cars/applications/dsm_filling/bulldozer_filling_app.py +14 -7
  20. cars/applications/dsm_filling/exogenous_filling_app.py +10 -5
  21. cars/applications/point_cloud_outlier_removal/abstract_outlier_removal_app.py +9 -5
  22. cars/applications/point_cloud_outlier_removal/small_components_app.py +5 -3
  23. cars/applications/point_cloud_outlier_removal/statistical_app.py +4 -2
  24. cars/applications/rasterization/abstract_pc_rasterization_app.py +1 -0
  25. cars/applications/rasterization/simple_gaussian_app.py +28 -3
  26. cars/applications/resampling/resampling_algo.py +44 -49
  27. cars/applications/sparse_matching/sift_app.py +2 -22
  28. cars/core/geometry/abstract_geometry.py +113 -2
  29. cars/core/geometry/shareloc_geometry.py +2 -0
  30. cars/core/inputs.py +15 -0
  31. cars/core/projection.py +117 -0
  32. cars/data_structures/cars_dataset.py +7 -5
  33. cars/orchestrator/cluster/log_wrapper.py +1 -1
  34. cars/orchestrator/cluster/mp_cluster/multiprocessing_cluster.py +1 -1
  35. cars/orchestrator/orchestrator.py +1 -1
  36. cars/pipelines/default/default_pipeline.py +46 -26
  37. cars/pipelines/parameters/advanced_parameters.py +17 -0
  38. cars/pipelines/parameters/advanced_parameters_constants.py +4 -0
  39. cars/pipelines/parameters/output_parameters.py +44 -8
  40. cars/pipelines/parameters/sensor_inputs.py +97 -3
  41. cars/pipelines/unit/unit_pipeline.py +194 -99
  42. cars-1.0.0a3.dist-info/DELVEWHEEL +2 -0
  43. {cars-1.0.0a2.dist-info → cars-1.0.0a3.dist-info}/METADATA +1 -1
  44. {cars-1.0.0a2.dist-info → cars-1.0.0a3.dist-info}/RECORD +49 -47
  45. cars.libs/libgcc_s_seh-1-ca70890bbc5723b6d0ea31e9c9cded2b.dll +0 -0
  46. cars.libs/libstdc++-6-00ee19f73d5122a1277c137b1c218401.dll +0 -0
  47. cars.libs/libwinpthread-1-f5042e8e3d21edce20c1bc99445f551b.dll +0 -0
  48. cars-1.0.0a2.dist-info/DELVEWHEEL +0 -2
  49. cars.libs/libgcc_s_seh-1-f2b6825d483bdf14050493af93b5997d.dll +0 -0
  50. cars.libs/libstdc++-6-6b0059df6bc601df5a0f18a5805eea05.dll +0 -0
  51. cars.libs/libwinpthread-1-e01b8e85fd67c2b861f64d4ccc7df607.dll +0 -0
  52. {cars-1.0.0a2.dist-info → cars-1.0.0a3.dist-info}/WHEEL +0 -0
  53. {cars-1.0.0a2.dist-info → cars-1.0.0a3.dist-info}/entry_points.txt +0 -0
@@ -18,6 +18,9 @@
18
18
  # See the License for the specific language governing permissions and
19
19
  # limitations under the License.
20
20
  #
21
+
22
+ # pylint: disable=C0302
23
+
21
24
  """
22
25
  this module contains the abstract geometry class to use in the
23
26
  geometry plugins
@@ -50,7 +53,7 @@ class AbstractGeometry(metaclass=ABCMeta):
50
53
 
51
54
  available_plugins: Dict = {}
52
55
 
53
- def __new__(cls, geometry_plugin_conf=None, **kwargs):
56
+ def __new__(cls, geometry_plugin_conf=None, scaling_coeff=1, **kwargs):
54
57
  """
55
58
  Return the required plugin
56
59
  :raises:
@@ -59,6 +62,8 @@ class AbstractGeometry(metaclass=ABCMeta):
59
62
  :param geometry_plugin_conf: plugin name or plugin configuration
60
63
  to instantiate
61
64
  :type geometry_plugin_conf: str or dict
65
+ :param scaling_coeff: scaling factor for resolution
66
+ :type scaling_coeff: float
62
67
  :return: a geometry_plugin object
63
68
  """
64
69
  if geometry_plugin_conf is not None:
@@ -100,9 +105,12 @@ class AbstractGeometry(metaclass=ABCMeta):
100
105
  dem=None,
101
106
  geoid=None,
102
107
  default_alt=None,
108
+ scaling_coeff=1,
103
109
  **kwargs,
104
110
  ):
105
111
 
112
+ self.scaling_coeff = scaling_coeff
113
+
106
114
  config = self.check_conf(geometry_plugin_conf)
107
115
 
108
116
  self.plugin_name = config["plugin_name"]
@@ -160,7 +168,9 @@ class AbstractGeometry(metaclass=ABCMeta):
160
168
  "plugin_name", "SharelocGeometry"
161
169
  )
162
170
  overloaded_conf["interpolator"] = conf.get("interpolator", "cubic")
163
- overloaded_conf["dem_roi_margin"] = conf.get("dem_roi_margin", 0.012)
171
+ overloaded_conf["dem_roi_margin"] = conf.get(
172
+ "dem_roi_margin", float(self.scaling_coeff * 0.012)
173
+ )
164
174
 
165
175
  geometry_schema = {
166
176
  "plugin_name": str,
@@ -617,6 +627,55 @@ class AbstractGeometry(metaclass=ABCMeta):
617
627
  :return: Latitude, Longitude, Altitude coordinates list as a numpy array
618
628
  """
619
629
 
630
+ def safe_direct_loc(
631
+ self,
632
+ sensor,
633
+ geomodel,
634
+ x_coord: np.array,
635
+ y_coord: np.array,
636
+ z_coord: np.array = None,
637
+ ) -> np.ndarray:
638
+ """
639
+ For a given image points list, compute the latitudes,
640
+ longitudes, altitudes
641
+
642
+ Advice: to be sure, use x,y,z list inputs only
643
+
644
+ :param sensor: path to sensor image
645
+ :param geomodel: path and attributes for geomodel
646
+ :param x_coord: X Coordinates list in input image sensor
647
+ :param y_coord: Y Coordinate list in input image sensor
648
+ :param z_coord: Z Altitude list coordinate to take the image
649
+ :return: Latitude, Longitude, Altitude coordinates list as a numpy array
650
+ """
651
+ if len(x_coord) > 0:
652
+ ground_points = self.direct_loc(
653
+ sensor,
654
+ geomodel,
655
+ x_coord,
656
+ y_coord,
657
+ z_coord,
658
+ )
659
+ else:
660
+ logging.warning("Direct loc function launched on empty list")
661
+ return []
662
+ if z_coord is None:
663
+ status = np.any(np.isnan(ground_points), axis=0)
664
+ if sum(status) > 0:
665
+ logging.warning(
666
+ "{} errors have been detected on direct "
667
+ "loc and will be re-launched".format(sum(status))
668
+ )
669
+ ground_points_retry = self.direct_loc(
670
+ sensor,
671
+ geomodel,
672
+ x_coord[status],
673
+ y_coord[status],
674
+ np.array([0]),
675
+ )
676
+ ground_points[:, status] = ground_points_retry
677
+ return ground_points
678
+
620
679
  @abstractmethod
621
680
  def inverse_loc(
622
681
  self,
@@ -640,6 +699,58 @@ class AbstractGeometry(metaclass=ABCMeta):
640
699
  :return: X / Y / Z Coordinates list in input image as a numpy array
641
700
  """
642
701
 
702
+ def safe_inverse_loc(
703
+ self,
704
+ sensor,
705
+ geomodel,
706
+ lat_coord: np.array,
707
+ lon_coord: np.array,
708
+ z_coord: np.array = None,
709
+ ) -> np.ndarray:
710
+ """
711
+ For a given image points list, compute the latitudes,
712
+ longitudes, altitudes
713
+
714
+ Advice: to be sure, use x,y,z list inputs only
715
+
716
+ :param sensor: path to sensor image
717
+ :param geomodel: path and attributes for geomodel
718
+ :param lat_coord: latitute Coordinate list
719
+ :param lon_coord: longitude Coordinates list
720
+ :param z_coord: Z Altitude list
721
+ :return: X / Y / Z Coordinates list in input image as a numpy array
722
+ """
723
+ if len(lat_coord) > 0:
724
+ image_points = self.inverse_loc(
725
+ sensor,
726
+ geomodel,
727
+ lat_coord,
728
+ lon_coord,
729
+ z_coord,
730
+ )
731
+ image_points = np.array(image_points)
732
+ else:
733
+ logging.warning("Inverse loc function launched on empty list")
734
+ return [], [], []
735
+ if z_coord is None:
736
+ image_points = np.array(image_points)
737
+ status = np.any(np.isnan(image_points), axis=0)
738
+ if sum(status) > 0:
739
+ logging.warning(
740
+ "{} errors have been detected on inverse "
741
+ "loc and will be re-launched".format(sum(status))
742
+ )
743
+ image_points_retry = self.inverse_loc(
744
+ sensor,
745
+ geomodel,
746
+ lat_coord[status],
747
+ lon_coord[status],
748
+ np.array([self.default_alt]),
749
+ )
750
+
751
+ image_points[:, status] = image_points_retry
752
+ return image_points[0], image_points[1], image_points[2]
753
+
643
754
  def image_envelope(
644
755
  self,
645
756
  sensor,
@@ -63,6 +63,7 @@ class SharelocGeometry(AbstractGeometry):
63
63
  geoid=None,
64
64
  default_alt=None,
65
65
  pairs_for_roi=None,
66
+ scaling_coeff=1,
66
67
  ):
67
68
 
68
69
  super().__init__(
@@ -71,6 +72,7 @@ class SharelocGeometry(AbstractGeometry):
71
72
  geoid=geoid,
72
73
  default_alt=default_alt,
73
74
  pairs_for_roi=pairs_for_roi,
75
+ scaling_coeff=scaling_coeff,
74
76
  )
75
77
 
76
78
  self.dem_roi = None
cars/core/inputs.py CHANGED
@@ -36,6 +36,7 @@ import numpy as np
36
36
  import rasterio as rio
37
37
  import xarray as xr
38
38
  from json_checker import Checker
39
+ from pyproj import CRS
39
40
  from rasterio.warp import Resampling, calculate_default_transform, reproject
40
41
  from rasterio.windows import Window
41
42
  from shapely.geometry import shape
@@ -378,6 +379,20 @@ def rasterio_get_epsg(raster_file: str) -> int:
378
379
  return epsg
379
380
 
380
381
 
382
+ def rasterio_get_crs(raster_file: str) -> CRS:
383
+ """
384
+ Get the crs of an image file
385
+
386
+ :param raster_file: Image file
387
+ :return: The crs of the given image
388
+ """
389
+ crs = None
390
+ with rio.open(raster_file, "r") as descriptor:
391
+ crs = descriptor.crs
392
+
393
+ return crs
394
+
395
+
381
396
  def rasterio_transform_epsg(file_name, new_epsg):
382
397
  """
383
398
  Modify epsg of raster file
cars/core/projection.py CHANGED
@@ -182,6 +182,22 @@ def polygon_projection(poly: Polygon, epsg_in: int, epsg_out: int) -> Polygon:
182
182
  return poly
183
183
 
184
184
 
185
+ def polygon_projection_crs(poly: Polygon, crs_in: CRS, crs_out: CRS) -> Polygon:
186
+ """
187
+ Projects a polygon from an initial crs to another
188
+
189
+ :param poly: poly to project
190
+ :param crs_in: initial crs
191
+ :param crs_out: final crs
192
+ :return: The polygon in the final projection
193
+ """
194
+ # Project polygon between CRS (keep always_xy for compatibility)
195
+ project = pyproj.Transformer.from_crs(crs_in, crs_out, always_xy=True)
196
+ poly = transform(project.transform, poly)
197
+
198
+ return poly
199
+
200
+
185
201
  def geo_to_ecef(
186
202
  lat: np.ndarray, lon: np.ndarray, alt: np.ndarray
187
203
  ) -> Tuple[np.ndarray, np.ndarray, np.ndarray]:
@@ -351,6 +367,27 @@ def point_cloud_conversion(
351
367
  return cloud_in
352
368
 
353
369
 
370
+ def point_cloud_conversion_crs(
371
+ cloud_in: np.ndarray, crs_in: int, crs_out: int
372
+ ) -> np.ndarray:
373
+ """
374
+ Convert a point cloud from a SRS to another one.
375
+
376
+ :param cloud_in: cloud to project
377
+ :param crs_in: crs of the input SRS
378
+ :param crs_out: crs of the output SRS
379
+ :return: Projected point cloud
380
+ """
381
+ # Project point cloud between CRS (keep always_xy for compatibility)
382
+ cloud_in = np.array(cloud_in).T
383
+ transformer = pyproj.Transformer.from_crs(crs_in, crs_out, always_xy=True)
384
+
385
+ cloud_in = transformer.transform(*cloud_in)
386
+ cloud_in = np.array(cloud_in).T
387
+
388
+ return cloud_in
389
+
390
+
354
391
  def get_xyz_np_array_from_dataset(
355
392
  cloud_in: xr.Dataset,
356
393
  ) -> Tuple[np.array, List[int]]:
@@ -721,3 +758,83 @@ def get_ground_angles(
721
758
  convergence_angle = np.degrees(utils.angle_vectors(enu1, enu2))
722
759
 
723
760
  return az1, elev_angle1, az2, elev_angle2, convergence_angle
761
+
762
+
763
+ def get_output_crs(epsg, out_conf):
764
+ """
765
+ Détermine le CRS de sortie en fonction de la config.
766
+ """
767
+ geoid = out_conf.get("geoid")
768
+ crs_epsg = CRS(f"EPSG:{epsg}")
769
+
770
+ if len(crs_epsg.axis_info) != 2:
771
+ return crs_epsg # the user himself set a 3D CRS
772
+
773
+ geoid_is_path = isinstance(geoid, str)
774
+
775
+ if geoid_is_path: # user given geoid
776
+ vepsg = guess_vcrs_from_file_name(geoid)
777
+ if vepsg is None:
778
+ custom_wkt = (
779
+ 'VERTCRS["Custom geoid height",'
780
+ + f' VDATUM["Custom geoid model (file: {geoid})"],'
781
+ + " CS[vertical,1],"
782
+ + ' AXIS["gravity-related height (h)", up],'
783
+ + ' LENGTHUNIT["metre", 1, ID["EPSG", 9001]]'
784
+ "]"
785
+ )
786
+ logging.warning(
787
+ "Could not create a known VCRS from the geoid file."
788
+ )
789
+ return CRS.from_wkt(
790
+ f'COMPOUNDCRS["EPSG:{epsg} + Custom geoid height",'
791
+ f" {crs_epsg.to_wkt()},"
792
+ f" {custom_wkt}]"
793
+ )
794
+ # a vepsg was found using the geoid file
795
+ return CRS(f"EPSG:{epsg}+{vepsg}")
796
+
797
+ if geoid: # geoid == True
798
+ return CRS(f"EPSG:{epsg}+5773")
799
+
800
+ # geoid == False
801
+ wgs84_wkt = (
802
+ 'VERTCRS["WGS 84 ellipsoidal height",'
803
+ + ' VDATUM["WGS 84"],'
804
+ + " CS[vertical,1],"
805
+ + ' AXIS["ellipsoidal height (h)", up],'
806
+ + ' LENGTHUNIT["metre", 1, ID["EPSG", 9001]]'
807
+ "]"
808
+ )
809
+ logging.warning("The output VCRS is WGS84.")
810
+
811
+ return CRS.from_wkt(
812
+ f'COMPOUNDCRS["EPSG:{epsg} + WGS84 ellipsoidal height",'
813
+ f" {crs_epsg.to_wkt()},"
814
+ f" {wgs84_wkt}]"
815
+ )
816
+
817
+
818
+ def guess_vcrs_from_file_name(filepath):
819
+ """
820
+ Tries to detect the geoid's EPSG from the file name
821
+ """
822
+ filename = os.path.basename(filepath).lower()
823
+
824
+ known_models = {
825
+ "egm96": 5773, # EGM96 height
826
+ "egm_96": 5773, # alias
827
+ "egm 96": 5773, # alias
828
+ "egm1996": 5773, # alias
829
+ "egm08": 3855, # EGM2008 height
830
+ "egm_08": 3855, # alias
831
+ "egm 08": 3855, # alias
832
+ "egm2008": 3855, # alias
833
+ }
834
+
835
+ for key, vepsg in known_models.items():
836
+ if key in filename:
837
+ return vepsg
838
+
839
+ # aucun match connu
840
+ return None
@@ -38,6 +38,7 @@ from typing import Dict
38
38
  # Third party imports
39
39
  import numpy as np
40
40
  import pandas
41
+ import pyproj
41
42
  import rasterio as rio
42
43
  import xarray as xr
43
44
  from rasterio.profiles import DefaultGTiffProfile
@@ -1327,12 +1328,13 @@ def dict_profile_to_rio_profile(dict_profile: Dict) -> Dict:
1327
1328
  crs = None
1328
1329
  if "crs" in dict_profile:
1329
1330
  if dict_profile["crs"] is not None:
1330
- if isinstance(dict_profile["crs"], str):
1331
- crs = rio.crs.CRS.from_epsg(
1332
- dict_profile["crs"].replace("EPSG:", "")
1333
- )
1331
+ if (
1332
+ isinstance(dict_profile["crs"], str)
1333
+ and "EPSG:" in dict_profile["crs"]
1334
+ ):
1335
+ crs = pyproj.CRS(dict_profile["crs"].replace("EPSG:", ""))
1334
1336
  else:
1335
- crs = rio.crs.CRS.from_epsg(dict_profile["crs"])
1337
+ crs = pyproj.CRS(dict_profile["crs"])
1336
1338
 
1337
1339
  rio_profile["crs"] = crs
1338
1340
  rio_profile["transform"] = transform
@@ -21,7 +21,7 @@
21
21
  """
22
22
  Contains functions for wrapper logs
23
23
  """
24
- # pylint: disable=too-many-lines
24
+ # pylint: disable=C0302
25
25
 
26
26
  import copy
27
27
  import cProfile
@@ -21,7 +21,7 @@
21
21
  """
22
22
  Contains abstract function for multiprocessing Cluster
23
23
  """
24
- # pylint: disable=too-many-lines
24
+ # pylint: disable=C0302
25
25
 
26
26
  import copy
27
27
  import itertools
@@ -22,7 +22,7 @@
22
22
  this module contains the orchestrator class
23
23
  """
24
24
 
25
- # pylint: disable=too-many-lines
25
+ # pylint: disable=C0302
26
26
 
27
27
  import collections
28
28
  import logging
@@ -120,9 +120,6 @@ class DefaultPipeline(PipelineTemplate):
120
120
  # Check conf inputs
121
121
  inputs = self.check_inputs(conf[INPUTS], config_dir=config_dir)
122
122
 
123
- # Check conf output
124
- output = self.check_output(conf[OUTPUT])
125
-
126
123
  # Check advanced parameters
127
124
  # TODO static method in the base class
128
125
  (
@@ -132,10 +129,19 @@ class DefaultPipeline(PipelineTemplate):
132
129
  self.geom_plugin_without_dem_and_geoid,
133
130
  self.geom_plugin_with_dem_and_geoid,
134
131
  _,
132
+ self.scaling_coeff,
133
+ _,
134
+ _,
135
135
  ) = advanced_parameters.check_advanced_parameters(
136
136
  inputs, conf.get(ADVANCED, {}), check_epipolar_a_priori=True
137
137
  )
138
138
 
139
+ # Check conf output
140
+ (
141
+ output,
142
+ self.scaling_coeff,
143
+ ) = self.check_output(conf[OUTPUT], self.scaling_coeff)
144
+
139
145
  resolutions = advanced["epipolar_resolutions"]
140
146
  if isinstance(resolutions, int):
141
147
  resolutions = [resolutions]
@@ -254,20 +260,6 @@ class DefaultPipeline(PipelineTemplate):
254
260
  # (except the last one)
255
261
  self.used_conf[key][OUTPUT][out_cst.PRODUCT_LEVEL] = "dsm"
256
262
 
257
- # The idea is to calculate the less possible things
258
- # So we override those parameters
259
- self.used_conf[key][ADVANCED][adv_cst.MERGING] = False
260
- self.used_conf[key][ADVANCED][adv_cst.PHASING] = None
261
- self.used_conf[key][OUTPUT][out_cst.SAVE_BY_PAIR] = False
262
-
263
- aux_items = self.used_conf[key][OUTPUT][
264
- out_cst.AUXILIARY
265
- ].items()
266
- for aux_key, _ in aux_items:
267
- if aux_key not in ("dem_min", "dem_max", "dem_median"):
268
- self.used_conf[key][OUTPUT][out_cst.AUXILIARY][
269
- aux_key
270
- ] = False
271
263
  else:
272
264
  # If save_intermediate_data is true,
273
265
  # we save the depth_maps also to debug
@@ -563,17 +555,19 @@ class DefaultPipeline(PipelineTemplate):
563
555
  return output_config
564
556
 
565
557
  @staticmethod
566
- def check_output(conf):
558
+ def check_output(conf, scaling_coeff):
567
559
  """
568
560
  Check the output given
569
561
 
570
562
  :param conf: configuration of output
571
563
  :type conf: dict
564
+ :param scaling_coeff: scaling factor for resolution
565
+ :type scaling_coeff: float
572
566
 
573
567
  :return overloader output
574
568
  :rtype : dict
575
569
  """
576
- return output_parameters.check_output_parameters(conf)
570
+ return output_parameters.check_output_parameters(conf, scaling_coeff)
577
571
 
578
572
  def merge_resolution_conf(self, config1, config2):
579
573
  """
@@ -629,6 +623,7 @@ class DefaultPipeline(PipelineTemplate):
629
623
  :param conf: configuration of applications
630
624
  :type conf: dict
631
625
  """
626
+ scaling_coeff = self.scaling_coeff
632
627
 
633
628
  # Check if all specified applications are used
634
629
  # Application in terrain_application are note used in
@@ -727,7 +722,9 @@ class DefaultPipeline(PipelineTemplate):
727
722
  if self.sensors_in_inputs:
728
723
  # Epipolar grid generation
729
724
  self.epipolar_grid_generation_application = Application(
730
- "grid_generation", cfg=used_conf.get("grid_generation", {})
725
+ "grid_generation",
726
+ cfg=used_conf.get("grid_generation", {}),
727
+ scaling_coeff=scaling_coeff,
731
728
  )
732
729
  used_conf["grid_generation"] = (
733
730
  self.epipolar_grid_generation_application.get_conf()
@@ -736,7 +733,9 @@ class DefaultPipeline(PipelineTemplate):
736
733
  # image resampling
737
734
 
738
735
  self.resampling_application = Application(
739
- "resampling", cfg=used_conf.get("resampling", {})
736
+ "resampling",
737
+ cfg=used_conf.get("resampling", {}),
738
+ scaling_coeff=scaling_coeff,
740
739
  )
741
740
  used_conf["resampling"] = self.resampling_application.get_conf()
742
741
 
@@ -758,10 +757,13 @@ class DefaultPipeline(PipelineTemplate):
758
757
  self.ground_truth_reprojection = Application(
759
758
  "ground_truth_reprojection",
760
759
  cfg=used_conf.get("ground_truth_reprojection", {}),
760
+ scaling_coeff=scaling_coeff,
761
761
  )
762
762
  # holes detection
763
763
  self.hole_detection_app = Application(
764
- "hole_detection", cfg=used_conf.get("hole_detection", {})
764
+ "hole_detection",
765
+ cfg=used_conf.get("hole_detection", {}),
766
+ scaling_coeff=scaling_coeff,
765
767
  )
766
768
  used_conf["hole_detection"] = self.hole_detection_app.get_conf()
767
769
 
@@ -772,6 +774,7 @@ class DefaultPipeline(PipelineTemplate):
772
774
  "dense_match_filling.1",
773
775
  {"method": "plane"},
774
776
  ),
777
+ scaling_coeff=scaling_coeff,
775
778
  )
776
779
  used_conf["dense_match_filling.1"] = (
777
780
  self.dense_match_filling_1.get_conf()
@@ -784,6 +787,7 @@ class DefaultPipeline(PipelineTemplate):
784
787
  "dense_match_filling.2",
785
788
  {"method": "zero_padding"},
786
789
  ),
790
+ scaling_coeff=scaling_coeff,
787
791
  )
788
792
  used_conf["dense_match_filling.2"] = (
789
793
  self.dense_match_filling_2.get_conf()
@@ -793,6 +797,7 @@ class DefaultPipeline(PipelineTemplate):
793
797
  self.sparse_mtch_sift_app = Application(
794
798
  "sparse_matching",
795
799
  cfg=used_conf.get("sparse_matching.sift", {"method": "sift"}),
800
+ scaling_coeff=scaling_coeff,
796
801
  )
797
802
  used_conf["sparse_matching.sift"] = (
798
803
  self.sparse_mtch_sift_app.get_conf()
@@ -820,7 +825,9 @@ class DefaultPipeline(PipelineTemplate):
820
825
  ):
821
826
  dense_matching_config["performance_map_method"] = "risk"
822
827
  self.dense_matching_app = Application(
823
- "dense_matching", cfg=dense_matching_config
828
+ "dense_matching",
829
+ cfg=dense_matching_config,
830
+ scaling_coeff=scaling_coeff,
824
831
  )
825
832
  used_conf["dense_matching"] = self.dense_matching_app.get_conf()
826
833
 
@@ -832,7 +839,9 @@ class DefaultPipeline(PipelineTemplate):
832
839
 
833
840
  # Triangulation
834
841
  self.triangulation_application = Application(
835
- "triangulation", cfg=used_conf.get("triangulation", {})
842
+ "triangulation",
843
+ cfg=used_conf.get("triangulation", {}),
844
+ scaling_coeff=scaling_coeff,
836
845
  )
837
846
  used_conf["triangulation"] = (
838
847
  self.triangulation_application.get_conf()
@@ -840,7 +849,9 @@ class DefaultPipeline(PipelineTemplate):
840
849
 
841
850
  # MNT generation
842
851
  self.dem_generation_application = Application(
843
- "dem_generation", cfg=used_conf.get("dem_generation", {})
852
+ "dem_generation",
853
+ cfg=used_conf.get("dem_generation", {}),
854
+ scaling_coeff=scaling_coeff,
844
855
  )
845
856
 
846
857
  height_margin = None
@@ -867,6 +878,7 @@ class DefaultPipeline(PipelineTemplate):
867
878
  "point_cloud_outlier_removal.1",
868
879
  {"method": "small_components"},
869
880
  ),
881
+ scaling_coeff=scaling_coeff,
870
882
  )
871
883
 
872
884
  connection_val = None
@@ -894,6 +906,7 @@ class DefaultPipeline(PipelineTemplate):
894
906
  "point_cloud_outlier_removal.2",
895
907
  {"method": "statistical"},
896
908
  ),
909
+ scaling_coeff=scaling_coeff,
897
910
  )
898
911
  used_conf["point_cloud_outlier_removal.2"] = (
899
912
  self.pc_outlier_removal_2_app.get_conf()
@@ -905,6 +918,7 @@ class DefaultPipeline(PipelineTemplate):
905
918
  self.pc_denoising_application = Application(
906
919
  "pc_denoising",
907
920
  cfg=used_conf.get("pc_denoising", {"method": "none"}),
921
+ scaling_coeff=scaling_coeff,
908
922
  )
909
923
  used_conf["pc_denoising"] = self.pc_denoising_application.get_conf()
910
924
 
@@ -914,6 +928,7 @@ class DefaultPipeline(PipelineTemplate):
914
928
  self.rasterization_application = Application(
915
929
  "point_cloud_rasterization",
916
930
  cfg=used_conf.get("point_cloud_rasterization", {}),
931
+ scaling_coeff=scaling_coeff,
917
932
  )
918
933
  used_conf["point_cloud_rasterization"] = (
919
934
  self.rasterization_application.get_conf()
@@ -925,6 +940,7 @@ class DefaultPipeline(PipelineTemplate):
925
940
  "dsm_filling.1",
926
941
  {"method": "exogenous_filling"},
927
942
  ),
943
+ scaling_coeff=scaling_coeff,
928
944
  )
929
945
  used_conf["dsm_filling.1"] = (
930
946
  self.dsm_filling_1_application.get_conf()
@@ -947,13 +963,16 @@ class DefaultPipeline(PipelineTemplate):
947
963
  "dsm_filling.3",
948
964
  {"method": "border_interpolation"},
949
965
  ),
966
+ scaling_coeff=scaling_coeff,
950
967
  )
951
968
  used_conf["dsm_filling.3"] = (
952
969
  self.dsm_filling_3_application.get_conf()
953
970
  )
954
971
  # Auxiliary filling
955
972
  self.auxiliary_filling_application = Application(
956
- "auxiliary_filling", cfg=conf.get("auxiliary_filling", {})
973
+ "auxiliary_filling",
974
+ cfg=conf.get("auxiliary_filling", {}),
975
+ scaling_coeff=scaling_coeff,
957
976
  )
958
977
  used_conf["auxiliary_filling"] = (
959
978
  self.auxiliary_filling_application.get_conf()
@@ -965,6 +984,7 @@ class DefaultPipeline(PipelineTemplate):
965
984
  self.pc_fusion_application = Application(
966
985
  "point_cloud_fusion",
967
986
  cfg=used_conf.get("point_cloud_fusion", {}),
987
+ scaling_coeff=scaling_coeff,
968
988
  )
969
989
  used_conf["point_cloud_fusion"] = (
970
990
  self.pc_fusion_application.get_conf()