cars 1.0.0a1__cp313-cp313-win_amd64.whl → 1.0.0a3__cp313-cp313-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 +4 -4
- 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 +48 -25
- cars/applications/dem_generation/dichotomic_generation_app.py +27 -9
- cars/applications/dem_generation/rasterization_app.py +85 -32
- cars/applications/dense_match_filling/abstract_dense_match_filling_app.py +4 -0
- cars/applications/dense_match_filling/cpp/dense_match_filling_cpp.cp313-win_amd64.dll.a +0 -0
- cars/applications/dense_match_filling/cpp/dense_match_filling_cpp.cp313-win_amd64.pyd +0 -0
- cars/applications/dense_match_filling/fill_disp_algo.py +41 -12
- cars/applications/dense_match_filling/plane_app.py +11 -0
- cars/applications/dense_match_filling/zero_padding_app.py +11 -1
- cars/applications/dense_matching/census_mccnn_sgm_app.py +254 -548
- cars/applications/dense_matching/cpp/dense_matching_cpp.cp313-win_amd64.dll.a +0 -0
- cars/applications/dense_matching/cpp/dense_matching_cpp.cp313-win_amd64.pyd +0 -0
- cars/applications/dense_matching/dense_matching_algo.py +59 -11
- cars/applications/dense_matching/dense_matching_wrappers.py +51 -31
- cars/applications/dense_matching/disparity_grid_algo.py +566 -0
- 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/grid_generation/grid_correction_app.py +0 -53
- cars/applications/grid_generation/transform_grid.py +5 -5
- cars/applications/point_cloud_fusion/pc_fusion_algo.py +17 -11
- cars/applications/point_cloud_fusion/pc_fusion_wrappers.py +3 -4
- 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/rasterization_algo.py +20 -27
- cars/applications/rasterization/rasterization_wrappers.py +6 -5
- cars/applications/rasterization/simple_gaussian_app.py +30 -17
- cars/applications/resampling/resampling_algo.py +44 -49
- cars/applications/sparse_matching/sift_app.py +2 -22
- cars/applications/sparse_matching/sparse_matching_wrappers.py +0 -49
- cars/applications/triangulation/line_of_sight_intersection_app.py +1 -1
- cars/applications/triangulation/triangulation_wrappers.py +2 -1
- cars/bundleadjustment.py +51 -11
- cars/cars.py +15 -5
- cars/core/constants.py +1 -1
- cars/core/geometry/abstract_geometry.py +166 -12
- cars/core/geometry/shareloc_geometry.py +61 -14
- 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/orchestrator/registry/saver_registry.py +0 -78
- cars/pipelines/default/default_pipeline.py +69 -52
- cars/pipelines/parameters/advanced_parameters.py +17 -0
- cars/pipelines/parameters/advanced_parameters_constants.py +4 -0
- cars/pipelines/parameters/depth_map_inputs.py +22 -67
- cars/pipelines/parameters/dsm_inputs.py +16 -29
- cars/pipelines/parameters/output_parameters.py +44 -8
- cars/pipelines/parameters/sensor_inputs.py +117 -24
- cars/pipelines/parameters/sensor_loaders/basic_sensor_loader.py +3 -3
- cars/pipelines/parameters/sensor_loaders/pivot_sensor_loader.py +2 -2
- cars/pipelines/parameters/sensor_loaders/sensor_loader.py +4 -6
- cars/pipelines/parameters/sensor_loaders/sensor_loader_template.py +2 -2
- cars/pipelines/pipeline.py +8 -8
- cars/pipelines/unit/unit_pipeline.py +276 -274
- cars/starter.py +20 -1
- cars-1.0.0a3.dist-info/DELVEWHEEL +2 -0
- {cars-1.0.0a1.dist-info → cars-1.0.0a3.dist-info}/METADATA +3 -2
- {cars-1.0.0a1.dist-info → cars-1.0.0a3.dist-info}/RECORD +77 -74
- cars.libs/libgcc_s_seh-1-ca70890bbc5723b6d0ea31e9c9cded2b.dll +0 -0
- cars.libs/libstdc++-6-00ee19f73d5122a1277c137b1c218401.dll +0 -0
- cars.libs/libwinpthread-1-f5042e8e3d21edce20c1bc99445f551b.dll +0 -0
- cars-1.0.0a1.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.0a1.dist-info → cars-1.0.0a3.dist-info}/WHEEL +0 -0
- {cars-1.0.0a1.dist-info → cars-1.0.0a3.dist-info}/entry_points.txt +0 -0
|
@@ -26,25 +26,21 @@ import collections
|
|
|
26
26
|
|
|
27
27
|
# Standard imports
|
|
28
28
|
import copy
|
|
29
|
-
import itertools
|
|
30
29
|
import logging
|
|
31
30
|
import math
|
|
32
31
|
import os
|
|
33
32
|
from typing import Dict, Tuple
|
|
34
33
|
|
|
35
34
|
# Third party imports
|
|
36
|
-
import affine
|
|
37
35
|
import numpy as np
|
|
38
|
-
import pandas
|
|
39
36
|
import pandora
|
|
40
|
-
import rasterio
|
|
41
37
|
import xarray as xr
|
|
42
|
-
from affine import Affine
|
|
43
38
|
from json_checker import And, Checker, Or
|
|
44
39
|
from pandora.check_configuration import check_pipeline_section
|
|
45
40
|
from pandora.img_tools import add_global_disparity
|
|
46
41
|
from pandora.state_machine import PandoraMachine
|
|
47
|
-
from
|
|
42
|
+
from rasterio.profiles import DefaultGTiffProfile
|
|
43
|
+
from scipy.ndimage import maximum_filter, minimum_filter
|
|
48
44
|
|
|
49
45
|
import cars.applications.dense_matching.dense_matching_constants as dm_cst
|
|
50
46
|
import cars.orchestrator.orchestrator as ocht
|
|
@@ -56,8 +52,9 @@ from cars.applications.dense_matching import (
|
|
|
56
52
|
from cars.applications.dense_matching.abstract_dense_matching_app import (
|
|
57
53
|
DenseMatching,
|
|
58
54
|
)
|
|
59
|
-
from cars.applications.dense_matching.
|
|
60
|
-
|
|
55
|
+
from cars.applications.dense_matching.disparity_grid_algo import (
|
|
56
|
+
generate_disp_range_const_tile_wrapper,
|
|
57
|
+
generate_disp_range_from_dem_wrapper,
|
|
61
58
|
)
|
|
62
59
|
from cars.applications.dense_matching.loaders.pandora_loader import (
|
|
63
60
|
PandoraLoader,
|
|
@@ -66,8 +63,7 @@ from cars.applications.dense_matching.loaders.pandora_loader import (
|
|
|
66
63
|
# CARS imports
|
|
67
64
|
from cars.core import constants as cst
|
|
68
65
|
from cars.core import constants_disparity as cst_disp
|
|
69
|
-
from cars.core import inputs,
|
|
70
|
-
from cars.core.projection import point_cloud_conversion
|
|
66
|
+
from cars.core import inputs, tiling
|
|
71
67
|
from cars.core.utils import safe_makedirs
|
|
72
68
|
from cars.data_structures import cars_dataset, format_transformation
|
|
73
69
|
from cars.orchestrator.cluster.log_wrapper import cars_profile
|
|
@@ -82,6 +78,7 @@ class CensusMccnnSgm(
|
|
|
82
78
|
"census_sgm_mountain_and_vegetation",
|
|
83
79
|
"census_sgm_homogeneous",
|
|
84
80
|
"mccnn_sgm",
|
|
81
|
+
"auto",
|
|
85
82
|
],
|
|
86
83
|
): # pylint: disable=R0903,disable=R0902
|
|
87
84
|
"""
|
|
@@ -126,6 +123,9 @@ class CensusMccnnSgm(
|
|
|
126
123
|
self.disp_range_propagation_filter_size = self.used_config[
|
|
127
124
|
"disp_range_propagation_filter_size"
|
|
128
125
|
]
|
|
126
|
+
self.epi_disp_grid_tile_size = self.used_config[
|
|
127
|
+
"epi_disp_grid_tile_size"
|
|
128
|
+
]
|
|
129
129
|
self.use_cross_validation = self.used_config["use_cross_validation"]
|
|
130
130
|
self.denoise_disparity_map = self.used_config["denoise_disparity_map"]
|
|
131
131
|
self.required_bands = self.used_config["required_bands"]
|
|
@@ -133,7 +133,11 @@ class CensusMccnnSgm(
|
|
|
133
133
|
|
|
134
134
|
# Saving files
|
|
135
135
|
self.save_intermediate_data = self.used_config["save_intermediate_data"]
|
|
136
|
+
|
|
136
137
|
self.confidence_filtering = self.used_config["confidence_filtering"]
|
|
138
|
+
self.threshold_disp_range_to_borders = self.used_config[
|
|
139
|
+
"threshold_disp_range_to_borders"
|
|
140
|
+
]
|
|
137
141
|
|
|
138
142
|
# init orchestrator
|
|
139
143
|
self.orchestrator = None
|
|
@@ -175,7 +179,7 @@ class CensusMccnnSgm(
|
|
|
175
179
|
|
|
176
180
|
# Overload conf
|
|
177
181
|
overloaded_conf["method"] = conf.get(
|
|
178
|
-
"method", "
|
|
182
|
+
"method", "auto"
|
|
179
183
|
) # change it if census_sgm is not default
|
|
180
184
|
# method called in abstract_dense_matching_app.py
|
|
181
185
|
overloaded_conf["min_epi_tile_size"] = conf.get(
|
|
@@ -232,13 +236,19 @@ class CensusMccnnSgm(
|
|
|
232
236
|
"use_global_disp_range", False
|
|
233
237
|
)
|
|
234
238
|
overloaded_conf["local_disp_grid_step"] = conf.get(
|
|
235
|
-
"local_disp_grid_step",
|
|
239
|
+
"local_disp_grid_step", 10
|
|
236
240
|
)
|
|
237
241
|
overloaded_conf["disp_range_propagation_filter_size"] = conf.get(
|
|
238
|
-
"disp_range_propagation_filter_size",
|
|
242
|
+
"disp_range_propagation_filter_size", 50
|
|
243
|
+
)
|
|
244
|
+
overloaded_conf["epi_disp_grid_tile_size"] = conf.get(
|
|
245
|
+
"epi_disp_grid_tile_size", 800
|
|
239
246
|
)
|
|
240
247
|
overloaded_conf["required_bands"] = conf.get("required_bands", ["b0"])
|
|
241
248
|
overloaded_conf["used_band"] = conf.get("used_band", "b0")
|
|
249
|
+
overloaded_conf["threshold_disp_range_to_borders"] = conf.get(
|
|
250
|
+
"threshold_disp_range_to_borders", False
|
|
251
|
+
)
|
|
242
252
|
|
|
243
253
|
# Saving files
|
|
244
254
|
overloaded_conf["save_intermediate_data"] = conf.get(
|
|
@@ -360,11 +370,13 @@ class CensusMccnnSgm(
|
|
|
360
370
|
"disp_range_propagation_filter_size": And(
|
|
361
371
|
Or(int, float), lambda x: x >= 0
|
|
362
372
|
),
|
|
373
|
+
"epi_disp_grid_tile_size": int,
|
|
363
374
|
"required_bands": [str],
|
|
364
375
|
"used_band": str,
|
|
365
376
|
"loader_conf": Or(dict, collections.OrderedDict, str, None),
|
|
366
377
|
"loader": str,
|
|
367
378
|
"confidence_filtering": dict,
|
|
379
|
+
"threshold_disp_range_to_borders": bool,
|
|
368
380
|
}
|
|
369
381
|
|
|
370
382
|
# Check conf
|
|
@@ -416,33 +428,41 @@ class CensusMccnnSgm(
|
|
|
416
428
|
overloaded_conf["confidence_filtering"]["activated"] = overloaded_conf[
|
|
417
429
|
"confidence_filtering"
|
|
418
430
|
].get("activated", True)
|
|
419
|
-
overloaded_conf["confidence_filtering"]["
|
|
420
|
-
overloaded_conf["confidence_filtering"].get(
|
|
431
|
+
overloaded_conf["confidence_filtering"]["bounds_ratio_threshold"] = (
|
|
432
|
+
overloaded_conf["confidence_filtering"].get(
|
|
433
|
+
"bounds_ratio_threshold", 0.2
|
|
434
|
+
)
|
|
421
435
|
)
|
|
422
|
-
overloaded_conf["confidence_filtering"]["
|
|
423
|
-
overloaded_conf["confidence_filtering"].get(
|
|
436
|
+
overloaded_conf["confidence_filtering"]["risk_ratio_threshold"] = (
|
|
437
|
+
overloaded_conf["confidence_filtering"].get(
|
|
438
|
+
"risk_ratio_threshold", 0.8
|
|
439
|
+
)
|
|
440
|
+
)
|
|
441
|
+
overloaded_conf["confidence_filtering"]["bounds_range_threshold"] = (
|
|
442
|
+
overloaded_conf["confidence_filtering"].get(
|
|
443
|
+
"bounds_range_threshold", 4
|
|
444
|
+
)
|
|
445
|
+
)
|
|
446
|
+
overloaded_conf["confidence_filtering"]["risk_range_threshold"] = (
|
|
447
|
+
overloaded_conf["confidence_filtering"].get(
|
|
448
|
+
"risk_range_threshold", 12
|
|
449
|
+
)
|
|
424
450
|
)
|
|
425
|
-
overloaded_conf["confidence_filtering"]["risk_max"] = overloaded_conf[
|
|
426
|
-
"confidence_filtering"
|
|
427
|
-
].get("risk_max", 60)
|
|
428
451
|
overloaded_conf["confidence_filtering"]["nan_threshold"] = (
|
|
429
|
-
overloaded_conf["confidence_filtering"].get("nan_threshold", 0.
|
|
452
|
+
overloaded_conf["confidence_filtering"].get("nan_threshold", 0.2)
|
|
430
453
|
)
|
|
431
454
|
overloaded_conf["confidence_filtering"]["win_nanratio"] = (
|
|
432
455
|
overloaded_conf["confidence_filtering"].get("win_nanratio", 20)
|
|
433
456
|
)
|
|
434
|
-
overloaded_conf["confidence_filtering"]["win_mean_risk_max"] = (
|
|
435
|
-
overloaded_conf["confidence_filtering"].get("win_mean_risk_max", 7)
|
|
436
|
-
)
|
|
437
457
|
|
|
438
458
|
confidence_filtering_schema = {
|
|
439
459
|
"activated": bool,
|
|
440
|
-
"
|
|
441
|
-
"
|
|
442
|
-
"
|
|
460
|
+
"bounds_ratio_threshold": float,
|
|
461
|
+
"risk_ratio_threshold": float,
|
|
462
|
+
"bounds_range_threshold": int,
|
|
463
|
+
"risk_range_threshold": int,
|
|
443
464
|
"nan_threshold": float,
|
|
444
465
|
"win_nanratio": int,
|
|
445
|
-
"win_mean_risk_max": int,
|
|
446
466
|
}
|
|
447
467
|
|
|
448
468
|
checker_confidence_filtering_schema = Checker(
|
|
@@ -464,12 +484,16 @@ class CensusMccnnSgm(
|
|
|
464
484
|
|
|
465
485
|
"""
|
|
466
486
|
|
|
467
|
-
disp_min_grid_arr =
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
487
|
+
disp_min_grid_arr, _ = inputs.rasterio_read_as_array(
|
|
488
|
+
disp_range_grid["grid_min_path"]
|
|
489
|
+
)
|
|
490
|
+
disp_max_grid_arr, _ = inputs.rasterio_read_as_array(
|
|
491
|
+
disp_range_grid["grid_max_path"]
|
|
492
|
+
)
|
|
493
|
+
step_row = disp_range_grid["step_row"]
|
|
494
|
+
step_col = disp_range_grid["step_col"]
|
|
495
|
+
row_range = disp_range_grid["row_range"]
|
|
496
|
+
col_range = disp_range_grid["col_range"]
|
|
473
497
|
|
|
474
498
|
# get disp_to_alt_ratio
|
|
475
499
|
disp_to_alt_ratio = grid_left["disp_to_alt_ratio"]
|
|
@@ -574,6 +598,13 @@ class CensusMccnnSgm(
|
|
|
574
598
|
|
|
575
599
|
return margins_wrapper
|
|
576
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
|
+
|
|
577
608
|
@cars_profile(name="Optimal size estimation")
|
|
578
609
|
def get_optimal_tile_size(self, disp_range_grid, max_ram_per_worker):
|
|
579
610
|
"""
|
|
@@ -585,19 +616,24 @@ class CensusMccnnSgm(
|
|
|
585
616
|
|
|
586
617
|
"""
|
|
587
618
|
|
|
588
|
-
disp_min_grids =
|
|
589
|
-
|
|
619
|
+
disp_min_grids, _ = inputs.rasterio_read_as_array(
|
|
620
|
+
disp_range_grid["grid_min_path"]
|
|
621
|
+
)
|
|
622
|
+
disp_max_grids, _ = inputs.rasterio_read_as_array(
|
|
623
|
+
disp_range_grid["grid_max_path"]
|
|
624
|
+
)
|
|
590
625
|
|
|
591
626
|
# use max tile size as overlap for min and max:
|
|
592
627
|
# max Point to point diff is less than diff of tile
|
|
593
628
|
|
|
594
629
|
# use filter of size max_epi_tile_size
|
|
595
630
|
overlap = 3 * int(self.max_epi_tile_size / self.local_disp_grid_step)
|
|
596
|
-
|
|
597
|
-
|
|
631
|
+
|
|
632
|
+
disp_min_grids = minimum_filter(
|
|
633
|
+
disp_min_grids, size=[overlap, overlap], mode="nearest"
|
|
598
634
|
)
|
|
599
|
-
disp_max_grids =
|
|
600
|
-
disp_max_grids,
|
|
635
|
+
disp_max_grids = maximum_filter(
|
|
636
|
+
disp_max_grids, size=[overlap, overlap], mode="nearest"
|
|
601
637
|
)
|
|
602
638
|
|
|
603
639
|
# Worst cases scenario:
|
|
@@ -692,7 +728,7 @@ class CensusMccnnSgm(
|
|
|
692
728
|
dem_min=None,
|
|
693
729
|
dem_max=None,
|
|
694
730
|
pair_folder=None,
|
|
695
|
-
|
|
731
|
+
orchestrator=None,
|
|
696
732
|
):
|
|
697
733
|
"""
|
|
698
734
|
Generate disparity grids min and max, with given step
|
|
@@ -724,18 +760,24 @@ class CensusMccnnSgm(
|
|
|
724
760
|
:type dem_max: str
|
|
725
761
|
:param pair_folder: folder used for current pair
|
|
726
762
|
:type pair_folder: str
|
|
727
|
-
:param
|
|
728
|
-
:type
|
|
763
|
+
:param orchestrator: orchestrator
|
|
764
|
+
:type orchestrator: Orchestrator
|
|
729
765
|
|
|
730
766
|
|
|
731
767
|
:return disparity grid range, containing grid min and max
|
|
732
768
|
:rtype: CarsDataset
|
|
733
769
|
"""
|
|
734
770
|
|
|
735
|
-
#
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
771
|
+
# Default orchestrator
|
|
772
|
+
if orchestrator is None:
|
|
773
|
+
# Create default sequential orchestrator for current application
|
|
774
|
+
# be aware, no out_json will be shared between orchestrators
|
|
775
|
+
# No files saved
|
|
776
|
+
self.orchestrator = ocht.Orchestrator(
|
|
777
|
+
orchestrator_conf={"mode": "sequential"}
|
|
778
|
+
)
|
|
779
|
+
else:
|
|
780
|
+
self.orchestrator = orchestrator
|
|
739
781
|
|
|
740
782
|
epi_size_row = grid_right["epipolar_size_y"]
|
|
741
783
|
epi_size_col = grid_right["epipolar_size_x"]
|
|
@@ -751,46 +793,31 @@ class CensusMccnnSgm(
|
|
|
751
793
|
0, epi_size_col, nb_cols, retstep=True
|
|
752
794
|
)
|
|
753
795
|
|
|
754
|
-
grid_min = np.empty((len(row_range), len(col_range)))
|
|
755
|
-
grid_max = np.empty((len(row_range), len(col_range)))
|
|
756
|
-
|
|
757
796
|
# Create CarsDataset
|
|
758
797
|
grid_disp_range = cars_dataset.CarsDataset(
|
|
759
798
|
"arrays", name="grid_disp_range_unknown_pair"
|
|
760
799
|
)
|
|
761
|
-
|
|
762
|
-
grid_disp_range.tiling_grid = np.array(
|
|
763
|
-
[[[0, epi_size_row, 0, epi_size_col]]]
|
|
764
|
-
)
|
|
800
|
+
global_infos_cars_ds = cars_dataset.CarsDataset("dict")
|
|
765
801
|
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
"step_col": step_col,
|
|
769
|
-
"row_range": row_range,
|
|
770
|
-
"col_range": col_range,
|
|
771
|
-
}
|
|
772
|
-
grid_disp_range.attributes = grid_attributes.copy()
|
|
802
|
+
# Generate profile
|
|
803
|
+
raster_profile = DefaultGTiffProfile(count=1)
|
|
773
804
|
|
|
774
805
|
# saving infos
|
|
775
806
|
# disp grids
|
|
807
|
+
|
|
776
808
|
if self.save_intermediate_data:
|
|
777
|
-
safe_makedirs(pair_folder)
|
|
778
809
|
grid_min_path = os.path.join(pair_folder, "disp_min_grid.tif")
|
|
779
|
-
grid_orchestrator.add_to_save_lists(
|
|
780
|
-
grid_min_path,
|
|
781
|
-
dm_cst.DISP_MIN_GRID,
|
|
782
|
-
grid_disp_range,
|
|
783
|
-
dtype=np.float32,
|
|
784
|
-
cars_ds_name="disp_min_grid",
|
|
785
|
-
)
|
|
786
810
|
grid_max_path = os.path.join(pair_folder, "disp_max_grid.tif")
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
)
|
|
811
|
+
safe_makedirs(pair_folder)
|
|
812
|
+
else:
|
|
813
|
+
if pair_folder is None:
|
|
814
|
+
tmp_folder = os.path.join(self.orchestrator.out_dir, "tmp")
|
|
815
|
+
else:
|
|
816
|
+
tmp_folder = os.path.join(pair_folder, "tmp")
|
|
817
|
+
safe_makedirs(tmp_folder)
|
|
818
|
+
self.orchestrator.add_to_clean(tmp_folder)
|
|
819
|
+
grid_min_path = os.path.join(tmp_folder, "disp_min_grid.tif")
|
|
820
|
+
grid_max_path = os.path.join(tmp_folder, "disp_max_grid.tif")
|
|
794
821
|
|
|
795
822
|
if None not in (dmin, dmax):
|
|
796
823
|
# use global disparity range
|
|
@@ -800,446 +827,169 @@ class CensusMccnnSgm(
|
|
|
800
827
|
):
|
|
801
828
|
raise RuntimeError("Mix between local and global mode")
|
|
802
829
|
|
|
803
|
-
|
|
804
|
-
|
|
830
|
+
# Only one tile
|
|
831
|
+
grid_disp_range.tiling_grid = np.array([[[0, nb_rows, 0, nb_cols]]])
|
|
805
832
|
|
|
806
833
|
elif None not in (dem_min, dem_max, dem_median) or None not in (
|
|
807
834
|
altitude_delta_min,
|
|
808
835
|
altitude_delta_max,
|
|
809
836
|
):
|
|
810
|
-
# use local disparity
|
|
811
|
-
|
|
812
|
-
# Get associated alti mean / min / max values
|
|
813
|
-
dem_median_shape = inputs.rasterio_get_size(dem_median)
|
|
814
|
-
dem_median_width, dem_median_height = dem_median_shape
|
|
815
|
-
|
|
816
|
-
min_row = 0
|
|
817
|
-
min_col = 0
|
|
818
|
-
max_row = dem_median_height
|
|
819
|
-
max_col = dem_median_width
|
|
820
|
-
|
|
821
|
-
# get epsg
|
|
822
|
-
terrain_epsg = inputs.rasterio_get_epsg(dem_median)
|
|
823
|
-
|
|
824
|
-
# Get epipolar position of all dem mean
|
|
825
|
-
transform = inputs.rasterio_get_transform(dem_median)
|
|
826
|
-
|
|
827
|
-
if None not in (dem_min, dem_max, dem_median):
|
|
828
|
-
dem_min_shape = inputs.rasterio_get_size(dem_min)
|
|
829
|
-
dem_epsg = inputs.rasterio_get_epsg(dem_min)
|
|
830
|
-
|
|
831
|
-
if dem_median_shape != dem_min_shape:
|
|
832
|
-
# dem min max are the same shape
|
|
833
|
-
# dem median is not , hence we crop it
|
|
834
|
-
|
|
835
|
-
# get terrain bounds dem min
|
|
836
|
-
dem_min_bounds = inputs.rasterio_get_bounds(dem_min)
|
|
837
|
-
|
|
838
|
-
# find roi in dem_mean
|
|
839
|
-
roi_points = np.array(
|
|
840
|
-
[
|
|
841
|
-
[dem_min_bounds[0], dem_min_bounds[1]],
|
|
842
|
-
[dem_min_bounds[0], dem_min_bounds[3]],
|
|
843
|
-
[dem_min_bounds[2], dem_min_bounds[1]],
|
|
844
|
-
[dem_min_bounds[2], dem_min_bounds[3]],
|
|
845
|
-
]
|
|
846
|
-
)
|
|
847
|
-
|
|
848
|
-
# Transform points to terrain_epsg (dem min is in 4326)
|
|
849
|
-
roi_points_terrain = point_cloud_conversion(
|
|
850
|
-
roi_points,
|
|
851
|
-
dem_epsg,
|
|
852
|
-
terrain_epsg,
|
|
853
|
-
)
|
|
854
837
|
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
max_row = int(
|
|
866
|
-
min(
|
|
867
|
-
dem_median_height, # number of rows
|
|
868
|
-
roi_upper_row,
|
|
869
|
-
)
|
|
870
|
-
)
|
|
871
|
-
min_col = int(max(0, roi_lower_col))
|
|
872
|
-
max_col = int(
|
|
873
|
-
min(
|
|
874
|
-
dem_median_width, # number of columns
|
|
875
|
-
roi_upper_col,
|
|
876
|
-
)
|
|
877
|
-
)
|
|
838
|
+
# Generate multiple tiles
|
|
839
|
+
grid_tile_size = self.epi_disp_grid_tile_size
|
|
840
|
+
grid_disp_range.tiling_grid = tiling.generate_tiling_grid(
|
|
841
|
+
0,
|
|
842
|
+
0,
|
|
843
|
+
nb_rows,
|
|
844
|
+
nb_cols,
|
|
845
|
+
grid_tile_size,
|
|
846
|
+
grid_tile_size,
|
|
847
|
+
)
|
|
878
848
|
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
[
|
|
886
|
-
[
|
|
887
|
-
geom_plugin_with_dem_and_geoid.roi_shareloc[1],
|
|
888
|
-
geom_plugin_with_dem_and_geoid.roi_shareloc[0],
|
|
889
|
-
],
|
|
890
|
-
[
|
|
891
|
-
geom_plugin_with_dem_and_geoid.roi_shareloc[1],
|
|
892
|
-
geom_plugin_with_dem_and_geoid.roi_shareloc[2],
|
|
893
|
-
],
|
|
894
|
-
[
|
|
895
|
-
geom_plugin_with_dem_and_geoid.roi_shareloc[3],
|
|
896
|
-
geom_plugin_with_dem_and_geoid.roi_shareloc[0],
|
|
897
|
-
],
|
|
898
|
-
[
|
|
899
|
-
geom_plugin_with_dem_and_geoid.roi_shareloc[3],
|
|
900
|
-
geom_plugin_with_dem_and_geoid.roi_shareloc[2],
|
|
901
|
-
],
|
|
902
|
-
]
|
|
903
|
-
)
|
|
849
|
+
# add tiling of global_infos_cars_ds
|
|
850
|
+
global_infos_cars_ds.tiling_grid = grid_disp_range.tiling_grid
|
|
851
|
+
self.orchestrator.add_to_replace_lists(
|
|
852
|
+
global_infos_cars_ds,
|
|
853
|
+
cars_ds_name="global infos",
|
|
854
|
+
)
|
|
904
855
|
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
856
|
+
self.orchestrator.add_to_save_lists(
|
|
857
|
+
grid_min_path,
|
|
858
|
+
dm_cst.DISP_MIN_GRID,
|
|
859
|
+
grid_disp_range,
|
|
860
|
+
dtype=np.float32,
|
|
861
|
+
nodata=0,
|
|
862
|
+
cars_ds_name="disp_min_grid",
|
|
863
|
+
)
|
|
908
864
|
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
865
|
+
self.orchestrator.add_to_save_lists(
|
|
866
|
+
grid_max_path,
|
|
867
|
+
dm_cst.DISP_MAX_GRID,
|
|
868
|
+
grid_disp_range,
|
|
869
|
+
dtype=np.float32,
|
|
870
|
+
nodata=0,
|
|
871
|
+
cars_ds_name="disp_max_grid",
|
|
872
|
+
)
|
|
873
|
+
[saving_info] = ( # pylint: disable=unbalanced-tuple-unpacking
|
|
874
|
+
self.orchestrator.get_saving_infos([grid_disp_range])
|
|
875
|
+
)
|
|
876
|
+
[saving_info_global_infos] = self.orchestrator.get_saving_infos(
|
|
877
|
+
[global_infos_cars_ds]
|
|
878
|
+
)
|
|
913
879
|
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
880
|
+
# Generate grids on dict format
|
|
881
|
+
grid_disp_range_dict = {
|
|
882
|
+
"grid_min_path": grid_min_path,
|
|
883
|
+
"grid_max_path": grid_max_path,
|
|
884
|
+
"global_min": None,
|
|
885
|
+
"global_max": None,
|
|
886
|
+
"step_row": step_row,
|
|
887
|
+
"step_col": step_col,
|
|
888
|
+
"row_range": row_range,
|
|
889
|
+
"col_range": col_range,
|
|
890
|
+
}
|
|
918
891
|
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
892
|
+
if None not in (dmin, dmax):
|
|
893
|
+
# use global disparity range
|
|
894
|
+
if None not in (dem_min, dem_max) or None not in (
|
|
895
|
+
altitude_delta_min,
|
|
896
|
+
altitude_delta_max,
|
|
897
|
+
):
|
|
898
|
+
raise RuntimeError("Mix between local and global mode")
|
|
923
899
|
|
|
924
|
-
|
|
925
|
-
|
|
900
|
+
saving_info_global_infos_full = ocht.update_saving_infos(
|
|
901
|
+
saving_info_global_infos, row=0, col=0
|
|
926
902
|
)
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
col = indexes[:, 1]
|
|
930
|
-
terrain_positions = []
|
|
931
|
-
x_mean, y_mean = transformer.xy(row, col)
|
|
932
|
-
terrain_positions = np.transpose(np.array([x_mean, y_mean]))
|
|
933
|
-
|
|
934
|
-
# dem mean in terrain_epsg
|
|
935
|
-
x_mean = terrain_positions[:, 0]
|
|
936
|
-
y_mean = terrain_positions[:, 1]
|
|
937
|
-
|
|
938
|
-
dem_median_list = inputs.rasterio_get_values(
|
|
939
|
-
dem_median, x_mean, y_mean, point_cloud_conversion
|
|
903
|
+
saving_info_full = ocht.update_saving_infos(
|
|
904
|
+
saving_info, row=0, col=0
|
|
940
905
|
)
|
|
941
906
|
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
907
|
+
(
|
|
908
|
+
grid_disp_range[0, 0],
|
|
909
|
+
global_infos_cars_ds[0, 0],
|
|
910
|
+
) = self.orchestrator.cluster.create_task(
|
|
911
|
+
generate_disp_range_const_tile_wrapper, nout=2
|
|
912
|
+
)(
|
|
913
|
+
row_range,
|
|
914
|
+
col_range,
|
|
915
|
+
dmin,
|
|
916
|
+
dmax,
|
|
917
|
+
raster_profile,
|
|
918
|
+
saving_info_full,
|
|
919
|
+
saving_info_global_infos_full,
|
|
947
920
|
)
|
|
948
|
-
lon_mean = terrain_position_lon_lat[:, 0]
|
|
949
|
-
lat_mean = terrain_position_lon_lat[:, 1]
|
|
950
921
|
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
)
|
|
956
|
-
dem_max_list = inputs.rasterio_get_values(
|
|
957
|
-
dem_max, lon_mean, lat_mean, point_cloud_conversion
|
|
958
|
-
)
|
|
959
|
-
nan_mask = (
|
|
960
|
-
nan_mask & ~np.isnan(dem_min_list) & ~np.isnan(dem_max_list)
|
|
961
|
-
)
|
|
962
|
-
else:
|
|
963
|
-
dem_min_list = dem_median_list - altitude_delta_min
|
|
964
|
-
dem_max_list = dem_median_list + altitude_delta_max
|
|
965
|
-
|
|
966
|
-
# filter nan value from input points
|
|
967
|
-
lon_mean = lon_mean[nan_mask]
|
|
968
|
-
lat_mean = lat_mean[nan_mask]
|
|
969
|
-
dem_median_list = dem_median_list[nan_mask]
|
|
970
|
-
dem_min_list = dem_min_list[nan_mask]
|
|
971
|
-
dem_max_list = dem_max_list[nan_mask]
|
|
972
|
-
|
|
973
|
-
# if shareloc is used, perform inverse locs sequentially
|
|
974
|
-
if geom_plugin_with_dem_and_geoid.plugin_name == "SharelocGeometry":
|
|
975
|
-
|
|
976
|
-
# sensors physical positions
|
|
977
|
-
(
|
|
978
|
-
ind_cols_sensor,
|
|
979
|
-
ind_rows_sensor,
|
|
980
|
-
_,
|
|
981
|
-
) = geom_plugin_with_dem_and_geoid.inverse_loc(
|
|
982
|
-
sensor_image_right["image"]["main_file"],
|
|
983
|
-
sensor_image_right["geomodel"],
|
|
984
|
-
lat_mean,
|
|
985
|
-
lon_mean,
|
|
986
|
-
z_coord=dem_median_list,
|
|
987
|
-
)
|
|
988
|
-
|
|
989
|
-
# else (if libgeo is used) perform inverse locs in parallel
|
|
990
|
-
else:
|
|
991
|
-
|
|
992
|
-
num_points = len(dem_median_list)
|
|
993
|
-
|
|
994
|
-
if loc_inverse_orchestrator is None:
|
|
995
|
-
loc_inverse_orchestrator = grid_orchestrator
|
|
996
|
-
|
|
997
|
-
num_workers = loc_inverse_orchestrator.get_conf().get(
|
|
998
|
-
"nb_workers", 1
|
|
999
|
-
)
|
|
1000
|
-
|
|
1001
|
-
loc_inverse_dataset = cars_dataset.CarsDataset(
|
|
1002
|
-
"points", name="loc_inverse"
|
|
1003
|
-
)
|
|
1004
|
-
step = int(np.ceil(num_points / num_workers))
|
|
1005
|
-
# Create a grid with num_workers elements
|
|
1006
|
-
loc_inverse_dataset.create_grid(1, num_workers, 1, 1, 0, 0)
|
|
922
|
+
elif None not in (dem_min, dem_max, dem_median) or None not in (
|
|
923
|
+
altitude_delta_min,
|
|
924
|
+
altitude_delta_max,
|
|
925
|
+
):
|
|
1007
926
|
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
927
|
+
# use filter to propagate min and max
|
|
928
|
+
filter_overlap = (
|
|
929
|
+
2
|
|
930
|
+
* int(
|
|
931
|
+
self.disp_range_propagation_filter_size
|
|
932
|
+
/ self.local_disp_grid_step
|
|
1011
933
|
)
|
|
934
|
+
+ 1
|
|
935
|
+
)
|
|
1012
936
|
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
937
|
+
for col in range(grid_disp_range.shape[1]):
|
|
938
|
+
for row in range(grid_disp_range.shape[0]):
|
|
939
|
+
# update saving infos for potential replacement
|
|
1016
940
|
full_saving_info = ocht.update_saving_infos(
|
|
1017
|
-
saving_info, row=
|
|
941
|
+
saving_info, row=row, col=col
|
|
942
|
+
)
|
|
943
|
+
saving_info_global_infos_full = ocht.update_saving_infos(
|
|
944
|
+
saving_info_global_infos, row=row, col=col
|
|
1018
945
|
)
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
946
|
+
array_window = grid_disp_range.get_window_as_dict(row, col)
|
|
947
|
+
(
|
|
948
|
+
grid_disp_range[row, col],
|
|
949
|
+
global_infos_cars_ds[row, col],
|
|
950
|
+
) = self.orchestrator.cluster.create_task(
|
|
951
|
+
generate_disp_range_from_dem_wrapper, nout=2
|
|
1023
952
|
)(
|
|
953
|
+
array_window,
|
|
954
|
+
row_range,
|
|
955
|
+
col_range,
|
|
956
|
+
sensor_image_right,
|
|
957
|
+
grid_right,
|
|
1024
958
|
geom_plugin_with_dem_and_geoid,
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
959
|
+
dem_median,
|
|
960
|
+
dem_min,
|
|
961
|
+
dem_max,
|
|
962
|
+
altitude_delta_min,
|
|
963
|
+
altitude_delta_max,
|
|
964
|
+
raster_profile,
|
|
1030
965
|
full_saving_info,
|
|
966
|
+
saving_info_global_infos_full,
|
|
967
|
+
filter_overlap,
|
|
968
|
+
disp_to_alt_ratio,
|
|
969
|
+
disp_min_threshold=self.disp_min_threshold,
|
|
970
|
+
disp_max_threshold=self.disp_max_threshold,
|
|
1031
971
|
)
|
|
1032
972
|
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
ind_rows_sensor += list(tile[0]["row"])
|
|
1049
|
-
|
|
1050
|
-
# Generate epipolar disp grids
|
|
1051
|
-
# Get epipolar positions
|
|
1052
|
-
(epipolar_positions_row, epipolar_positions_col) = np.meshgrid(
|
|
1053
|
-
col_range, row_range
|
|
1054
|
-
)
|
|
1055
|
-
epipolar_positions = np.stack(
|
|
1056
|
-
[epipolar_positions_row, epipolar_positions_col], axis=2
|
|
1057
|
-
)
|
|
1058
|
-
|
|
1059
|
-
# Get sensor position
|
|
1060
|
-
sensors_positions = (
|
|
1061
|
-
geom_plugin_with_dem_and_geoid.sensor_position_from_grid(
|
|
1062
|
-
grid_right,
|
|
1063
|
-
np.reshape(
|
|
1064
|
-
epipolar_positions,
|
|
1065
|
-
(
|
|
1066
|
-
epipolar_positions.shape[0]
|
|
1067
|
-
* epipolar_positions.shape[1],
|
|
1068
|
-
2,
|
|
1069
|
-
),
|
|
1070
|
-
),
|
|
1071
|
-
)
|
|
1072
|
-
)
|
|
1073
|
-
|
|
1074
|
-
# compute reverse matrix
|
|
1075
|
-
transform_sensor = rasterio.Affine(
|
|
1076
|
-
*np.abs(
|
|
1077
|
-
inputs.rasterio_get_transform(
|
|
1078
|
-
sensor_image_right["image"]["main_file"]
|
|
1079
|
-
)
|
|
1080
|
-
)
|
|
1081
|
-
)
|
|
1082
|
-
|
|
1083
|
-
trans_inv = ~transform_sensor
|
|
1084
|
-
# Transform to positive values
|
|
1085
|
-
trans_inv = np.array(trans_inv)
|
|
1086
|
-
trans_inv = np.reshape(trans_inv, (3, 3))
|
|
1087
|
-
if trans_inv[0, 0] < 0:
|
|
1088
|
-
trans_inv[0, :] *= -1
|
|
1089
|
-
if trans_inv[1, 1] < 0:
|
|
1090
|
-
trans_inv[1, :] *= -1
|
|
1091
|
-
trans_inv = affine.Affine(*list(trans_inv.flatten()))
|
|
1092
|
-
|
|
1093
|
-
# Transform physical position to index
|
|
1094
|
-
index_positions = np.empty(sensors_positions.shape)
|
|
1095
|
-
for row_point in range(index_positions.shape[0]):
|
|
1096
|
-
row_geo, col_geo = sensors_positions[row_point, :]
|
|
1097
|
-
col, row = trans_inv * (row_geo, col_geo)
|
|
1098
|
-
index_positions[row_point, :] = (row, col)
|
|
1099
|
-
|
|
1100
|
-
ind_rows_sensor_grid = index_positions[:, 0] - 0.5
|
|
1101
|
-
ind_cols_sensor_grid = index_positions[:, 1] - 0.5
|
|
1102
|
-
|
|
1103
|
-
# Interpolate disparity
|
|
1104
|
-
disp_min_points = (
|
|
1105
|
-
-(dem_max_list - dem_median_list) / disp_to_alt_ratio
|
|
1106
|
-
)
|
|
1107
|
-
disp_max_points = (
|
|
1108
|
-
-(dem_min_list - dem_median_list) / disp_to_alt_ratio
|
|
1109
|
-
)
|
|
1110
|
-
|
|
1111
|
-
interp_min_linear = LinearInterpNearestExtrap(
|
|
1112
|
-
list(zip(ind_rows_sensor, ind_cols_sensor)), # noqa: B905
|
|
1113
|
-
disp_min_points,
|
|
1114
|
-
)
|
|
1115
|
-
interp_max_linear = LinearInterpNearestExtrap(
|
|
1116
|
-
list(zip(ind_rows_sensor, ind_cols_sensor)), # noqa: B905
|
|
1117
|
-
disp_max_points,
|
|
1118
|
-
)
|
|
1119
|
-
|
|
1120
|
-
grid_min = np.reshape(
|
|
1121
|
-
interp_min_linear(ind_rows_sensor_grid, ind_cols_sensor_grid),
|
|
1122
|
-
(
|
|
1123
|
-
epipolar_positions.shape[0],
|
|
1124
|
-
epipolar_positions.shape[1],
|
|
1125
|
-
),
|
|
1126
|
-
)
|
|
1127
|
-
|
|
1128
|
-
grid_max = np.reshape(
|
|
1129
|
-
interp_max_linear(ind_rows_sensor_grid, ind_cols_sensor_grid),
|
|
1130
|
-
(
|
|
1131
|
-
epipolar_positions.shape[0],
|
|
1132
|
-
epipolar_positions.shape[1],
|
|
1133
|
-
),
|
|
1134
|
-
)
|
|
1135
|
-
|
|
1136
|
-
else:
|
|
1137
|
-
raise RuntimeError(
|
|
1138
|
-
"Not a global or local mode for disparity range estimation"
|
|
1139
|
-
)
|
|
1140
|
-
|
|
1141
|
-
# Add margin
|
|
1142
|
-
diff = grid_max - grid_min
|
|
1143
|
-
logging.info("Max grid max - grid min : {} disp ".format(np.max(diff)))
|
|
1144
|
-
|
|
1145
|
-
if self.disp_min_threshold is not None:
|
|
1146
|
-
if np.any(grid_min < self.disp_min_threshold):
|
|
1147
|
-
logging.warning(
|
|
1148
|
-
"Override disp_min with disp_min_threshold {}".format(
|
|
1149
|
-
self.disp_min_threshold
|
|
1150
|
-
)
|
|
1151
|
-
)
|
|
1152
|
-
grid_min[grid_min < self.disp_min_threshold] = (
|
|
1153
|
-
self.disp_min_threshold
|
|
1154
|
-
)
|
|
1155
|
-
if self.disp_max_threshold is not None:
|
|
1156
|
-
if np.any(grid_max > self.disp_max_threshold):
|
|
1157
|
-
logging.warning(
|
|
1158
|
-
"Override disp_max with disp_max_threshold {}".format(
|
|
1159
|
-
self.disp_max_threshold
|
|
973
|
+
# Compute grid
|
|
974
|
+
self.orchestrator.breakpoint()
|
|
975
|
+
|
|
976
|
+
# Fill global infos
|
|
977
|
+
mins, maxs = [], []
|
|
978
|
+
for row in range(global_infos_cars_ds.shape[0]):
|
|
979
|
+
for col in range(global_infos_cars_ds.shape[1]):
|
|
980
|
+
try:
|
|
981
|
+
dict_data = global_infos_cars_ds[row, col].data
|
|
982
|
+
mins.append(dict_data["global_min"])
|
|
983
|
+
maxs.append(dict_data["global_max"])
|
|
984
|
+
except Exception:
|
|
985
|
+
logging.info(
|
|
986
|
+
"Tile {} {} not computed in epi disp range"
|
|
987
|
+
" generation".format(row, col)
|
|
1160
988
|
)
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
self.disp_max_threshold
|
|
1164
|
-
)
|
|
1165
|
-
|
|
1166
|
-
# use filter to propagate min and max
|
|
1167
|
-
overlap = (
|
|
1168
|
-
2
|
|
1169
|
-
* int(
|
|
1170
|
-
self.disp_range_propagation_filter_size
|
|
1171
|
-
/ self.local_disp_grid_step
|
|
1172
|
-
)
|
|
1173
|
-
+ 1
|
|
1174
|
-
)
|
|
1175
|
-
|
|
1176
|
-
grid_min = generic_filter(
|
|
1177
|
-
grid_min, np.min, [overlap, overlap], mode="nearest"
|
|
1178
|
-
)
|
|
1179
|
-
grid_max = generic_filter(
|
|
1180
|
-
grid_max, np.max, [overlap, overlap], mode="nearest"
|
|
1181
|
-
)
|
|
1182
|
-
|
|
1183
|
-
# Generate dataset
|
|
1184
|
-
# min and max are reversed
|
|
1185
|
-
disp_range_tile = xr.Dataset(
|
|
1186
|
-
data_vars={
|
|
1187
|
-
dm_cst.DISP_MIN_GRID: (["row", "col"], grid_min),
|
|
1188
|
-
dm_cst.DISP_MAX_GRID: (["row", "col"], grid_max),
|
|
1189
|
-
},
|
|
1190
|
-
coords={
|
|
1191
|
-
"row": np.arange(0, grid_min.shape[0]),
|
|
1192
|
-
"col": np.arange(0, grid_min.shape[1]),
|
|
1193
|
-
},
|
|
1194
|
-
)
|
|
1195
|
-
|
|
1196
|
-
# Save
|
|
1197
|
-
[saving_info] = ( # pylint: disable=unbalanced-tuple-unpacking
|
|
1198
|
-
grid_orchestrator.get_saving_infos([grid_disp_range])
|
|
1199
|
-
)
|
|
1200
|
-
saving_info = ocht.update_saving_infos(saving_info, row=0, col=0)
|
|
1201
|
-
# Generate profile
|
|
1202
|
-
# Generate profile
|
|
1203
|
-
geotransform = (
|
|
1204
|
-
epi_size_row,
|
|
1205
|
-
step_row,
|
|
1206
|
-
0.0,
|
|
1207
|
-
epi_size_col,
|
|
1208
|
-
0.0,
|
|
1209
|
-
step_col,
|
|
1210
|
-
)
|
|
1211
|
-
|
|
1212
|
-
transform = Affine.from_gdal(*geotransform)
|
|
1213
|
-
raster_profile = collections.OrderedDict(
|
|
1214
|
-
{
|
|
1215
|
-
"height": nb_rows,
|
|
1216
|
-
"width": nb_cols,
|
|
1217
|
-
"driver": "GTiff",
|
|
1218
|
-
"dtype": "float32",
|
|
1219
|
-
"transform": transform,
|
|
1220
|
-
"tiled": True,
|
|
1221
|
-
}
|
|
1222
|
-
)
|
|
1223
|
-
cars_dataset.fill_dataset(
|
|
1224
|
-
disp_range_tile,
|
|
1225
|
-
saving_info=saving_info,
|
|
1226
|
-
window=None,
|
|
1227
|
-
profile=raster_profile,
|
|
1228
|
-
attributes=None,
|
|
1229
|
-
overlaps=None,
|
|
1230
|
-
)
|
|
1231
|
-
grid_disp_range[0, 0] = disp_range_tile
|
|
989
|
+
grid_disp_range_dict["global_min"] = np.floor(np.nanmin(mins))
|
|
990
|
+
grid_disp_range_dict["global_max"] = np.ceil(np.nanmax(maxs))
|
|
1232
991
|
|
|
1233
|
-
|
|
1234
|
-
grid_orchestrator.breakpoint()
|
|
1235
|
-
|
|
1236
|
-
if np.any(diff < 0):
|
|
1237
|
-
logging.error("grid min > grid max in {}".format(pair_folder))
|
|
1238
|
-
raise RuntimeError("grid min > grid max in {}".format(pair_folder))
|
|
1239
|
-
|
|
1240
|
-
# cleanup
|
|
1241
|
-
grid_orchestrator.cleanup()
|
|
1242
|
-
return grid_disp_range
|
|
992
|
+
return grid_disp_range_dict
|
|
1243
993
|
|
|
1244
994
|
def run(
|
|
1245
995
|
self,
|
|
@@ -1435,16 +1185,8 @@ class CensusMccnnSgm(
|
|
|
1435
1185
|
application_constants.APPLICATION_TAG: {
|
|
1436
1186
|
dm_cst.DENSE_MATCHING_RUN_TAG: {
|
|
1437
1187
|
pair_key: {
|
|
1438
|
-
"global_disp_min":
|
|
1439
|
-
|
|
1440
|
-
dm_cst.DISP_MIN_GRID
|
|
1441
|
-
].values
|
|
1442
|
-
),
|
|
1443
|
-
"global_disp_max": np.nanmax(
|
|
1444
|
-
disp_range_grid[0, 0][
|
|
1445
|
-
dm_cst.DISP_MAX_GRID
|
|
1446
|
-
].values
|
|
1447
|
-
),
|
|
1188
|
+
"global_disp_min": disp_range_grid["global_min"],
|
|
1189
|
+
"global_disp_max": disp_range_grid["global_max"],
|
|
1448
1190
|
},
|
|
1449
1191
|
},
|
|
1450
1192
|
}
|
|
@@ -1521,6 +1263,9 @@ class CensusMccnnSgm(
|
|
|
1521
1263
|
),
|
|
1522
1264
|
texture_bands=texture_bands,
|
|
1523
1265
|
conf_filtering=self.confidence_filtering,
|
|
1266
|
+
threshold_disp_range_to_borders=(
|
|
1267
|
+
self.threshold_disp_range_to_borders
|
|
1268
|
+
),
|
|
1524
1269
|
)
|
|
1525
1270
|
|
|
1526
1271
|
else:
|
|
@@ -1545,6 +1290,7 @@ def compute_disparity_wrapper(
|
|
|
1545
1290
|
classification_fusion_margin=-1,
|
|
1546
1291
|
texture_bands=None,
|
|
1547
1292
|
conf_filtering=None,
|
|
1293
|
+
threshold_disp_range_to_borders=False,
|
|
1548
1294
|
) -> Dict[str, Tuple[xr.Dataset, xr.Dataset]]:
|
|
1549
1295
|
"""
|
|
1550
1296
|
Compute disparity maps from image objects.
|
|
@@ -1604,15 +1350,17 @@ def compute_disparity_wrapper(
|
|
|
1604
1350
|
(
|
|
1605
1351
|
disp_min_grid,
|
|
1606
1352
|
disp_max_grid,
|
|
1607
|
-
) = dm_algo.compute_disparity_grid(
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
np.nanmax(disp_range_grid[0, 0]["disp_max_grid"].data)
|
|
1353
|
+
) = dm_algo.compute_disparity_grid(
|
|
1354
|
+
disp_range_grid,
|
|
1355
|
+
left_image_object,
|
|
1356
|
+
right_image_object,
|
|
1357
|
+
used_band,
|
|
1358
|
+
threshold_disp_range_to_borders,
|
|
1614
1359
|
)
|
|
1615
1360
|
|
|
1361
|
+
global_disp_min = disp_range_grid["global_min"]
|
|
1362
|
+
global_disp_max = disp_range_grid["global_max"]
|
|
1363
|
+
|
|
1616
1364
|
# add global disparity in case of ambiguity normalization
|
|
1617
1365
|
left_image_object = add_global_disparity(
|
|
1618
1366
|
left_image_object, global_disp_min, global_disp_max
|
|
@@ -1664,7 +1412,9 @@ def compute_disparity_wrapper(
|
|
|
1664
1412
|
|
|
1665
1413
|
# Filtering by using the confidence
|
|
1666
1414
|
requested_confidence = [
|
|
1415
|
+
"confidence_from_risk_min.cars_2",
|
|
1667
1416
|
"confidence_from_risk_max.cars_2",
|
|
1417
|
+
"confidence_from_interval_bounds_inf.cars_3",
|
|
1668
1418
|
"confidence_from_interval_bounds_sup.cars_3",
|
|
1669
1419
|
]
|
|
1670
1420
|
|
|
@@ -1690,47 +1440,3 @@ def compute_disparity_wrapper(
|
|
|
1690
1440
|
)
|
|
1691
1441
|
|
|
1692
1442
|
return disp_dataset
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
def loc_inverse_wrapper(
|
|
1696
|
-
geom_plugin,
|
|
1697
|
-
image,
|
|
1698
|
-
geomodel,
|
|
1699
|
-
latitudes,
|
|
1700
|
-
longitudes,
|
|
1701
|
-
altitudes,
|
|
1702
|
-
saving_info=None,
|
|
1703
|
-
) -> pandas.DataFrame:
|
|
1704
|
-
"""
|
|
1705
|
-
Perform inverse localizations on input coordinates
|
|
1706
|
-
This function will be run as a delayed task.
|
|
1707
|
-
|
|
1708
|
-
:param geom_plugin: geometry plugin used to perform localizations
|
|
1709
|
-
:type geom_plugin: SharelocGeometry
|
|
1710
|
-
:param image: input image path
|
|
1711
|
-
:type image: str
|
|
1712
|
-
:param geomodel: input geometric model
|
|
1713
|
-
:type geomodel: str
|
|
1714
|
-
:param latitudes: input latitude coordinates
|
|
1715
|
-
:type latitudes: np.array
|
|
1716
|
-
:param longitudes: input longitudes coordinates
|
|
1717
|
-
:type longitudes: np.array
|
|
1718
|
-
:param altitudes: input latitude coordinates
|
|
1719
|
-
:type altitudes: np.array
|
|
1720
|
-
:param saving_info: saving info for cars orchestrator
|
|
1721
|
-
:type saving_info: dict
|
|
1722
|
-
|
|
1723
|
-
"""
|
|
1724
|
-
col, row, _ = geom_plugin.inverse_loc(
|
|
1725
|
-
image,
|
|
1726
|
-
geomodel,
|
|
1727
|
-
latitudes,
|
|
1728
|
-
longitudes,
|
|
1729
|
-
z_coord=altitudes,
|
|
1730
|
-
)
|
|
1731
|
-
output = pandas.DataFrame({"col": col, "row": row}, copy=False)
|
|
1732
|
-
cars_dataset.fill_dataframe(
|
|
1733
|
-
output, saving_info=saving_info, attributes=None
|
|
1734
|
-
)
|
|
1735
|
-
|
|
1736
|
-
return output
|