cars 1.0.0a2__cp312-cp312-win_amd64.whl → 1.0.0a4__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.
- cars/__init__.py +3 -3
- cars/applications/__init__.py +0 -3
- cars/applications/application.py +14 -6
- cars/applications/application_template.py +42 -0
- cars/applications/auxiliary_filling/abstract_auxiliary_filling_app.py +12 -2
- cars/applications/auxiliary_filling/auxiliary_filling_algo.py +2 -2
- cars/applications/auxiliary_filling/auxiliary_filling_from_sensors_app.py +95 -46
- 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_algo.py +1 -1
- cars/applications/dem_generation/dem_generation_wrappers.py +44 -59
- cars/applications/dem_generation/dichotomic_generation_app.py +9 -6
- cars/applications/dem_generation/rasterization_app.py +112 -43
- cars/applications/dense_match_filling/__init__.py +1 -1
- cars/applications/dense_match_filling/abstract_dense_match_filling_app.py +2 -15
- cars/applications/dense_match_filling/fill_disp_algo.py +32 -373
- cars/applications/dense_match_filling/fill_disp_wrappers.py +0 -343
- cars/applications/dense_match_filling/zero_padding_app.py +10 -5
- cars/applications/dense_matching/abstract_dense_matching_app.py +2 -1
- cars/applications/dense_matching/census_mccnn_sgm_app.py +48 -60
- cars/applications/dense_matching/cpp/dense_matching_cpp.cp312-win_amd64.dll.a +0 -0
- cars/applications/dense_matching/cpp/dense_matching_cpp.cp312-win_amd64.pyd +0 -0
- cars/applications/dense_matching/dense_matching_algo.py +48 -14
- cars/applications/dense_matching/dense_matching_wrappers.py +11 -3
- cars/applications/dense_matching/disparity_grid_algo.py +95 -79
- 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 +169 -34
- cars/applications/dsm_filling/border_interpolation_app.py +11 -12
- cars/applications/dsm_filling/bulldozer_filling_app.py +16 -15
- cars/applications/dsm_filling/exogenous_filling_app.py +14 -14
- cars/applications/grid_generation/abstract_grid_generation_app.py +1 -1
- cars/applications/grid_generation/epipolar_grid_generation_app.py +4 -2
- cars/applications/grid_generation/grid_correction_app.py +4 -1
- cars/applications/grid_generation/grid_generation_algo.py +7 -2
- cars/applications/ground_truth_reprojection/abstract_ground_truth_reprojection_app.py +1 -1
- cars/applications/ground_truth_reprojection/direct_localization_app.py +2 -2
- cars/applications/ground_truth_reprojection/ground_truth_reprojection_algo.py +2 -1
- cars/applications/point_cloud_fusion/abstract_pc_fusion_app.py +0 -155
- cars/applications/point_cloud_fusion/mapping_to_terrain_tiles_app.py +0 -658
- cars/applications/point_cloud_fusion/pc_fusion_algo.py +0 -1339
- cars/applications/point_cloud_fusion/pc_fusion_wrappers.py +0 -869
- cars/applications/point_cloud_outlier_removal/abstract_outlier_removal_app.py +11 -6
- cars/applications/point_cloud_outlier_removal/outlier_removal_algo.py +9 -8
- cars/applications/point_cloud_outlier_removal/small_components_app.py +101 -270
- cars/applications/point_cloud_outlier_removal/statistical_app.py +120 -277
- cars/applications/rasterization/abstract_pc_rasterization_app.py +2 -1
- cars/applications/rasterization/rasterization_algo.py +18 -6
- cars/applications/rasterization/rasterization_wrappers.py +2 -1
- cars/applications/rasterization/simple_gaussian_app.py +88 -116
- cars/applications/resampling/abstract_resampling_app.py +1 -1
- cars/applications/resampling/bicubic_resampling_app.py +3 -1
- cars/applications/resampling/resampling_algo.py +60 -53
- cars/applications/resampling/resampling_wrappers.py +3 -1
- cars/applications/sparse_matching/abstract_sparse_matching_app.py +1 -1
- cars/applications/sparse_matching/sift_app.py +5 -25
- cars/applications/sparse_matching/sparse_matching_algo.py +3 -2
- cars/applications/sparse_matching/sparse_matching_wrappers.py +1 -1
- cars/applications/triangulation/abstract_triangulation_app.py +1 -1
- cars/applications/triangulation/line_of_sight_intersection_app.py +13 -11
- cars/applications/triangulation/pc_transform.py +552 -0
- cars/applications/triangulation/triangulation_algo.py +6 -4
- cars/applications/triangulation/triangulation_wrappers.py +1 -0
- cars/bundleadjustment.py +6 -6
- cars/cars.py +11 -9
- cars/core/cars_logging.py +80 -49
- cars/core/constants.py +0 -1
- cars/core/datasets.py +5 -2
- cars/core/geometry/abstract_geometry.py +364 -22
- cars/core/geometry/shareloc_geometry.py +112 -82
- cars/core/inputs.py +72 -19
- cars/core/outputs.py +1 -1
- cars/core/preprocessing.py +17 -3
- cars/core/projection.py +126 -6
- cars/core/tiling.py +10 -3
- cars/data_structures/cars_dataset.py +12 -10
- cars/data_structures/corresponding_tiles_tools.py +0 -103
- cars/data_structures/format_transformation.py +4 -1
- cars/devibrate.py +6 -3
- cars/extractroi.py +20 -21
- cars/orchestrator/cluster/abstract_cluster.py +15 -5
- cars/orchestrator/cluster/abstract_dask_cluster.py +6 -2
- cars/orchestrator/cluster/dask_jobqueue_utils.py +1 -1
- cars/orchestrator/cluster/log_wrapper.py +149 -22
- cars/orchestrator/cluster/mp_cluster/multiprocessing_cluster.py +12 -4
- cars/orchestrator/cluster/mp_cluster/multiprocessing_profiler.py +2 -2
- cars/orchestrator/cluster/pbs_dask_cluster.py +1 -1
- cars/orchestrator/cluster/sequential_cluster.py +5 -4
- cars/orchestrator/cluster/slurm_dask_cluster.py +1 -1
- cars/orchestrator/orchestrator.py +15 -4
- cars/orchestrator/registry/id_generator.py +1 -0
- cars/orchestrator/registry/saver_registry.py +2 -2
- cars/pipelines/conf_resolution/conf_final_resolution.json +5 -3
- cars/pipelines/default/default_pipeline.py +461 -1052
- cars/pipelines/parameters/advanced_parameters.py +91 -64
- cars/pipelines/parameters/advanced_parameters_constants.py +6 -5
- cars/pipelines/parameters/application_parameters.py +71 -0
- cars/pipelines/parameters/depth_map_inputs.py +0 -314
- cars/pipelines/parameters/dsm_inputs.py +40 -4
- cars/pipelines/parameters/output_parameters.py +44 -8
- cars/pipelines/parameters/sensor_inputs.py +122 -73
- cars/pipelines/parameters/sensor_inputs_constants.py +0 -2
- cars/pipelines/parameters/sensor_loaders/__init__.py +4 -3
- cars/pipelines/parameters/sensor_loaders/basic_classif_loader.py +106 -0
- cars/pipelines/parameters/sensor_loaders/{basic_sensor_loader.py → basic_image_loader.py} +16 -22
- cars/pipelines/parameters/sensor_loaders/pivot_classif_loader.py +121 -0
- cars/pipelines/parameters/sensor_loaders/{pivot_sensor_loader.py → pivot_image_loader.py} +10 -21
- cars/pipelines/parameters/sensor_loaders/sensor_loader.py +4 -6
- cars/pipelines/parameters/sensor_loaders/sensor_loader_template.py +1 -3
- cars/pipelines/pipeline_template.py +1 -3
- cars/pipelines/unit/unit_pipeline.py +676 -1070
- cars/starter.py +4 -3
- cars-1.0.0a4.dist-info/DELVEWHEEL +2 -0
- {cars-1.0.0a2.dist-info → cars-1.0.0a4.dist-info}/METADATA +135 -53
- {cars-1.0.0a2.dist-info → cars-1.0.0a4.dist-info}/RECORD +120 -134
- cars.libs/libgcc_s_seh-1-b2494fcbd4d80cf2c98fdd5261f6d850.dll +0 -0
- cars.libs/libstdc++-6-e9b0d12ae0e9555bbae55e8dfd08c3f7.dll +0 -0
- cars.libs/libwinpthread-1-7882d1b093714ccdfaf4e0789a817792.dll +0 -0
- cars/applications/dense_match_filling/cpp/__init__.py +0 -0
- cars/applications/dense_match_filling/cpp/dense_match_filling_cpp.cp312-win_amd64.dll.a +0 -0
- cars/applications/dense_match_filling/cpp/dense_match_filling_cpp.cp312-win_amd64.pyd +0 -0
- cars/applications/dense_match_filling/cpp/dense_match_filling_cpp.py +0 -72
- cars/applications/dense_match_filling/cpp/includes/dense_match_filling.hpp +0 -46
- cars/applications/dense_match_filling/cpp/meson.build +0 -9
- cars/applications/dense_match_filling/cpp/src/bindings.cpp +0 -11
- cars/applications/dense_match_filling/cpp/src/dense_match_filling.cpp +0 -142
- cars/applications/dense_match_filling/plane_app.py +0 -556
- cars/applications/hole_detection/__init__.py +0 -30
- cars/applications/hole_detection/abstract_hole_detection_app.py +0 -125
- cars/applications/hole_detection/cloud_to_bbox_app.py +0 -346
- cars/applications/hole_detection/hole_detection_algo.py +0 -144
- cars/applications/hole_detection/hole_detection_wrappers.py +0 -53
- cars/applications/point_cloud_denoising/__init__.py +0 -29
- cars/applications/point_cloud_denoising/abstract_pc_denoising_app.py +0 -273
- cars/applications/point_cloud_fusion/__init__.py +0 -30
- cars/applications/point_cloud_fusion/cloud_fusion_constants.py +0 -39
- cars/applications/sparse_matching/pandora_sparse_matching_app.py +0 -0
- cars/pipelines/parameters/depth_map_inputs_constants.py +0 -25
- cars-1.0.0a2.dist-info/DELVEWHEEL +0 -2
- cars.libs/libgcc_s_seh-1-f2b6825d483bdf14050493af93b5997d.dll +0 -0
- cars.libs/libstdc++-6-6b0059df6bc601df5a0f18a5805eea05.dll +0 -0
- cars.libs/libwinpthread-1-e01b8e85fd67c2b861f64d4ccc7df607.dll +0 -0
- {cars-1.0.0a2.dist-info → cars-1.0.0a4.dist-info}/WHEEL +0 -0
- {cars-1.0.0a2.dist-info → cars-1.0.0a4.dist-info}/entry_points.txt +0 -0
|
@@ -26,7 +26,6 @@ import logging
|
|
|
26
26
|
import os
|
|
27
27
|
|
|
28
28
|
import numpy as np
|
|
29
|
-
import pyproj
|
|
30
29
|
import rasterio as rio
|
|
31
30
|
import xdem
|
|
32
31
|
|
|
@@ -37,8 +36,6 @@ from rasterio.enums import Resampling
|
|
|
37
36
|
from rasterio.warp import calculate_default_transform, reproject
|
|
38
37
|
from scipy.ndimage import median_filter
|
|
39
38
|
|
|
40
|
-
from cars.core import preprocessing
|
|
41
|
-
|
|
42
39
|
|
|
43
40
|
def fit_initial_elevation_on_dem_median(
|
|
44
41
|
dem_to_fit_path: str, dem_ref_path: str, dem_out_path: str
|
|
@@ -136,7 +133,7 @@ def add_margin(bbox, ratio=1):
|
|
|
136
133
|
return new_bbox
|
|
137
134
|
|
|
138
135
|
|
|
139
|
-
def generate_grid(
|
|
136
|
+
def generate_grid( # pylint: disable=too-many-positional-arguments
|
|
140
137
|
pd_pc, resolution, xmin=None, xmax=None, ymin=None, ymax=None
|
|
141
138
|
):
|
|
142
139
|
"""
|
|
@@ -244,7 +241,13 @@ def reverse_dem(input_dem):
|
|
|
244
241
|
out_dem.nodata = -nodata
|
|
245
242
|
|
|
246
243
|
|
|
247
|
-
def downsample_dem(
|
|
244
|
+
def downsample_dem(
|
|
245
|
+
input_dem,
|
|
246
|
+
scale,
|
|
247
|
+
interpolator,
|
|
248
|
+
median_filter_size=None,
|
|
249
|
+
default_alt=0,
|
|
250
|
+
):
|
|
248
251
|
"""
|
|
249
252
|
Downsample median DEM with median resampling
|
|
250
253
|
|
|
@@ -266,85 +269,67 @@ def downsample_dem(input_dem, scale, median_filter_size=7):
|
|
|
266
269
|
metadata["transform"] = dst_transform
|
|
267
270
|
metadata["height"] = dst_height
|
|
268
271
|
metadata["width"] = dst_width
|
|
269
|
-
|
|
272
|
+
dem_data = np.zeros((dst_height, dst_width))
|
|
273
|
+
interpolator_dict = {
|
|
274
|
+
"min": Resampling.min,
|
|
275
|
+
"median": Resampling.med,
|
|
276
|
+
"max": Resampling.max,
|
|
277
|
+
"nearest": Resampling.nearest,
|
|
278
|
+
}
|
|
279
|
+
interpolator = interpolator_dict[interpolator]
|
|
270
280
|
reproject(
|
|
271
281
|
data,
|
|
272
|
-
|
|
282
|
+
dem_data,
|
|
273
283
|
src_transform=src_transform,
|
|
274
284
|
src_crs=crs,
|
|
275
285
|
dst_transform=dst_transform,
|
|
276
286
|
dst_crs=crs,
|
|
277
287
|
dst_nodata=nodata,
|
|
278
|
-
resampling=
|
|
288
|
+
resampling=interpolator,
|
|
289
|
+
)
|
|
290
|
+
|
|
291
|
+
# Post-processing
|
|
292
|
+
|
|
293
|
+
# Median filter
|
|
294
|
+
if median_filter_size is not None:
|
|
295
|
+
dem_data = median_filter(dem_data, size=median_filter_size)
|
|
296
|
+
|
|
297
|
+
# Fill nodata
|
|
298
|
+
dem_data = rio.fill.fillnodata(
|
|
299
|
+
dem_data,
|
|
300
|
+
mask=~(dem_data == nodata),
|
|
279
301
|
)
|
|
280
302
|
|
|
281
|
-
|
|
282
|
-
output = median_filter(output, size=median_filter_size)
|
|
303
|
+
dem_data[dem_data == nodata] = default_alt
|
|
283
304
|
|
|
284
305
|
with rio.open(input_dem, "w", **metadata) as dst:
|
|
285
|
-
dst.write(
|
|
306
|
+
dst.write(dem_data, 1)
|
|
286
307
|
|
|
287
308
|
|
|
288
|
-
def modify_terrain_bounds(
|
|
309
|
+
def modify_terrain_bounds(terrain_bounds, linear_margin, constant_margin):
|
|
289
310
|
"""
|
|
290
311
|
Modify the terrain bounds
|
|
291
312
|
|
|
292
|
-
:param
|
|
293
|
-
:type
|
|
294
|
-
:param
|
|
295
|
-
:type epsg: int
|
|
296
|
-
:param margin: the margin
|
|
313
|
+
:param terrain_bounds: Input region of interest for DEM
|
|
314
|
+
:type terrain_bounds: list
|
|
315
|
+
:param margin: Margin of the output ROI in meters
|
|
297
316
|
:type margin: int
|
|
298
317
|
"""
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
xmin =
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
ymax =
|
|
305
|
-
|
|
306
|
-
bounds_cloud = [xmin, ymin, xmax, ymax]
|
|
307
|
-
|
|
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
|
|
314
|
-
|
|
315
|
-
# 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
|
|
318
|
+
xsize = terrain_bounds[2] - terrain_bounds[0]
|
|
319
|
+
ysize = terrain_bounds[3] - terrain_bounds[1]
|
|
320
|
+
xmin = terrain_bounds[0] - linear_margin * xsize - constant_margin
|
|
321
|
+
ymin = terrain_bounds[1] - linear_margin * ysize - constant_margin
|
|
322
|
+
xmax = terrain_bounds[2] + linear_margin * xsize + constant_margin
|
|
323
|
+
ymax = terrain_bounds[3] + linear_margin * ysize + constant_margin
|
|
320
324
|
|
|
321
325
|
terrain_bounds = [xmin, ymin, xmax, ymax]
|
|
322
326
|
|
|
323
|
-
|
|
324
|
-
crs_in = pyproj.CRS.from_epsg(4326)
|
|
325
|
-
crs_out = pyproj.CRS.from_epsg(epsg)
|
|
326
|
-
|
|
327
|
-
transformer = pyproj.Transformer.from_crs(
|
|
328
|
-
crs_in, crs_out, always_xy=True
|
|
329
|
-
)
|
|
330
|
-
|
|
331
|
-
xymin = transformer.transform(terrain_bounds[0], terrain_bounds[1])
|
|
332
|
-
xymax = transformer.transform(terrain_bounds[2], terrain_bounds[3])
|
|
333
|
-
|
|
334
|
-
xmin, ymin = xymin if isinstance(xymin, tuple) else (None, None)
|
|
335
|
-
xmax, ymax = xymax if isinstance(xymax, tuple) else (None, None)
|
|
336
|
-
|
|
337
|
-
if None in (xmin, ymin, xmax, ymax):
|
|
338
|
-
raise RuntimeError("An error occured during the projection")
|
|
339
|
-
|
|
340
|
-
new_terrain_bounds = [xmin, ymin, xmax, ymax]
|
|
341
|
-
|
|
342
|
-
return new_terrain_bounds
|
|
327
|
+
return terrain_bounds
|
|
343
328
|
|
|
344
329
|
|
|
345
330
|
def reproject_dem(dsm_file_name, epsg_out, out_file_name):
|
|
346
331
|
"""
|
|
347
|
-
Reproject the
|
|
332
|
+
Reproject the DEM
|
|
348
333
|
|
|
349
334
|
:param dsm_file_name: the path to dsm
|
|
350
335
|
: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"]
|
|
@@ -127,7 +129,7 @@ class DichotomicGeneration(DemGeneration, short_name="dichotomic"):
|
|
|
127
129
|
overloaded_conf["resolution"] = conf.get("resolution", 90)
|
|
128
130
|
# default margin: (z max - zmin) * tan(teta)
|
|
129
131
|
# with z max = 9000, z min = 0, teta = 30 degrees
|
|
130
|
-
overloaded_conf["margin"] = conf.get("margin", 6000)
|
|
132
|
+
overloaded_conf["margin"] = conf.get("margin", [0, 6000])
|
|
131
133
|
overloaded_conf["height_margin"] = conf.get("height_margin", 20)
|
|
132
134
|
overloaded_conf["percentile"] = conf.get("percentile", 1)
|
|
133
135
|
overloaded_conf["min_number_matches"] = conf.get(
|
|
@@ -152,7 +154,7 @@ class DichotomicGeneration(DemGeneration, short_name="dichotomic"):
|
|
|
152
154
|
rectification_schema = {
|
|
153
155
|
"method": str,
|
|
154
156
|
"resolution": And(Or(float, int), lambda x: x > 0),
|
|
155
|
-
"margin":
|
|
157
|
+
"margin": [Or(float, int)],
|
|
156
158
|
"height_margin": Or(list, int),
|
|
157
159
|
"percentile": And(Or(int, float), lambda x: x >= 0),
|
|
158
160
|
"min_number_matches": And(int, lambda x: x > 0),
|
|
@@ -171,7 +173,7 @@ class DichotomicGeneration(DemGeneration, short_name="dichotomic"):
|
|
|
171
173
|
return overloaded_conf
|
|
172
174
|
|
|
173
175
|
@cars_profile(name="DEM Generation")
|
|
174
|
-
def run(
|
|
176
|
+
def run( # pylint: disable=too-many-positional-arguments
|
|
175
177
|
self,
|
|
176
178
|
triangulated_matches_list,
|
|
177
179
|
output_dir,
|
|
@@ -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
|
|
|
@@ -23,6 +23,7 @@ this module contains the dichotomic dem generation application class.
|
|
|
23
23
|
"""
|
|
24
24
|
# Standard library
|
|
25
25
|
import logging
|
|
26
|
+
import math
|
|
26
27
|
import os
|
|
27
28
|
import shutil
|
|
28
29
|
|
|
@@ -63,14 +64,16 @@ class Rasterization(DemGeneration, short_name="bulldozer_on_raster"):
|
|
|
63
64
|
|
|
64
65
|
# pylint: disable=too-many-instance-attributes
|
|
65
66
|
|
|
66
|
-
def __init__(self, conf=None):
|
|
67
|
+
def __init__(self, scaling_coeff, conf=None):
|
|
67
68
|
"""
|
|
68
69
|
Init function of Rasterization
|
|
69
70
|
|
|
71
|
+
:param scaling_coeff: scaling factor for resolution
|
|
72
|
+
:type scaling_coeff: float
|
|
70
73
|
:param conf: configuration for Rasterization
|
|
71
74
|
:return: an application_to_use object
|
|
72
75
|
"""
|
|
73
|
-
super().__init__(conf=conf)
|
|
76
|
+
super().__init__(scaling_coeff, conf=conf)
|
|
74
77
|
|
|
75
78
|
# check conf
|
|
76
79
|
self.used_method = self.used_config["method"]
|
|
@@ -92,9 +95,8 @@ class Rasterization(DemGeneration, short_name="bulldozer_on_raster"):
|
|
|
92
95
|
self.postprocessing_median_filter_size = self.used_config[
|
|
93
96
|
"postprocessing_median_filter_size"
|
|
94
97
|
]
|
|
95
|
-
self.
|
|
96
|
-
|
|
97
|
-
]
|
|
98
|
+
self.dem_median_downscale = self.used_config["dem_median_downscale"]
|
|
99
|
+
self.dem_min_max_downscale = self.used_config["dem_min_max_downscale"]
|
|
98
100
|
self.fillnodata_max_search_distance = self.used_config[
|
|
99
101
|
"fillnodata_max_search_distance"
|
|
100
102
|
]
|
|
@@ -103,6 +105,7 @@ class Rasterization(DemGeneration, short_name="bulldozer_on_raster"):
|
|
|
103
105
|
self.bulldozer_max_object_size = self.used_config[
|
|
104
106
|
"bulldozer_max_object_size"
|
|
105
107
|
]
|
|
108
|
+
self.disable_bulldozer = self.used_config["disable_bulldozer"]
|
|
106
109
|
self.compute_stats = self.used_config["compute_stats"]
|
|
107
110
|
self.coregistration = self.used_config["coregistration"]
|
|
108
111
|
self.coregistration_max_shift = self.used_config[
|
|
@@ -134,8 +137,12 @@ class Rasterization(DemGeneration, short_name="bulldozer_on_raster"):
|
|
|
134
137
|
|
|
135
138
|
# Overload conf
|
|
136
139
|
overloaded_conf["method"] = conf.get("method", "bulldozer_on_raster")
|
|
137
|
-
overloaded_conf["resolution"] = conf.get(
|
|
138
|
-
|
|
140
|
+
overloaded_conf["resolution"] = conf.get(
|
|
141
|
+
"resolution", float(self.scaling_coeff * 0.5)
|
|
142
|
+
)
|
|
143
|
+
overloaded_conf["margin"] = conf.get(
|
|
144
|
+
"margin", [0.1, float(math.sqrt(self.scaling_coeff) * 500)]
|
|
145
|
+
)
|
|
139
146
|
overloaded_conf["morphological_filters_size"] = conf.get(
|
|
140
147
|
"morphological_filters_size", 30
|
|
141
148
|
)
|
|
@@ -145,18 +152,26 @@ class Rasterization(DemGeneration, short_name="bulldozer_on_raster"):
|
|
|
145
152
|
overloaded_conf["postprocessing_median_filter_size"] = conf.get(
|
|
146
153
|
"postprocessing_median_filter_size", 7
|
|
147
154
|
)
|
|
148
|
-
overloaded_conf["
|
|
149
|
-
"
|
|
155
|
+
overloaded_conf["dem_median_downscale"] = conf.get(
|
|
156
|
+
"dem_median_downscale", 10
|
|
157
|
+
)
|
|
158
|
+
overloaded_conf["dem_min_max_downscale"] = conf.get(
|
|
159
|
+
"dem_min_max_downscale", 2
|
|
150
160
|
)
|
|
151
161
|
overloaded_conf["fillnodata_max_search_distance"] = conf.get(
|
|
152
162
|
"fillnodata_max_search_distance", 50
|
|
153
163
|
)
|
|
154
164
|
overloaded_conf["min_dem"] = conf.get("min_dem", -500)
|
|
155
165
|
overloaded_conf["max_dem"] = conf.get("max_dem", 1000)
|
|
156
|
-
overloaded_conf["height_margin"] = conf.get(
|
|
166
|
+
overloaded_conf["height_margin"] = conf.get(
|
|
167
|
+
"height_margin", float(math.sqrt(self.scaling_coeff) * 20)
|
|
168
|
+
)
|
|
157
169
|
overloaded_conf["bulldozer_max_object_size"] = conf.get(
|
|
158
170
|
"bulldozer_max_object_size", 8
|
|
159
171
|
)
|
|
172
|
+
overloaded_conf["disable_bulldozer"] = conf.get(
|
|
173
|
+
"disable_bulldozer", False
|
|
174
|
+
)
|
|
160
175
|
overloaded_conf["compute_stats"] = conf.get("compute_stats", True)
|
|
161
176
|
overloaded_conf["coregistration"] = conf.get("coregistration", True)
|
|
162
177
|
overloaded_conf["coregistration_max_shift"] = conf.get(
|
|
@@ -170,16 +185,18 @@ class Rasterization(DemGeneration, short_name="bulldozer_on_raster"):
|
|
|
170
185
|
"method": str,
|
|
171
186
|
"resolution": And(Or(float, int), lambda x: x > 0),
|
|
172
187
|
application_constants.SAVE_INTERMEDIATE_DATA: bool,
|
|
173
|
-
"margin":
|
|
188
|
+
"margin": [Or(float, int)],
|
|
174
189
|
"morphological_filters_size": And(int, lambda x: x > 0),
|
|
175
190
|
"preprocessing_median_filter_size": And(int, lambda x: x > 0),
|
|
176
191
|
"postprocessing_median_filter_size": And(int, lambda x: x > 0),
|
|
177
|
-
"
|
|
192
|
+
"dem_median_downscale": And(int, lambda x: x > 0),
|
|
193
|
+
"dem_min_max_downscale": And(int, lambda x: x > 0),
|
|
178
194
|
"fillnodata_max_search_distance": And(int, lambda x: x > 0),
|
|
179
195
|
"min_dem": And(Or(int, float), lambda x: x < 0),
|
|
180
196
|
"max_dem": And(Or(int, float), lambda x: x > 0),
|
|
181
197
|
"height_margin": Or(list, float, int),
|
|
182
198
|
"bulldozer_max_object_size": And(int, lambda x: x > 0),
|
|
199
|
+
"disable_bulldozer": bool,
|
|
183
200
|
"compute_stats": bool,
|
|
184
201
|
"coregistration": bool,
|
|
185
202
|
"coregistration_max_shift": And(Or(int, float), lambda x: x > 0),
|
|
@@ -193,7 +210,7 @@ class Rasterization(DemGeneration, short_name="bulldozer_on_raster"):
|
|
|
193
210
|
return overloaded_conf
|
|
194
211
|
|
|
195
212
|
@cars_profile(name="DEM Generation")
|
|
196
|
-
def run(
|
|
213
|
+
def run( # pylint: disable=too-many-positional-arguments # noqa: C901
|
|
197
214
|
self,
|
|
198
215
|
dsm_file_name,
|
|
199
216
|
output_dir,
|
|
@@ -203,6 +220,7 @@ class Rasterization(DemGeneration, short_name="bulldozer_on_raster"):
|
|
|
203
220
|
input_geoid,
|
|
204
221
|
output_geoid,
|
|
205
222
|
initial_elevation=None,
|
|
223
|
+
default_alt=0,
|
|
206
224
|
cars_orchestrator=None,
|
|
207
225
|
):
|
|
208
226
|
"""
|
|
@@ -389,14 +407,17 @@ class Rasterization(DemGeneration, short_name="bulldozer_on_raster"):
|
|
|
389
407
|
out_dem.write(dem_median, 1)
|
|
390
408
|
with rio.open(dem_max_path, "w", **profile) as out_dem:
|
|
391
409
|
out_dem.write(dem_max, 1)
|
|
410
|
+
dem_filled_path = os.path.join(output_dir, "dem_filled.tif")
|
|
411
|
+
with rio.open(dem_filled_path, "w", **profile) as out_dem:
|
|
412
|
+
out_dem.write(dem_data, 1)
|
|
392
413
|
|
|
393
414
|
if self.save_intermediate_data:
|
|
394
415
|
intermediate_dem_min_path = os.path.join(
|
|
395
|
-
output_dir, "
|
|
416
|
+
output_dir, "dem_min_before_downsampling.tif"
|
|
396
417
|
)
|
|
397
418
|
shutil.copy2(dem_min_path, intermediate_dem_min_path)
|
|
398
419
|
intermediate_dem_max_path = os.path.join(
|
|
399
|
-
output_dir, "
|
|
420
|
+
output_dir, "dem_max_before_downsampling.tif"
|
|
400
421
|
)
|
|
401
422
|
shutil.copy2(dem_max_path, intermediate_dem_max_path)
|
|
402
423
|
|
|
@@ -405,44 +426,79 @@ class Rasterization(DemGeneration, short_name="bulldozer_on_raster"):
|
|
|
405
426
|
)
|
|
406
427
|
shutil.copy2(dem_median_path_out, intermediate_dem_median_path)
|
|
407
428
|
|
|
408
|
-
# Downsample
|
|
429
|
+
# Downsample dems
|
|
409
430
|
downsample_dem(
|
|
410
431
|
dem_median_path_out,
|
|
411
|
-
scale=self.
|
|
432
|
+
scale=self.dem_median_downscale,
|
|
433
|
+
interpolator="median",
|
|
412
434
|
median_filter_size=self.postprocessing_median_filter_size,
|
|
435
|
+
default_alt=default_alt,
|
|
413
436
|
)
|
|
414
437
|
|
|
415
|
-
|
|
416
|
-
saved_transform = edit_transform(
|
|
417
|
-
dem_min_path, resolution=resolution_in_meters
|
|
418
|
-
)
|
|
419
|
-
logging.info("Launch Bulldozer on DEM min")
|
|
420
|
-
temp_output_path = launch_bulldozer(
|
|
438
|
+
downsample_dem(
|
|
421
439
|
dem_min_path,
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
440
|
+
scale=self.dem_min_max_downscale,
|
|
441
|
+
interpolator="min",
|
|
442
|
+
default_alt=default_alt,
|
|
425
443
|
)
|
|
426
|
-
if temp_output_path is not None:
|
|
427
|
-
shutil.copy2(temp_output_path, dem_min_path)
|
|
428
|
-
edit_transform(dem_min_path, transform=saved_transform)
|
|
429
444
|
|
|
430
|
-
|
|
431
|
-
saved_transform = edit_transform(
|
|
432
|
-
dem_max_path, resolution=resolution_in_meters
|
|
433
|
-
)
|
|
434
|
-
reverse_dem(dem_max_path)
|
|
435
|
-
logging.info("Launch Bulldozer on DEM max")
|
|
436
|
-
temp_output_path = launch_bulldozer(
|
|
445
|
+
downsample_dem(
|
|
437
446
|
dem_max_path,
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
447
|
+
scale=self.dem_min_max_downscale,
|
|
448
|
+
interpolator="max",
|
|
449
|
+
default_alt=default_alt,
|
|
441
450
|
)
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
451
|
+
|
|
452
|
+
downsample_dem(
|
|
453
|
+
dem_filled_path,
|
|
454
|
+
scale=self.dem_min_max_downscale,
|
|
455
|
+
interpolator="nearest",
|
|
456
|
+
default_alt=default_alt,
|
|
457
|
+
)
|
|
458
|
+
|
|
459
|
+
if self.save_intermediate_data:
|
|
460
|
+
intermediate_dem_min_path = os.path.join(
|
|
461
|
+
output_dir, "dem_min_before_bulldozer.tif"
|
|
462
|
+
)
|
|
463
|
+
shutil.copy2(dem_min_path, intermediate_dem_min_path)
|
|
464
|
+
intermediate_dem_max_path = os.path.join(
|
|
465
|
+
output_dir, "dem_max_before_bulldozer.tif"
|
|
466
|
+
)
|
|
467
|
+
shutil.copy2(dem_max_path, intermediate_dem_max_path)
|
|
468
|
+
|
|
469
|
+
if not self.disable_bulldozer:
|
|
470
|
+
dem_min_max_res = resolution_in_meters * self.dem_min_max_downscale
|
|
471
|
+
# Launch Bulldozer on dem min
|
|
472
|
+
saved_transform = edit_transform(
|
|
473
|
+
dem_min_path, resolution=dem_min_max_res
|
|
474
|
+
)
|
|
475
|
+
logging.info("Launch Bulldozer on DEM min")
|
|
476
|
+
temp_output_path = launch_bulldozer(
|
|
477
|
+
dem_min_path,
|
|
478
|
+
os.path.join(output_dir, "dem_min_bulldozer"),
|
|
479
|
+
cars_orchestrator,
|
|
480
|
+
self.bulldozer_max_object_size,
|
|
481
|
+
)
|
|
482
|
+
if temp_output_path is not None:
|
|
483
|
+
shutil.copy2(temp_output_path, dem_min_path)
|
|
484
|
+
edit_transform(dem_min_path, transform=saved_transform)
|
|
485
|
+
|
|
486
|
+
# Inverse dem max and launch bulldozer
|
|
487
|
+
saved_transform = edit_transform(
|
|
488
|
+
dem_max_path, resolution=dem_min_max_res
|
|
489
|
+
)
|
|
490
|
+
reverse_dem(dem_max_path)
|
|
491
|
+
logging.info("Launch Bulldozer on DEM max")
|
|
492
|
+
temp_output_path = launch_bulldozer(
|
|
493
|
+
dem_max_path,
|
|
494
|
+
os.path.join(output_dir, "dem_max_bulldozer"),
|
|
495
|
+
cars_orchestrator,
|
|
496
|
+
self.bulldozer_max_object_size,
|
|
497
|
+
)
|
|
498
|
+
if temp_output_path is not None:
|
|
499
|
+
shutil.copy2(temp_output_path, dem_max_path)
|
|
500
|
+
reverse_dem(dem_max_path)
|
|
501
|
+
edit_transform(dem_max_path, transform=saved_transform)
|
|
446
502
|
|
|
447
503
|
# Check DEM min and max
|
|
448
504
|
with rio.open(dem_min_path, "r") as in_dem:
|
|
@@ -452,11 +508,14 @@ class Rasterization(DemGeneration, short_name="bulldozer_on_raster"):
|
|
|
452
508
|
with rio.open(dem_max_path, "r") as in_dem:
|
|
453
509
|
dem_max = in_dem.read()
|
|
454
510
|
dem_max_metadata = in_dem.meta
|
|
511
|
+
with rio.open(dem_filled_path, "r") as in_dem:
|
|
512
|
+
dem_data = in_dem.read()
|
|
455
513
|
dem_data[dem_data == nodata] = np.nan
|
|
456
514
|
dem_min[dem_min == nodata] = np.nan
|
|
457
515
|
dem_max[dem_max == nodata] = np.nan
|
|
458
516
|
if self.compute_stats:
|
|
459
517
|
diff = dem_data - dem_min
|
|
518
|
+
diff = diff[dem_data != 0]
|
|
460
519
|
logging.info(
|
|
461
520
|
"Statistics of difference between subsampled "
|
|
462
521
|
"DSM and DEM min (in meters)"
|
|
@@ -464,6 +523,7 @@ class Rasterization(DemGeneration, short_name="bulldozer_on_raster"):
|
|
|
464
523
|
compute_stats(diff)
|
|
465
524
|
|
|
466
525
|
diff = dem_max - dem_data
|
|
526
|
+
diff = diff[dem_data != 0]
|
|
467
527
|
logging.info(
|
|
468
528
|
"Statistics of difference between DEM max "
|
|
469
529
|
"and subsampled DSM (in meters)"
|
|
@@ -471,6 +531,7 @@ class Rasterization(DemGeneration, short_name="bulldozer_on_raster"):
|
|
|
471
531
|
compute_stats(diff)
|
|
472
532
|
|
|
473
533
|
diff = dem_max - dem_min
|
|
534
|
+
diff = diff[dem_data != 0]
|
|
474
535
|
logging.info(
|
|
475
536
|
"Statistics of difference between DEM max "
|
|
476
537
|
"and DEM min (in meters)"
|
|
@@ -490,6 +551,14 @@ class Rasterization(DemGeneration, short_name="bulldozer_on_raster"):
|
|
|
490
551
|
dem_max,
|
|
491
552
|
)
|
|
492
553
|
|
|
554
|
+
# Rectify pixels where DEM min > DEM max - margin, to ensure that
|
|
555
|
+
# DEM min < DEM max even on filled pixels
|
|
556
|
+
dem_min = np.where(
|
|
557
|
+
dem_min > dem_max - self.min_height_margin,
|
|
558
|
+
dem_max - self.min_height_margin,
|
|
559
|
+
dem_min,
|
|
560
|
+
)
|
|
561
|
+
|
|
493
562
|
with rio.open(dem_min_path, "w", **dem_min_metadata) as out_dem:
|
|
494
563
|
out_dem.write(dem_min)
|
|
495
564
|
with rio.open(dem_max_path, "w", **dem_max_metadata) as out_dem:
|
|
@@ -123,23 +123,10 @@ class DenseMatchFilling(ApplicationTemplate, metaclass=ABCMeta):
|
|
|
123
123
|
**kwargs,
|
|
124
124
|
):
|
|
125
125
|
"""
|
|
126
|
-
Run
|
|
126
|
+
Run filling application.
|
|
127
127
|
|
|
128
128
|
:param epipolar_disparity_map: left disparity
|
|
129
129
|
:type epipolar_disparity_map: CarsDataset
|
|
130
|
-
:param holes_bbox_left: left holes
|
|
131
|
-
:type holes_bbox_left: CarsDataset
|
|
132
|
-
:param holes_bbox_right: right holes
|
|
133
|
-
:type holes_bbox_right: CarsDataset
|
|
134
|
-
:param disp_min: minimum disparity
|
|
135
|
-
:type disp_min: int
|
|
136
|
-
:param disp_max: maximum disparity
|
|
137
|
-
:type disp_max: int
|
|
138
|
-
:param orchestrator: orchestrator used
|
|
139
|
-
:param pair_folder: folder used for current pair
|
|
140
|
-
:type pair_folder: str
|
|
141
|
-
:param pair_key: pair id
|
|
142
|
-
:type pair_key: str
|
|
143
130
|
|
|
144
131
|
:return: filled disparity map: \
|
|
145
132
|
The CarsDataset contains:
|
|
@@ -156,7 +143,7 @@ class DenseMatchFilling(ApplicationTemplate, metaclass=ABCMeta):
|
|
|
156
143
|
|
|
157
144
|
"""
|
|
158
145
|
|
|
159
|
-
def __register_dataset__(
|
|
146
|
+
def __register_dataset__( # pylint: disable=too-many-positional-arguments
|
|
160
147
|
self,
|
|
161
148
|
epipolar_disparity_map,
|
|
162
149
|
save_intermediate_data,
|