cars 1.0.0a2__cp312-cp312-musllinux_1_2_i686.whl → 1.0.0a3__cp312-cp312-musllinux_1_2_i686.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/applications/application.py +14 -6
- cars/applications/application_template.py +22 -0
- cars/applications/auxiliary_filling/auxiliary_filling_from_sensors_app.py +15 -10
- cars/applications/auxiliary_filling/auxiliary_filling_wrappers.py +7 -6
- cars/applications/dem_generation/abstract_dem_generation_app.py +9 -5
- cars/applications/dem_generation/dem_generation_wrappers.py +46 -27
- cars/applications/dem_generation/dichotomic_generation_app.py +6 -3
- cars/applications/dem_generation/rasterization_app.py +15 -5
- cars/applications/dense_match_filling/cpp/dense_match_filling_cpp.cpython-312-i386-linux-musl.so +0 -0
- cars/applications/dense_matching/census_mccnn_sgm_app.py +11 -22
- cars/applications/dense_matching/cpp/dense_matching_cpp.cpython-312-i386-linux-musl.so +0 -0
- cars/applications/dense_matching/disparity_grid_algo.py +26 -32
- cars/applications/dense_matching/loaders/config_mapping.json +13 -0
- cars/applications/dense_matching/loaders/global_land_cover_map.tif +0 -0
- cars/applications/dense_matching/loaders/pandora_loader.py +78 -1
- cars/applications/dsm_filling/border_interpolation_app.py +10 -5
- cars/applications/dsm_filling/bulldozer_filling_app.py +14 -7
- cars/applications/dsm_filling/exogenous_filling_app.py +10 -5
- cars/applications/point_cloud_outlier_removal/abstract_outlier_removal_app.py +9 -5
- cars/applications/point_cloud_outlier_removal/small_components_app.py +5 -3
- cars/applications/point_cloud_outlier_removal/statistical_app.py +4 -2
- cars/applications/rasterization/abstract_pc_rasterization_app.py +1 -0
- cars/applications/rasterization/simple_gaussian_app.py +28 -3
- cars/applications/resampling/resampling_algo.py +44 -49
- cars/applications/sparse_matching/sift_app.py +2 -22
- cars/core/geometry/abstract_geometry.py +113 -2
- cars/core/geometry/shareloc_geometry.py +2 -0
- cars/core/inputs.py +15 -0
- cars/core/projection.py +117 -0
- cars/data_structures/cars_dataset.py +7 -5
- cars/orchestrator/cluster/log_wrapper.py +1 -1
- cars/orchestrator/cluster/mp_cluster/multiprocessing_cluster.py +1 -1
- cars/orchestrator/orchestrator.py +1 -1
- cars/pipelines/default/default_pipeline.py +46 -26
- cars/pipelines/parameters/advanced_parameters.py +17 -0
- cars/pipelines/parameters/advanced_parameters_constants.py +4 -0
- cars/pipelines/parameters/output_parameters.py +44 -8
- cars/pipelines/parameters/sensor_inputs.py +97 -3
- cars/pipelines/unit/unit_pipeline.py +194 -99
- {cars-1.0.0a2.dist-info → cars-1.0.0a3.dist-info}/METADATA +1 -1
- {cars-1.0.0a2.dist-info → cars-1.0.0a3.dist-info}/RECORD +175 -173
- {cars-1.0.0a2.dist-info → cars-1.0.0a3.dist-info}/WHEEL +0 -0
- {cars-1.0.0a2.dist-info → cars-1.0.0a3.dist-info}/entry_points.txt +0 -0
cars/applications/application.py
CHANGED
|
@@ -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
|
-
|
|
81
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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,
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
355
|
-
:type
|
|
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.
|
|
403
|
-
stacked_values.transpose(),
|
|
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
|
|
28
|
+
from cars.core.projection import polygon_projection_crs
|
|
28
29
|
|
|
29
30
|
|
|
30
|
-
def compute_sensor_bounds(sensor_inputs, geom_plugin,
|
|
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
|
|
42
|
-
:type
|
|
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] =
|
|
63
|
-
poly_geo, 4326,
|
|
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
|
|
29
|
+
from cars.applications.application_template import ScalingApplicationTemplate
|
|
30
30
|
|
|
31
31
|
|
|
32
32
|
@Application.register("dem_generation")
|
|
33
|
-
class DemGeneration(
|
|
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(
|
|
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
|
-
|
|
274
|
+
dem_data = np.zeros((dst_height, dst_width))
|
|
270
275
|
reproject(
|
|
271
276
|
data,
|
|
272
|
-
|
|
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
|
-
#
|
|
282
|
-
|
|
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(
|
|
300
|
+
dst.write(dem_data, 1)
|
|
286
301
|
|
|
287
302
|
|
|
288
|
-
def modify_terrain_bounds(
|
|
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
|
|
293
|
-
:type
|
|
294
|
-
:param
|
|
295
|
-
:type
|
|
296
|
-
:param
|
|
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
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
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 -
|
|
317
|
-
ymin = ymin -
|
|
318
|
-
xmax = xmax +
|
|
319
|
-
ymax = ymax +
|
|
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
|
|
324
|
-
crs_in = pyproj.CRS.from_epsg(
|
|
325
|
-
crs_out = pyproj.CRS.from_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
|
|
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(
|
|
138
|
-
|
|
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(
|
|
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
|
cars/applications/dense_match_filling/cpp/dense_match_filling_cpp.cpython-312-i386-linux-musl.so
CHANGED
|
Binary file
|
|
@@ -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", "
|
|
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
|
-
|
|
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
|
|
Binary file
|
|
@@ -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
|
-
|
|
299
|
+
trans_inv_sensor, sensor_bbox[:, 1], sensor_bbox[:, 0]
|
|
284
300
|
)
|
|
285
301
|
|
|
286
|
-
terrain_bbox = geo_plugin.
|
|
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.
|
|
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
|
-
#
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
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
|
+
}
|
|
Binary file
|