cars 1.0.0a1__cp311-cp311-win_amd64.whl → 1.0.0a3__cp311-cp311-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.cp311-win_amd64.dll.a +0 -0
- cars/applications/dense_match_filling/cpp/dense_match_filling_cpp.cp311-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.cp311-win_amd64.dll.a +0 -0
- cars/applications/dense_matching/cpp/dense_matching_cpp.cp311-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
|
@@ -36,6 +36,7 @@ import math
|
|
|
36
36
|
import os
|
|
37
37
|
|
|
38
38
|
import numpy as np
|
|
39
|
+
from pyproj import CRS
|
|
39
40
|
|
|
40
41
|
import cars.applications.sparse_matching.sparse_matching_constants as sm_cst
|
|
41
42
|
from cars import __version__
|
|
@@ -56,6 +57,7 @@ from cars.core import preprocessing, projection, roi_tools
|
|
|
56
57
|
from cars.core.geometry.abstract_geometry import AbstractGeometry
|
|
57
58
|
from cars.core.inputs import (
|
|
58
59
|
get_descriptions_bands,
|
|
60
|
+
rasterio_get_crs,
|
|
59
61
|
rasterio_get_epsg,
|
|
60
62
|
rasterio_get_size,
|
|
61
63
|
read_vector,
|
|
@@ -94,7 +96,7 @@ class UnitPipeline(PipelineTemplate):
|
|
|
94
96
|
|
|
95
97
|
# pylint: disable=too-many-instance-attributes
|
|
96
98
|
|
|
97
|
-
def __init__(self, conf,
|
|
99
|
+
def __init__(self, conf, config_dir=None): # noqa: C901
|
|
98
100
|
"""
|
|
99
101
|
Creates pipeline
|
|
100
102
|
|
|
@@ -113,13 +115,17 @@ class UnitPipeline(PipelineTemplate):
|
|
|
113
115
|
:type pipeline_name: str
|
|
114
116
|
:param cfg: configuration {'matching_cost_method': value}
|
|
115
117
|
:type cfg: dictionary
|
|
116
|
-
:param
|
|
117
|
-
:type
|
|
118
|
+
:param config_dir: path to dir containing json/yaml
|
|
119
|
+
:type config_dir: str
|
|
118
120
|
"""
|
|
119
121
|
|
|
120
122
|
# Used conf
|
|
121
123
|
self.used_conf = {}
|
|
122
124
|
|
|
125
|
+
# Transform relative path to absolute path
|
|
126
|
+
if config_dir is not None:
|
|
127
|
+
config_dir = os.path.abspath(config_dir)
|
|
128
|
+
|
|
123
129
|
# Check global conf
|
|
124
130
|
self.check_global_schema(conf)
|
|
125
131
|
|
|
@@ -129,9 +135,7 @@ class UnitPipeline(PipelineTemplate):
|
|
|
129
135
|
)
|
|
130
136
|
|
|
131
137
|
# Check conf inputs
|
|
132
|
-
inputs = self.check_inputs(
|
|
133
|
-
conf[INPUTS], config_json_dir=config_json_dir
|
|
134
|
-
)
|
|
138
|
+
inputs = self.check_inputs(conf[INPUTS], config_dir=config_dir)
|
|
135
139
|
self.used_conf[INPUTS] = inputs
|
|
136
140
|
|
|
137
141
|
# Check advanced parameters
|
|
@@ -143,6 +147,9 @@ class UnitPipeline(PipelineTemplate):
|
|
|
143
147
|
self.geom_plugin_without_dem_and_geoid,
|
|
144
148
|
self.geom_plugin_with_dem_and_geoid,
|
|
145
149
|
self.dem_generation_roi,
|
|
150
|
+
self.scaling_coeff,
|
|
151
|
+
self.land_cover_map,
|
|
152
|
+
self.classification_to_config_mapping,
|
|
146
153
|
) = advanced_parameters.check_advanced_parameters(
|
|
147
154
|
inputs, conf.get(ADVANCED, {}), check_epipolar_a_priori=True
|
|
148
155
|
)
|
|
@@ -159,7 +166,11 @@ class UnitPipeline(PipelineTemplate):
|
|
|
159
166
|
self.debug_with_roi = self.used_conf[ADVANCED][adv_cst.DEBUG_WITH_ROI]
|
|
160
167
|
|
|
161
168
|
# Check conf output
|
|
162
|
-
|
|
169
|
+
(
|
|
170
|
+
output,
|
|
171
|
+
self.scaling_coeff,
|
|
172
|
+
) = self.check_output(conf[OUTPUT], self.scaling_coeff)
|
|
173
|
+
|
|
163
174
|
self.used_conf[OUTPUT] = output
|
|
164
175
|
|
|
165
176
|
prod_level = output[out_cst.PRODUCT_LEVEL]
|
|
@@ -419,15 +430,15 @@ class UnitPipeline(PipelineTemplate):
|
|
|
419
430
|
logging.warning(log_msg)
|
|
420
431
|
|
|
421
432
|
@staticmethod
|
|
422
|
-
def check_inputs(conf,
|
|
433
|
+
def check_inputs(conf, config_dir=None):
|
|
423
434
|
"""
|
|
424
435
|
Check the inputs given
|
|
425
436
|
|
|
426
437
|
:param conf: configuration of inputs
|
|
427
438
|
:type conf: dict
|
|
428
|
-
:param
|
|
439
|
+
:param config_dir: directory of used json/yaml, if
|
|
429
440
|
user filled paths with relative paths
|
|
430
|
-
:type
|
|
441
|
+
:type config_dir: str
|
|
431
442
|
|
|
432
443
|
:return: overloaded inputs
|
|
433
444
|
:rtype: dict
|
|
@@ -440,36 +451,35 @@ class UnitPipeline(PipelineTemplate):
|
|
|
440
451
|
and dsm_cst.DSMS not in conf
|
|
441
452
|
):
|
|
442
453
|
output_config = sensor_inputs.sensors_check_inputs(
|
|
443
|
-
conf,
|
|
454
|
+
conf, config_dir=config_dir
|
|
444
455
|
)
|
|
445
456
|
elif depth_cst.DEPTH_MAPS in conf:
|
|
446
457
|
output_config = {
|
|
447
458
|
**output_config,
|
|
448
459
|
**depth_map_inputs.check_depth_maps_inputs(
|
|
449
|
-
conf,
|
|
460
|
+
conf, config_dir=config_dir
|
|
450
461
|
),
|
|
451
462
|
}
|
|
452
463
|
else:
|
|
453
464
|
output_config = {
|
|
454
465
|
**output_config,
|
|
455
|
-
**dsm_inputs.check_dsm_inputs(
|
|
456
|
-
conf, config_json_dir=config_json_dir
|
|
457
|
-
),
|
|
466
|
+
**dsm_inputs.check_dsm_inputs(conf, config_dir=config_dir),
|
|
458
467
|
}
|
|
459
468
|
return output_config
|
|
460
469
|
|
|
461
470
|
@staticmethod
|
|
462
|
-
def check_output(conf):
|
|
471
|
+
def check_output(conf, scaling_coeff):
|
|
463
472
|
"""
|
|
464
473
|
Check the output given
|
|
465
474
|
|
|
466
475
|
:param conf: configuration of output
|
|
467
476
|
:type conf: dict
|
|
468
|
-
|
|
469
|
-
:
|
|
470
|
-
:
|
|
477
|
+
:param scaling_coeff: scaling factor for resolution
|
|
478
|
+
:type scaling_coeff: float
|
|
479
|
+
:return: overloader output
|
|
480
|
+
:rtype: dict
|
|
471
481
|
"""
|
|
472
|
-
return output_parameters.check_output_parameters(conf)
|
|
482
|
+
return output_parameters.check_output_parameters(conf, scaling_coeff)
|
|
473
483
|
|
|
474
484
|
def check_applications( # noqa: C901 : too complex
|
|
475
485
|
self,
|
|
@@ -483,6 +493,7 @@ class UnitPipeline(PipelineTemplate):
|
|
|
483
493
|
:param conf: configuration of applications
|
|
484
494
|
:type conf: dict
|
|
485
495
|
"""
|
|
496
|
+
scaling_coeff = self.scaling_coeff
|
|
486
497
|
|
|
487
498
|
# Check if all specified applications are used
|
|
488
499
|
# Application in terrain_application are note used in
|
|
@@ -580,7 +591,9 @@ class UnitPipeline(PipelineTemplate):
|
|
|
580
591
|
if self.sensors_in_inputs:
|
|
581
592
|
# Epipolar grid generation
|
|
582
593
|
self.epipolar_grid_generation_application = Application(
|
|
583
|
-
"grid_generation",
|
|
594
|
+
"grid_generation",
|
|
595
|
+
cfg=used_conf.get("grid_generation", {}),
|
|
596
|
+
scaling_coeff=scaling_coeff,
|
|
584
597
|
)
|
|
585
598
|
used_conf["grid_generation"] = (
|
|
586
599
|
self.epipolar_grid_generation_application.get_conf()
|
|
@@ -588,7 +601,9 @@ class UnitPipeline(PipelineTemplate):
|
|
|
588
601
|
|
|
589
602
|
# image resampling
|
|
590
603
|
self.resampling_application = Application(
|
|
591
|
-
"resampling",
|
|
604
|
+
"resampling",
|
|
605
|
+
cfg=used_conf.get("resampling", {}),
|
|
606
|
+
scaling_coeff=scaling_coeff,
|
|
592
607
|
)
|
|
593
608
|
used_conf["resampling"] = self.resampling_application.get_conf()
|
|
594
609
|
|
|
@@ -610,10 +625,13 @@ class UnitPipeline(PipelineTemplate):
|
|
|
610
625
|
self.ground_truth_reprojection = Application(
|
|
611
626
|
"ground_truth_reprojection",
|
|
612
627
|
cfg=used_conf.get("ground_truth_reprojection", {}),
|
|
628
|
+
scaling_coeff=scaling_coeff,
|
|
613
629
|
)
|
|
614
630
|
# holes detection
|
|
615
631
|
self.hole_detection_app = Application(
|
|
616
|
-
"hole_detection",
|
|
632
|
+
"hole_detection",
|
|
633
|
+
cfg=used_conf.get("hole_detection", {}),
|
|
634
|
+
scaling_coeff=scaling_coeff,
|
|
617
635
|
)
|
|
618
636
|
used_conf["hole_detection"] = self.hole_detection_app.get_conf()
|
|
619
637
|
|
|
@@ -624,6 +642,7 @@ class UnitPipeline(PipelineTemplate):
|
|
|
624
642
|
"dense_match_filling.1",
|
|
625
643
|
{"method": "plane"},
|
|
626
644
|
),
|
|
645
|
+
scaling_coeff=scaling_coeff,
|
|
627
646
|
)
|
|
628
647
|
used_conf["dense_match_filling.1"] = (
|
|
629
648
|
self.dense_match_filling_1.get_conf()
|
|
@@ -636,6 +655,7 @@ class UnitPipeline(PipelineTemplate):
|
|
|
636
655
|
"dense_match_filling.2",
|
|
637
656
|
{"method": "zero_padding"},
|
|
638
657
|
),
|
|
658
|
+
scaling_coeff=scaling_coeff,
|
|
639
659
|
)
|
|
640
660
|
used_conf["dense_match_filling.2"] = (
|
|
641
661
|
self.dense_match_filling_2.get_conf()
|
|
@@ -645,6 +665,7 @@ class UnitPipeline(PipelineTemplate):
|
|
|
645
665
|
self.sparse_mtch_sift_app = Application(
|
|
646
666
|
"sparse_matching",
|
|
647
667
|
cfg=used_conf.get("sparse_matching.sift", {"method": "sift"}),
|
|
668
|
+
scaling_coeff=scaling_coeff,
|
|
648
669
|
)
|
|
649
670
|
used_conf["sparse_matching.sift"] = (
|
|
650
671
|
self.sparse_mtch_sift_app.get_conf()
|
|
@@ -672,13 +693,17 @@ class UnitPipeline(PipelineTemplate):
|
|
|
672
693
|
):
|
|
673
694
|
dense_matching_config["performance_map_method"] = "risk"
|
|
674
695
|
self.dense_matching_app = Application(
|
|
675
|
-
"dense_matching",
|
|
696
|
+
"dense_matching",
|
|
697
|
+
cfg=dense_matching_config,
|
|
698
|
+
scaling_coeff=scaling_coeff,
|
|
676
699
|
)
|
|
677
700
|
used_conf["dense_matching"] = self.dense_matching_app.get_conf()
|
|
678
701
|
|
|
679
702
|
# Triangulation
|
|
680
703
|
self.triangulation_application = Application(
|
|
681
|
-
"triangulation",
|
|
704
|
+
"triangulation",
|
|
705
|
+
cfg=used_conf.get("triangulation", {}),
|
|
706
|
+
scaling_coeff=scaling_coeff,
|
|
682
707
|
)
|
|
683
708
|
used_conf["triangulation"] = (
|
|
684
709
|
self.triangulation_application.get_conf()
|
|
@@ -686,7 +711,9 @@ class UnitPipeline(PipelineTemplate):
|
|
|
686
711
|
|
|
687
712
|
# MNT generation
|
|
688
713
|
self.dem_generation_application = Application(
|
|
689
|
-
"dem_generation",
|
|
714
|
+
"dem_generation",
|
|
715
|
+
cfg=used_conf.get("dem_generation", {}),
|
|
716
|
+
scaling_coeff=scaling_coeff,
|
|
690
717
|
)
|
|
691
718
|
used_conf["dem_generation"] = (
|
|
692
719
|
self.dem_generation_application.get_conf()
|
|
@@ -704,6 +731,7 @@ class UnitPipeline(PipelineTemplate):
|
|
|
704
731
|
"point_cloud_outlier_removal.1",
|
|
705
732
|
{"method": "small_components"},
|
|
706
733
|
),
|
|
734
|
+
scaling_coeff=scaling_coeff,
|
|
707
735
|
)
|
|
708
736
|
used_conf["point_cloud_outlier_removal.1"] = (
|
|
709
737
|
self.pc_outlier_removal_1_app.get_conf()
|
|
@@ -716,6 +744,7 @@ class UnitPipeline(PipelineTemplate):
|
|
|
716
744
|
"point_cloud_outlier_removal.2",
|
|
717
745
|
{"method": "statistical"},
|
|
718
746
|
),
|
|
747
|
+
scaling_coeff=scaling_coeff,
|
|
719
748
|
)
|
|
720
749
|
used_conf["point_cloud_outlier_removal.2"] = (
|
|
721
750
|
self.pc_outlier_removal_2_app.get_conf()
|
|
@@ -727,6 +756,7 @@ class UnitPipeline(PipelineTemplate):
|
|
|
727
756
|
self.pc_denoising_application = Application(
|
|
728
757
|
"pc_denoising",
|
|
729
758
|
cfg=used_conf.get("pc_denoising", {"method": "none"}),
|
|
759
|
+
scaling_coeff=scaling_coeff,
|
|
730
760
|
)
|
|
731
761
|
used_conf["pc_denoising"] = self.pc_denoising_application.get_conf()
|
|
732
762
|
|
|
@@ -736,6 +766,7 @@ class UnitPipeline(PipelineTemplate):
|
|
|
736
766
|
self.rasterization_application = Application(
|
|
737
767
|
"point_cloud_rasterization",
|
|
738
768
|
cfg=used_conf.get("point_cloud_rasterization", {}),
|
|
769
|
+
scaling_coeff=scaling_coeff,
|
|
739
770
|
)
|
|
740
771
|
used_conf["point_cloud_rasterization"] = (
|
|
741
772
|
self.rasterization_application.get_conf()
|
|
@@ -747,6 +778,7 @@ class UnitPipeline(PipelineTemplate):
|
|
|
747
778
|
"dsm_filling.1",
|
|
748
779
|
{"method": "exogenous_filling"},
|
|
749
780
|
),
|
|
781
|
+
scaling_coeff=scaling_coeff,
|
|
750
782
|
)
|
|
751
783
|
used_conf["dsm_filling.1"] = (
|
|
752
784
|
self.dsm_filling_1_application.get_conf()
|
|
@@ -769,22 +801,25 @@ class UnitPipeline(PipelineTemplate):
|
|
|
769
801
|
"dsm_filling.3",
|
|
770
802
|
{"method": "border_interpolation"},
|
|
771
803
|
),
|
|
804
|
+
scaling_coeff=scaling_coeff,
|
|
772
805
|
)
|
|
773
806
|
used_conf["dsm_filling.3"] = (
|
|
774
807
|
self.dsm_filling_3_application.get_conf()
|
|
775
808
|
)
|
|
776
809
|
# Auxiliary filling
|
|
777
810
|
self.auxiliary_filling_application = Application(
|
|
778
|
-
"auxiliary_filling",
|
|
811
|
+
"auxiliary_filling",
|
|
812
|
+
cfg=conf.get("auxiliary_filling", {}),
|
|
813
|
+
scaling_coeff=scaling_coeff,
|
|
779
814
|
)
|
|
780
815
|
used_conf["auxiliary_filling"] = (
|
|
781
816
|
self.auxiliary_filling_application.get_conf()
|
|
782
817
|
)
|
|
783
818
|
|
|
784
819
|
if (
|
|
785
|
-
self.dsm_filling_1_application.classification
|
|
786
|
-
or self.dsm_filling_2_application.classification
|
|
787
|
-
or self.dsm_filling_3_application.classification
|
|
820
|
+
self.dsm_filling_1_application.classification != ["nodata"]
|
|
821
|
+
or self.dsm_filling_2_application.classification != ["nodata"]
|
|
822
|
+
or self.dsm_filling_3_application.classification != ["nodata"]
|
|
788
823
|
):
|
|
789
824
|
self.save_output_classif_for_filling = True
|
|
790
825
|
|
|
@@ -794,6 +829,7 @@ class UnitPipeline(PipelineTemplate):
|
|
|
794
829
|
self.pc_fusion_application = Application(
|
|
795
830
|
"point_cloud_fusion",
|
|
796
831
|
cfg=used_conf.get("point_cloud_fusion", {}),
|
|
832
|
+
scaling_coeff=scaling_coeff,
|
|
797
833
|
)
|
|
798
834
|
used_conf["point_cloud_fusion"] = (
|
|
799
835
|
self.pc_fusion_application.get_conf()
|
|
@@ -914,7 +950,7 @@ class UnitPipeline(PipelineTemplate):
|
|
|
914
950
|
]
|
|
915
951
|
if (
|
|
916
952
|
"classification" in inputs_conf["sensors"][key2]
|
|
917
|
-
and inputs_conf["sensors"][
|
|
953
|
+
and inputs_conf["sensors"][key2]["classification"] is not None
|
|
918
954
|
):
|
|
919
955
|
classif_right = inputs_conf["sensors"][key2]["classification"][
|
|
920
956
|
"main_file"
|
|
@@ -1156,6 +1192,10 @@ class UnitPipeline(PipelineTemplate):
|
|
|
1156
1192
|
# Run cluster breakpoint to compute sifts: force computation
|
|
1157
1193
|
self.cars_orchestrator.breakpoint()
|
|
1158
1194
|
|
|
1195
|
+
minimum_nb_matches = (
|
|
1196
|
+
self.sparse_mtch_sift_app.get_minimum_nb_matches()
|
|
1197
|
+
)
|
|
1198
|
+
|
|
1159
1199
|
# Run grid correction application
|
|
1160
1200
|
if self.used_conf[ADVANCED][adv_cst.USE_EPIPOLAR_A_PRIORI] is False:
|
|
1161
1201
|
# Estimate grid correction if no epipolar a priori
|
|
@@ -1177,23 +1217,15 @@ class UnitPipeline(PipelineTemplate):
|
|
|
1177
1217
|
)
|
|
1178
1218
|
)
|
|
1179
1219
|
|
|
1180
|
-
minimum_nb_matches = (
|
|
1181
|
-
self.sparse_mtch_sift_app.get_minimum_nb_matches()
|
|
1182
|
-
)
|
|
1183
|
-
|
|
1184
1220
|
# Compute grid correction
|
|
1185
1221
|
(
|
|
1186
1222
|
self.pairs[pair_key]["grid_correction_coef"],
|
|
1187
1223
|
self.pairs[pair_key]["corrected_matches_array"],
|
|
1188
|
-
self.pairs[pair_key]["corrected_matches_cars_ds"],
|
|
1189
1224
|
_,
|
|
1190
1225
|
_,
|
|
1191
1226
|
) = grid_correction_app.estimate_right_grid_correction(
|
|
1192
1227
|
self.pairs[pair_key]["matches_array"],
|
|
1193
1228
|
self.pairs[pair_key]["grid_right"],
|
|
1194
|
-
initial_cars_ds=self.pairs[pair_key][
|
|
1195
|
-
"epipolar_matches_left"
|
|
1196
|
-
],
|
|
1197
1229
|
save_matches=save_matches,
|
|
1198
1230
|
minimum_nb_matches=minimum_nb_matches,
|
|
1199
1231
|
pair_folder=os.path.join(
|
|
@@ -1255,6 +1287,19 @@ class UnitPipeline(PipelineTemplate):
|
|
|
1255
1287
|
"Global disparity interval with margin : "
|
|
1256
1288
|
f"[{disp_min:.2f} pix, {disp_max:.2f} pix]"
|
|
1257
1289
|
)
|
|
1290
|
+
else:
|
|
1291
|
+
disp_min = (
|
|
1292
|
+
-self.sparse_mtch_sift_app.elevation_delta_upper_bound
|
|
1293
|
+
/ disp_to_alt_ratio
|
|
1294
|
+
)
|
|
1295
|
+
disp_max = (
|
|
1296
|
+
-self.sparse_mtch_sift_app.elevation_delta_lower_bound
|
|
1297
|
+
/ disp_to_alt_ratio
|
|
1298
|
+
)
|
|
1299
|
+
logging.info(
|
|
1300
|
+
"Global disparity interval : "
|
|
1301
|
+
f"[{disp_min:.2f} pix, {disp_max:.2f} pix]"
|
|
1302
|
+
)
|
|
1258
1303
|
|
|
1259
1304
|
if self.epsg is None:
|
|
1260
1305
|
# compute epsg
|
|
@@ -1293,7 +1338,6 @@ class UnitPipeline(PipelineTemplate):
|
|
|
1293
1338
|
or self.quit_on_app("resampling")
|
|
1294
1339
|
or self.quit_on_app("hole_detection")
|
|
1295
1340
|
or self.quit_on_app("sparse_matching.sift")
|
|
1296
|
-
or self.quit_on_app("sparse_matching.pandora")
|
|
1297
1341
|
):
|
|
1298
1342
|
return True
|
|
1299
1343
|
|
|
@@ -1356,13 +1400,12 @@ class UnitPipeline(PipelineTemplate):
|
|
|
1356
1400
|
pair_name for pair_name, _, _ in self.list_sensor_pairs
|
|
1357
1401
|
]
|
|
1358
1402
|
|
|
1359
|
-
for
|
|
1403
|
+
for _, (pair_key, _, _) in enumerate(self.list_sensor_pairs):
|
|
1360
1404
|
# Geometry plugin with dem will be used for the grid generation
|
|
1361
1405
|
geom_plugin = self.geom_plugin_with_dem_and_geoid
|
|
1362
1406
|
|
|
1363
1407
|
if self.used_conf[ADVANCED][adv_cst.USE_EPIPOLAR_A_PRIORI] is False:
|
|
1364
|
-
|
|
1365
|
-
save_matches = True
|
|
1408
|
+
save_matches = True
|
|
1366
1409
|
|
|
1367
1410
|
(
|
|
1368
1411
|
self.pairs[pair_key]["sensor_matches_left"],
|
|
@@ -1376,97 +1419,6 @@ class UnitPipeline(PipelineTemplate):
|
|
|
1376
1419
|
),
|
|
1377
1420
|
save_matches=save_matches,
|
|
1378
1421
|
)
|
|
1379
|
-
|
|
1380
|
-
# saved used
|
|
1381
|
-
|
|
1382
|
-
if (
|
|
1383
|
-
inputs[sens_cst.INITIAL_ELEVATION][sens_cst.DEM_PATH]
|
|
1384
|
-
is None
|
|
1385
|
-
# cover the case where the geom plugin doesn't use init elev
|
|
1386
|
-
or (
|
|
1387
|
-
inputs[sens_cst.INITIAL_ELEVATION][sens_cst.DEM_PATH]
|
|
1388
|
-
!= geom_plugin.dem
|
|
1389
|
-
)
|
|
1390
|
-
):
|
|
1391
|
-
# Generate grids with new MNT
|
|
1392
|
-
(
|
|
1393
|
-
self.pairs[pair_key]["new_grid_left"],
|
|
1394
|
-
self.pairs[pair_key]["new_grid_right"],
|
|
1395
|
-
) = self.epipolar_grid_generation_application.run(
|
|
1396
|
-
self.pairs[pair_key]["sensor_image_left"],
|
|
1397
|
-
self.pairs[pair_key]["sensor_image_right"],
|
|
1398
|
-
geom_plugin,
|
|
1399
|
-
orchestrator=self.cars_orchestrator,
|
|
1400
|
-
pair_folder=os.path.join(
|
|
1401
|
-
self.dump_dir,
|
|
1402
|
-
"epipolar_grid_generation",
|
|
1403
|
-
"new_mnt",
|
|
1404
|
-
pair_key,
|
|
1405
|
-
),
|
|
1406
|
-
pair_key=pair_key,
|
|
1407
|
-
)
|
|
1408
|
-
|
|
1409
|
-
# Correct grids with former matches
|
|
1410
|
-
# Transform matches to new grids
|
|
1411
|
-
|
|
1412
|
-
save_matches = self.sparse_mtch_sift_app.get_save_matches()
|
|
1413
|
-
|
|
1414
|
-
new_grid_matches_array = (
|
|
1415
|
-
geom_plugin.transform_matches_from_grids(
|
|
1416
|
-
self.pairs[pair_key]["sensor_matches_left"],
|
|
1417
|
-
self.pairs[pair_key]["sensor_matches_right"],
|
|
1418
|
-
self.pairs[pair_key]["new_grid_left"],
|
|
1419
|
-
self.pairs[pair_key]["new_grid_right"],
|
|
1420
|
-
)
|
|
1421
|
-
)
|
|
1422
|
-
|
|
1423
|
-
# Estimate grid_correction
|
|
1424
|
-
(
|
|
1425
|
-
self.pairs[pair_key]["grid_correction_coef"],
|
|
1426
|
-
self.pairs[pair_key]["corrected_matches_array"],
|
|
1427
|
-
self.pairs[pair_key]["corrected_matches_cars_ds"],
|
|
1428
|
-
_,
|
|
1429
|
-
_,
|
|
1430
|
-
) = grid_correction_app.estimate_right_grid_correction(
|
|
1431
|
-
new_grid_matches_array,
|
|
1432
|
-
self.pairs[pair_key]["new_grid_right"],
|
|
1433
|
-
save_matches=save_matches,
|
|
1434
|
-
minimum_nb_matches=minimum_nb_matches,
|
|
1435
|
-
initial_cars_ds=self.pairs[pair_key][
|
|
1436
|
-
"epipolar_matches_left"
|
|
1437
|
-
],
|
|
1438
|
-
pair_folder=os.path.join(
|
|
1439
|
-
self.dump_dir, "grid_correction", "new", pair_key
|
|
1440
|
-
),
|
|
1441
|
-
pair_key=pair_key,
|
|
1442
|
-
orchestrator=self.cars_orchestrator,
|
|
1443
|
-
)
|
|
1444
|
-
|
|
1445
|
-
# Correct grid right
|
|
1446
|
-
|
|
1447
|
-
self.pairs[pair_key]["corrected_grid_right"] = (
|
|
1448
|
-
grid_correction_app.correct_grid(
|
|
1449
|
-
self.pairs[pair_key]["new_grid_right"],
|
|
1450
|
-
self.pairs[pair_key]["grid_correction_coef"],
|
|
1451
|
-
os.path.join(
|
|
1452
|
-
self.dump_dir,
|
|
1453
|
-
"grid_correction",
|
|
1454
|
-
"new",
|
|
1455
|
-
pair_key,
|
|
1456
|
-
),
|
|
1457
|
-
save_corrected_grid,
|
|
1458
|
-
)
|
|
1459
|
-
)
|
|
1460
|
-
|
|
1461
|
-
# Use the new grid as uncorrected grid
|
|
1462
|
-
self.pairs[pair_key]["grid_right"] = self.pairs[pair_key][
|
|
1463
|
-
"new_grid_right"
|
|
1464
|
-
]
|
|
1465
|
-
|
|
1466
|
-
self.pairs[pair_key]["corrected_grid_left"] = self.pairs[
|
|
1467
|
-
pair_key
|
|
1468
|
-
]["new_grid_left"]
|
|
1469
|
-
|
|
1470
1422
|
elif (
|
|
1471
1423
|
self.used_conf[ADVANCED][adv_cst.USE_EPIPOLAR_A_PRIORI] is True
|
|
1472
1424
|
and not self.use_sift_a_priori
|
|
@@ -1553,14 +1505,13 @@ class UnitPipeline(PipelineTemplate):
|
|
|
1553
1505
|
(
|
|
1554
1506
|
self.pairs[pair_key]["grid_correction_coef"],
|
|
1555
1507
|
self.pairs[pair_key]["corrected_matches_array"],
|
|
1556
|
-
self.pairs[pair_key]["corrected_matches_cars_ds"],
|
|
1557
1508
|
_,
|
|
1558
1509
|
_,
|
|
1559
1510
|
) = grid_correction_app.estimate_right_grid_correction(
|
|
1560
1511
|
new_grid_matches_array,
|
|
1561
1512
|
self.pairs[pair_key]["grid_right"],
|
|
1562
1513
|
save_matches=save_matches,
|
|
1563
|
-
|
|
1514
|
+
minimum_nb_matches=minimum_nb_matches,
|
|
1564
1515
|
pair_folder=os.path.join(
|
|
1565
1516
|
self.dump_dir, "grid_correction", "new", pair_key
|
|
1566
1517
|
),
|
|
@@ -1638,8 +1589,8 @@ class UnitPipeline(PipelineTemplate):
|
|
|
1638
1589
|
):
|
|
1639
1590
|
dmin = disp_min / self.res_resamp
|
|
1640
1591
|
dmax = disp_max / self.res_resamp
|
|
1641
|
-
|
|
1642
|
-
disp_range_grid = (
|
|
1592
|
+
# generate_disparity_grids runs orchestrator.breakpoint()
|
|
1593
|
+
self.pairs[pair_key]["disp_range_grid"] = (
|
|
1643
1594
|
self.dense_matching_app.generate_disparity_grids(
|
|
1644
1595
|
self.pairs[pair_key]["sensor_image_right"],
|
|
1645
1596
|
self.pairs[pair_key]["corrected_grid_right"],
|
|
@@ -1647,7 +1598,7 @@ class UnitPipeline(PipelineTemplate):
|
|
|
1647
1598
|
dmin=dmin,
|
|
1648
1599
|
dmax=dmax,
|
|
1649
1600
|
pair_folder=dense_matching_pair_folder,
|
|
1650
|
-
|
|
1601
|
+
orchestrator=self.cars_orchestrator,
|
|
1651
1602
|
)
|
|
1652
1603
|
)
|
|
1653
1604
|
|
|
@@ -1674,8 +1625,8 @@ class UnitPipeline(PipelineTemplate):
|
|
|
1674
1625
|
else:
|
|
1675
1626
|
if None in (altitude_delta_min, altitude_delta_max):
|
|
1676
1627
|
# Generate min and max disp grids from dems
|
|
1677
|
-
|
|
1678
|
-
disp_range_grid = (
|
|
1628
|
+
# generate_disparity_grids runs orchestrator.breakpoint()
|
|
1629
|
+
self.pairs[pair_key]["disp_range_grid"] = (
|
|
1679
1630
|
self.dense_matching_app.generate_disparity_grids(
|
|
1680
1631
|
self.pairs[pair_key]["sensor_image_right"],
|
|
1681
1632
|
self.pairs[pair_key]["corrected_grid_right"],
|
|
@@ -1684,12 +1635,13 @@ class UnitPipeline(PipelineTemplate):
|
|
|
1684
1635
|
dem_max=dem_max,
|
|
1685
1636
|
dem_median=dem_median,
|
|
1686
1637
|
pair_folder=dense_matching_pair_folder,
|
|
1687
|
-
|
|
1638
|
+
orchestrator=self.cars_orchestrator,
|
|
1688
1639
|
)
|
|
1689
1640
|
)
|
|
1690
1641
|
else:
|
|
1691
1642
|
# Generate min and max disp grids from deltas
|
|
1692
|
-
|
|
1643
|
+
# generate_disparity_grids runs orchestrator.breakpoint()
|
|
1644
|
+
self.pairs[pair_key]["disp_range_grid"] = (
|
|
1693
1645
|
self.dense_matching_app.generate_disparity_grids(
|
|
1694
1646
|
self.pairs[pair_key]["sensor_image_right"],
|
|
1695
1647
|
self.pairs[pair_key]["corrected_grid_right"],
|
|
@@ -1698,7 +1650,7 @@ class UnitPipeline(PipelineTemplate):
|
|
|
1698
1650
|
altitude_delta_max=altitude_delta_max,
|
|
1699
1651
|
dem_median=dem_median,
|
|
1700
1652
|
pair_folder=dense_matching_pair_folder,
|
|
1701
|
-
|
|
1653
|
+
orchestrator=self.cars_orchestrator,
|
|
1702
1654
|
)
|
|
1703
1655
|
)
|
|
1704
1656
|
|
|
@@ -1708,12 +1660,12 @@ class UnitPipeline(PipelineTemplate):
|
|
|
1708
1660
|
# TODO remove when only local diparity range will be used
|
|
1709
1661
|
|
|
1710
1662
|
if self.use_sift_a_priori:
|
|
1711
|
-
dmin =
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
dmax =
|
|
1715
|
-
|
|
1716
|
-
|
|
1663
|
+
dmin = self.pairs[pair_key]["disp_range_grid"][
|
|
1664
|
+
"global_min"
|
|
1665
|
+
]
|
|
1666
|
+
dmax = self.pairs[pair_key]["disp_range_grid"][
|
|
1667
|
+
"global_max"
|
|
1668
|
+
]
|
|
1717
1669
|
|
|
1718
1670
|
# update orchestrator_out_json
|
|
1719
1671
|
marg = self.sparse_mtch_sift_app.get_disparity_margin()
|
|
@@ -1737,7 +1689,8 @@ class UnitPipeline(PipelineTemplate):
|
|
|
1737
1689
|
pair_key=pair_key,
|
|
1738
1690
|
)
|
|
1739
1691
|
|
|
1740
|
-
|
|
1692
|
+
# generate_disparity_grids runs orchestrator.breakpoint()
|
|
1693
|
+
self.pairs[pair_key]["disp_range_grid"] = (
|
|
1741
1694
|
self.dense_matching_app.generate_disparity_grids(
|
|
1742
1695
|
self.pairs[pair_key]["sensor_image_right"],
|
|
1743
1696
|
self.pairs[pair_key]["corrected_grid_right"],
|
|
@@ -1745,34 +1698,23 @@ class UnitPipeline(PipelineTemplate):
|
|
|
1745
1698
|
dmin=dmin,
|
|
1746
1699
|
dmax=dmax,
|
|
1747
1700
|
pair_folder=dense_matching_pair_folder,
|
|
1748
|
-
|
|
1701
|
+
orchestrator=self.cars_orchestrator,
|
|
1749
1702
|
)
|
|
1750
1703
|
)
|
|
1751
|
-
# Get margins used in dense matching,
|
|
1752
|
-
dense_matching_margins_fun = (
|
|
1753
|
-
self.dense_matching_app.get_margins_fun(
|
|
1754
|
-
self.pairs[pair_key]["corrected_grid_left"],
|
|
1755
|
-
disp_range_grid,
|
|
1756
|
-
)
|
|
1757
|
-
)
|
|
1758
1704
|
|
|
1759
1705
|
# TODO add in metadata.json max diff max - min
|
|
1760
1706
|
# Update used_conf configuration with epipolar a priori
|
|
1761
1707
|
# Add global min and max computed with grids
|
|
1762
1708
|
advanced_parameters.update_conf(
|
|
1763
1709
|
self.used_conf,
|
|
1764
|
-
dmin=
|
|
1765
|
-
|
|
1766
|
-
), # TODO compute dmin dans dmax
|
|
1767
|
-
dmax=np.max(disp_range_grid[0, 0]["disp_max_grid"].values),
|
|
1710
|
+
dmin=self.pairs[pair_key]["disp_range_grid"]["global_min"],
|
|
1711
|
+
dmax=self.pairs[pair_key]["disp_range_grid"]["global_max"],
|
|
1768
1712
|
pair_key=pair_key,
|
|
1769
1713
|
)
|
|
1770
1714
|
advanced_parameters.update_conf(
|
|
1771
1715
|
self.config_full_res,
|
|
1772
|
-
dmin=
|
|
1773
|
-
|
|
1774
|
-
), # TODO compute dmin dans dmax
|
|
1775
|
-
dmax=np.max(disp_range_grid[0, 0]["disp_max_grid"].values),
|
|
1716
|
+
dmin=self.pairs[pair_key]["disp_range_grid"]["global_min"],
|
|
1717
|
+
dmax=self.pairs[pair_key]["disp_range_grid"]["global_max"],
|
|
1776
1718
|
pair_key=pair_key,
|
|
1777
1719
|
)
|
|
1778
1720
|
|
|
@@ -1783,6 +1725,10 @@ class UnitPipeline(PipelineTemplate):
|
|
|
1783
1725
|
safe_save=True,
|
|
1784
1726
|
)
|
|
1785
1727
|
|
|
1728
|
+
# end of for loop, to finish computing disparity range grids
|
|
1729
|
+
|
|
1730
|
+
for cloud_id, (pair_key, _, _) in enumerate(self.list_sensor_pairs):
|
|
1731
|
+
|
|
1786
1732
|
# Generate roi
|
|
1787
1733
|
epipolar_roi = preprocessing.compute_epipolar_roi(
|
|
1788
1734
|
self.input_roi_poly,
|
|
@@ -1793,10 +1739,8 @@ class UnitPipeline(PipelineTemplate):
|
|
|
1793
1739
|
self.pairs[pair_key]["corrected_grid_left"],
|
|
1794
1740
|
self.pairs[pair_key]["corrected_grid_right"],
|
|
1795
1741
|
os.path.join(self.dump_dir, "compute_epipolar_roi", pair_key),
|
|
1796
|
-
disp_min=
|
|
1797
|
-
|
|
1798
|
-
), # TODO compute dmin dans dmax
|
|
1799
|
-
disp_max=np.max(disp_range_grid[0, 0]["disp_max_grid"].values),
|
|
1742
|
+
disp_min=self.pairs[pair_key]["disp_range_grid"]["global_min"],
|
|
1743
|
+
disp_max=self.pairs[pair_key]["disp_range_grid"]["global_max"],
|
|
1800
1744
|
)
|
|
1801
1745
|
|
|
1802
1746
|
# Generate new epipolar images
|
|
@@ -1808,7 +1752,7 @@ class UnitPipeline(PipelineTemplate):
|
|
|
1808
1752
|
optimum_tile_size,
|
|
1809
1753
|
local_tile_optimal_size_fun,
|
|
1810
1754
|
) = self.dense_matching_app.get_optimal_tile_size(
|
|
1811
|
-
disp_range_grid,
|
|
1755
|
+
self.pairs[pair_key]["disp_range_grid"],
|
|
1812
1756
|
self.cars_orchestrator.cluster.checked_conf_cluster[
|
|
1813
1757
|
"max_ram_per_worker"
|
|
1814
1758
|
],
|
|
@@ -1828,6 +1772,14 @@ class UnitPipeline(PipelineTemplate):
|
|
|
1828
1772
|
for band in self.texture_bands
|
|
1829
1773
|
]
|
|
1830
1774
|
|
|
1775
|
+
# Get margins used in dense matching,
|
|
1776
|
+
dense_matching_margins_fun = (
|
|
1777
|
+
self.dense_matching_app.get_margins_fun(
|
|
1778
|
+
self.pairs[pair_key]["corrected_grid_left"],
|
|
1779
|
+
self.pairs[pair_key]["disp_range_grid"],
|
|
1780
|
+
)
|
|
1781
|
+
)
|
|
1782
|
+
|
|
1831
1783
|
# Run third epipolar resampling
|
|
1832
1784
|
(
|
|
1833
1785
|
new_epipolar_image_left,
|
|
@@ -1866,6 +1818,7 @@ class UnitPipeline(PipelineTemplate):
|
|
|
1866
1818
|
geoid=self.used_conf[ADVANCED][adv_cst.GROUND_TRUTH_DSM][
|
|
1867
1819
|
adv_cst.INPUT_GEOID
|
|
1868
1820
|
],
|
|
1821
|
+
scaling_coeff=self.scaling_coeff,
|
|
1869
1822
|
)
|
|
1870
1823
|
self.ground_truth_reprojection.run(
|
|
1871
1824
|
self.pairs[pair_key]["sensor_image_left"],
|
|
@@ -1889,6 +1842,131 @@ class UnitPipeline(PipelineTemplate):
|
|
|
1889
1842
|
),
|
|
1890
1843
|
)
|
|
1891
1844
|
|
|
1845
|
+
if self.epsg is None:
|
|
1846
|
+
# compute epsg
|
|
1847
|
+
# Epsg uses global disparity min and max
|
|
1848
|
+
self.epsg = preprocessing.compute_epsg(
|
|
1849
|
+
self.pairs[pair_key]["sensor_image_left"],
|
|
1850
|
+
self.pairs[pair_key]["sensor_image_right"],
|
|
1851
|
+
self.pairs[pair_key]["corrected_grid_left"],
|
|
1852
|
+
self.pairs[pair_key]["corrected_grid_right"],
|
|
1853
|
+
self.geom_plugin_with_dem_and_geoid,
|
|
1854
|
+
disp_min=self.pairs[pair_key]["disp_range_grid"][
|
|
1855
|
+
"global_min"
|
|
1856
|
+
],
|
|
1857
|
+
disp_max=self.pairs[pair_key]["disp_range_grid"][
|
|
1858
|
+
"global_max"
|
|
1859
|
+
],
|
|
1860
|
+
)
|
|
1861
|
+
# Compute roi polygon, in input EPSG
|
|
1862
|
+
self.roi_poly = preprocessing.compute_roi_poly(
|
|
1863
|
+
self.input_roi_poly, self.input_roi_epsg, self.epsg
|
|
1864
|
+
)
|
|
1865
|
+
|
|
1866
|
+
self.vertical_crs = projection.get_output_crs(self.epsg, output)
|
|
1867
|
+
|
|
1868
|
+
if (
|
|
1869
|
+
self.save_output_dsm
|
|
1870
|
+
or self.save_output_point_cloud
|
|
1871
|
+
or self.dense_matching_app.get_method() == "auto"
|
|
1872
|
+
):
|
|
1873
|
+
# Compute terrain bounding box /roi related to
|
|
1874
|
+
# current images
|
|
1875
|
+
(current_terrain_roi_bbox, intersection_poly) = (
|
|
1876
|
+
preprocessing.compute_terrain_bbox(
|
|
1877
|
+
self.pairs[pair_key]["sensor_image_left"],
|
|
1878
|
+
self.pairs[pair_key]["sensor_image_right"],
|
|
1879
|
+
new_epipolar_image_left,
|
|
1880
|
+
self.pairs[pair_key]["corrected_grid_left"],
|
|
1881
|
+
self.pairs[pair_key]["corrected_grid_right"],
|
|
1882
|
+
self.epsg,
|
|
1883
|
+
self.geom_plugin_with_dem_and_geoid,
|
|
1884
|
+
resolution=self.resolution,
|
|
1885
|
+
disp_min=self.pairs[pair_key]["disp_range_grid"][
|
|
1886
|
+
"global_min"
|
|
1887
|
+
],
|
|
1888
|
+
disp_max=self.pairs[pair_key]["disp_range_grid"][
|
|
1889
|
+
"global_max"
|
|
1890
|
+
],
|
|
1891
|
+
roi_poly=(
|
|
1892
|
+
None if self.debug_with_roi else self.roi_poly
|
|
1893
|
+
),
|
|
1894
|
+
orchestrator=self.cars_orchestrator,
|
|
1895
|
+
pair_key=pair_key,
|
|
1896
|
+
pair_folder=os.path.join(
|
|
1897
|
+
self.dump_dir, "terrain_bbox", pair_key
|
|
1898
|
+
),
|
|
1899
|
+
check_inputs=False,
|
|
1900
|
+
)
|
|
1901
|
+
)
|
|
1902
|
+
self.list_terrain_roi.append(current_terrain_roi_bbox)
|
|
1903
|
+
self.list_intersection_poly.append(intersection_poly)
|
|
1904
|
+
|
|
1905
|
+
# compute terrain bounds for later use
|
|
1906
|
+
(
|
|
1907
|
+
self.terrain_bounds,
|
|
1908
|
+
self.optimal_terrain_tile_width,
|
|
1909
|
+
) = preprocessing.compute_terrain_bounds(
|
|
1910
|
+
self.list_terrain_roi,
|
|
1911
|
+
roi_poly=(None if self.debug_with_roi else self.roi_poly),
|
|
1912
|
+
resolution=self.resolution,
|
|
1913
|
+
)
|
|
1914
|
+
|
|
1915
|
+
if self.which_resolution not in ("final", "single"):
|
|
1916
|
+
# To get the correct size for the dem generation
|
|
1917
|
+
if self.dem_generation_roi is not None:
|
|
1918
|
+
# ROI has been computed by Shareloc
|
|
1919
|
+
self.terrain_bounds = (
|
|
1920
|
+
dem_wrappers.modify_terrain_bounds(
|
|
1921
|
+
self.dem_generation_roi.bounds,
|
|
1922
|
+
4326,
|
|
1923
|
+
self.epsg,
|
|
1924
|
+
self.dem_generation_application.margin,
|
|
1925
|
+
)
|
|
1926
|
+
)
|
|
1927
|
+
else:
|
|
1928
|
+
# ROI has not been computed
|
|
1929
|
+
self.terrain_bounds = (
|
|
1930
|
+
dem_wrappers.modify_terrain_bounds(
|
|
1931
|
+
self.terrain_bounds,
|
|
1932
|
+
self.epsg,
|
|
1933
|
+
self.epsg,
|
|
1934
|
+
self.dem_generation_application.margin,
|
|
1935
|
+
0.7,
|
|
1936
|
+
)
|
|
1937
|
+
)
|
|
1938
|
+
|
|
1939
|
+
if self.dense_matching_app.get_method() == "auto":
|
|
1940
|
+
# Copy the initial corr_config in order to keep
|
|
1941
|
+
# the inputs that have already been checked
|
|
1942
|
+
corr_cfg = self.dense_matching_app.corr_config.copy()
|
|
1943
|
+
|
|
1944
|
+
# Find the conf that correspond to the land cover map
|
|
1945
|
+
conf = self.dense_matching_app.loader.find_auto_conf(
|
|
1946
|
+
intersection_poly,
|
|
1947
|
+
self.land_cover_map,
|
|
1948
|
+
self.classification_to_config_mapping,
|
|
1949
|
+
self.epsg,
|
|
1950
|
+
)
|
|
1951
|
+
|
|
1952
|
+
# Update the used_conf if order to reinitialize
|
|
1953
|
+
# the dense matching app
|
|
1954
|
+
# Because we kept the information regarding the ambiguity,
|
|
1955
|
+
# performance_map calculus..
|
|
1956
|
+
self.used_conf["applications"]["dense_matching"]["loader_conf"][
|
|
1957
|
+
"pipeline"
|
|
1958
|
+
] = conf["pipeline"]
|
|
1959
|
+
|
|
1960
|
+
# Re initialization of the dense matching application
|
|
1961
|
+
self.dense_matching_app = Application(
|
|
1962
|
+
"dense_matching",
|
|
1963
|
+
cfg=self.used_conf["applications"]["dense_matching"],
|
|
1964
|
+
)
|
|
1965
|
+
|
|
1966
|
+
# Update the corr_config with the inputs that have
|
|
1967
|
+
# already been checked
|
|
1968
|
+
self.dense_matching_app.corr_config["input"] = corr_cfg["input"]
|
|
1969
|
+
|
|
1892
1970
|
# Run epipolar matching application
|
|
1893
1971
|
epipolar_disparity_map = self.dense_matching_app.run(
|
|
1894
1972
|
new_epipolar_image_left,
|
|
@@ -1899,7 +1977,7 @@ class UnitPipeline(PipelineTemplate):
|
|
|
1899
1977
|
self.dump_dir, "dense_matching", pair_key
|
|
1900
1978
|
),
|
|
1901
1979
|
pair_key=pair_key,
|
|
1902
|
-
disp_range_grid=disp_range_grid,
|
|
1980
|
+
disp_range_grid=self.pairs[pair_key]["disp_range_grid"],
|
|
1903
1981
|
compute_disparity_masks=False,
|
|
1904
1982
|
margins_to_keep=(
|
|
1905
1983
|
self.pc_outlier_removal_1_app.get_epipolar_margin()
|
|
@@ -1919,11 +1997,13 @@ class UnitPipeline(PipelineTemplate):
|
|
|
1919
1997
|
epipolar_disparity_map,
|
|
1920
1998
|
self.pairs[pair_key]["holes_bbox_left"],
|
|
1921
1999
|
self.pairs[pair_key]["holes_bbox_right"],
|
|
1922
|
-
disp_min=
|
|
1923
|
-
|
|
1924
|
-
|
|
2000
|
+
disp_min=self.pairs[pair_key]["disp_range_grid"][
|
|
2001
|
+
"global_min"
|
|
2002
|
+
],
|
|
1925
2003
|
disp_max=np.max(
|
|
1926
|
-
|
|
2004
|
+
self.pairs[pair_key]["disp_range_grid"][
|
|
2005
|
+
"global_max"
|
|
2006
|
+
]
|
|
1927
2007
|
),
|
|
1928
2008
|
orchestrator=self.cars_orchestrator,
|
|
1929
2009
|
pair_folder=os.path.join(
|
|
@@ -1955,11 +2035,13 @@ class UnitPipeline(PipelineTemplate):
|
|
|
1955
2035
|
filled_with_1_epipolar_disparity_map,
|
|
1956
2036
|
self.pairs[pair_key]["holes_bbox_left"],
|
|
1957
2037
|
self.pairs[pair_key]["holes_bbox_right"],
|
|
1958
|
-
disp_min=
|
|
1959
|
-
|
|
1960
|
-
|
|
2038
|
+
disp_min=self.pairs[pair_key]["disp_range_grid"][
|
|
2039
|
+
"global_min"
|
|
2040
|
+
],
|
|
1961
2041
|
disp_max=np.max(
|
|
1962
|
-
|
|
2042
|
+
self.pairs[pair_key]["disp_range_grid"][
|
|
2043
|
+
"global_max"
|
|
2044
|
+
]
|
|
1963
2045
|
),
|
|
1964
2046
|
orchestrator=self.cars_orchestrator,
|
|
1965
2047
|
pair_folder=os.path.join(
|
|
@@ -1984,27 +2066,6 @@ class UnitPipeline(PipelineTemplate):
|
|
|
1984
2066
|
if self.quit_on_app("dense_match_filling.2"):
|
|
1985
2067
|
continue # keep iterating over pairs, but don't go further
|
|
1986
2068
|
|
|
1987
|
-
if self.epsg is None:
|
|
1988
|
-
# compute epsg
|
|
1989
|
-
# Epsg uses global disparity min and max
|
|
1990
|
-
self.epsg = preprocessing.compute_epsg(
|
|
1991
|
-
self.pairs[pair_key]["sensor_image_left"],
|
|
1992
|
-
self.pairs[pair_key]["sensor_image_right"],
|
|
1993
|
-
self.pairs[pair_key]["corrected_grid_left"],
|
|
1994
|
-
self.pairs[pair_key]["corrected_grid_right"],
|
|
1995
|
-
self.geom_plugin_with_dem_and_geoid,
|
|
1996
|
-
disp_min=np.min(
|
|
1997
|
-
disp_range_grid[0, 0]["disp_min_grid"].values
|
|
1998
|
-
),
|
|
1999
|
-
disp_max=np.max(
|
|
2000
|
-
disp_range_grid[0, 0]["disp_max_grid"].values
|
|
2001
|
-
),
|
|
2002
|
-
)
|
|
2003
|
-
# Compute roi polygon, in input EPSG
|
|
2004
|
-
self.roi_poly = preprocessing.compute_roi_poly(
|
|
2005
|
-
self.input_roi_poly, self.input_roi_epsg, self.epsg
|
|
2006
|
-
)
|
|
2007
|
-
|
|
2008
2069
|
if isinstance(output[sens_cst.GEOID], str):
|
|
2009
2070
|
output_geoid_path = output[sens_cst.GEOID]
|
|
2010
2071
|
elif (
|
|
@@ -2200,57 +2261,6 @@ class UnitPipeline(PipelineTemplate):
|
|
|
2200
2261
|
# keep iterating over pairs, but don't go further
|
|
2201
2262
|
continue
|
|
2202
2263
|
|
|
2203
|
-
if self.save_output_dsm or self.save_output_point_cloud:
|
|
2204
|
-
# Compute terrain bounding box /roi related to
|
|
2205
|
-
# current images
|
|
2206
|
-
(current_terrain_roi_bbox, intersection_poly) = (
|
|
2207
|
-
preprocessing.compute_terrain_bbox(
|
|
2208
|
-
self.pairs[pair_key]["sensor_image_left"],
|
|
2209
|
-
self.pairs[pair_key]["sensor_image_right"],
|
|
2210
|
-
new_epipolar_image_left,
|
|
2211
|
-
self.pairs[pair_key]["corrected_grid_left"],
|
|
2212
|
-
self.pairs[pair_key]["corrected_grid_right"],
|
|
2213
|
-
self.epsg,
|
|
2214
|
-
self.geom_plugin_with_dem_and_geoid,
|
|
2215
|
-
resolution=self.resolution,
|
|
2216
|
-
disp_min=np.min(
|
|
2217
|
-
disp_range_grid[0, 0]["disp_min_grid"].values
|
|
2218
|
-
),
|
|
2219
|
-
disp_max=np.max(
|
|
2220
|
-
disp_range_grid[0, 0]["disp_max_grid"].values
|
|
2221
|
-
),
|
|
2222
|
-
roi_poly=(
|
|
2223
|
-
None if self.debug_with_roi else self.roi_poly
|
|
2224
|
-
),
|
|
2225
|
-
orchestrator=self.cars_orchestrator,
|
|
2226
|
-
pair_key=pair_key,
|
|
2227
|
-
pair_folder=os.path.join(
|
|
2228
|
-
self.dump_dir, "terrain_bbox", pair_key
|
|
2229
|
-
),
|
|
2230
|
-
check_inputs=False,
|
|
2231
|
-
)
|
|
2232
|
-
)
|
|
2233
|
-
self.list_terrain_roi.append(current_terrain_roi_bbox)
|
|
2234
|
-
self.list_intersection_poly.append(intersection_poly)
|
|
2235
|
-
|
|
2236
|
-
# compute terrain bounds for later use
|
|
2237
|
-
(
|
|
2238
|
-
self.terrain_bounds,
|
|
2239
|
-
self.optimal_terrain_tile_width,
|
|
2240
|
-
) = preprocessing.compute_terrain_bounds(
|
|
2241
|
-
self.list_terrain_roi,
|
|
2242
|
-
roi_poly=(None if self.debug_with_roi else self.roi_poly),
|
|
2243
|
-
resolution=self.resolution,
|
|
2244
|
-
)
|
|
2245
|
-
|
|
2246
|
-
if self.which_resolution not in ("final", "single"):
|
|
2247
|
-
# To get the correct size for the dem generation
|
|
2248
|
-
self.terrain_bounds = dem_wrappers.modify_terrain_bounds(
|
|
2249
|
-
self.dem_generation_roi,
|
|
2250
|
-
self.epsg,
|
|
2251
|
-
self.dem_generation_application.margin,
|
|
2252
|
-
)
|
|
2253
|
-
|
|
2254
2264
|
# quit if any app in the loop over the pairs was the last one
|
|
2255
2265
|
# pylint:disable=too-many-boolean-expressions
|
|
2256
2266
|
if (
|
|
@@ -2390,6 +2400,7 @@ class UnitPipeline(PipelineTemplate):
|
|
|
2390
2400
|
_ = self.rasterization_application.run(
|
|
2391
2401
|
self.point_cloud_to_rasterize,
|
|
2392
2402
|
self.epsg,
|
|
2403
|
+
self.vertical_crs,
|
|
2393
2404
|
resolution=self.resolution,
|
|
2394
2405
|
orchestrator=self.cars_orchestrator,
|
|
2395
2406
|
dsm_file_name=dsm_file_name,
|
|
@@ -2488,14 +2499,16 @@ class UnitPipeline(PipelineTemplate):
|
|
|
2488
2499
|
dem_min_file_name,
|
|
2489
2500
|
dem_max_file_name,
|
|
2490
2501
|
dem_median_file_name,
|
|
2491
|
-
self.used_conf[INPUTS][sens_cst.INITIAL_ELEVATION][
|
|
2502
|
+
input_geoid=self.used_conf[INPUTS][sens_cst.INITIAL_ELEVATION][
|
|
2492
2503
|
sens_cst.GEOID
|
|
2493
2504
|
],
|
|
2505
|
+
output_geoid=self.used_conf[OUTPUT][out_cst.OUT_GEOID],
|
|
2494
2506
|
initial_elevation=(
|
|
2495
2507
|
self.used_conf[INPUTS][sens_cst.INITIAL_ELEVATION][
|
|
2496
2508
|
sens_cst.DEM_PATH
|
|
2497
2509
|
]
|
|
2498
2510
|
),
|
|
2511
|
+
default_alt=self.geom_plugin_with_dem_and_geoid.default_alt,
|
|
2499
2512
|
cars_orchestrator=self.cars_orchestrator,
|
|
2500
2513
|
)
|
|
2501
2514
|
|
|
@@ -2539,7 +2552,7 @@ class UnitPipeline(PipelineTemplate):
|
|
|
2539
2552
|
for key in dsm_dict.keys():
|
|
2540
2553
|
for path_name in dsm_dict[key].keys():
|
|
2541
2554
|
if dsm_dict[key][path_name] is not None:
|
|
2542
|
-
if
|
|
2555
|
+
if isinstance(dsm_dict[key][path_name], str):
|
|
2543
2556
|
if path_name not in dict_path:
|
|
2544
2557
|
dict_path[path_name] = [
|
|
2545
2558
|
dsm_dict[key][path_name]
|
|
@@ -2548,22 +2561,6 @@ class UnitPipeline(PipelineTemplate):
|
|
|
2548
2561
|
dict_path[path_name].append(
|
|
2549
2562
|
dsm_dict[key][path_name]
|
|
2550
2563
|
)
|
|
2551
|
-
else:
|
|
2552
|
-
for confidence_path_name in dsm_dict[key][
|
|
2553
|
-
path_name
|
|
2554
|
-
].keys():
|
|
2555
|
-
if confidence_path_name not in dict_path:
|
|
2556
|
-
dict_path[confidence_path_name] = [
|
|
2557
|
-
dsm_dict[key][path_name][
|
|
2558
|
-
confidence_path_name
|
|
2559
|
-
]
|
|
2560
|
-
]
|
|
2561
|
-
else:
|
|
2562
|
-
dict_path[confidence_path_name].append(
|
|
2563
|
-
dsm_dict[key][path_name][
|
|
2564
|
-
confidence_path_name
|
|
2565
|
-
]
|
|
2566
|
-
)
|
|
2567
2564
|
|
|
2568
2565
|
color_file_name = (
|
|
2569
2566
|
os.path.join(
|
|
@@ -2642,6 +2639,7 @@ class UnitPipeline(PipelineTemplate):
|
|
|
2642
2639
|
)
|
|
2643
2640
|
|
|
2644
2641
|
self.epsg = rasterio_get_epsg(dict_path["dsm"][0])
|
|
2642
|
+
self.vertical_crs = rasterio_get_crs(dict_path["dsm"][0])
|
|
2645
2643
|
|
|
2646
2644
|
# Compute roi polygon, in input EPSG
|
|
2647
2645
|
self.roi_poly = preprocessing.compute_roi_poly(
|
|
@@ -2771,9 +2769,9 @@ class UnitPipeline(PipelineTemplate):
|
|
|
2771
2769
|
)
|
|
2772
2770
|
|
|
2773
2771
|
# Project polygon if epsg is different
|
|
2774
|
-
if self.
|
|
2775
|
-
inter_poly = projection.
|
|
2776
|
-
inter_poly, inter_epsg, self.
|
|
2772
|
+
if self.vertical_crs != CRS(inter_epsg):
|
|
2773
|
+
inter_poly = projection.polygon_projection_crs(
|
|
2774
|
+
inter_poly, CRS(inter_epsg), self.vertical_crs
|
|
2777
2775
|
)
|
|
2778
2776
|
|
|
2779
2777
|
self.list_intersection_poly.append(inter_poly)
|
|
@@ -2944,6 +2942,10 @@ class UnitPipeline(PipelineTemplate):
|
|
|
2944
2942
|
if self.epsg is None:
|
|
2945
2943
|
self.epsg = epsg_cloud
|
|
2946
2944
|
|
|
2945
|
+
self.vertical_crs = projection.get_output_crs(
|
|
2946
|
+
self.epsg, self.used_conf[OUTPUT]
|
|
2947
|
+
)
|
|
2948
|
+
|
|
2947
2949
|
self.resolution = (
|
|
2948
2950
|
self.used_conf[OUTPUT][out_cst.RESOLUTION] * self.res_resamp
|
|
2949
2951
|
)
|