cars 1.0.0rc3__cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.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.
- cars/__init__.py +74 -0
- cars/applications/__init__.py +40 -0
- cars/applications/application.py +117 -0
- cars/applications/application_constants.py +29 -0
- cars/applications/application_template.py +146 -0
- cars/applications/auxiliary_filling/__init__.py +29 -0
- cars/applications/auxiliary_filling/abstract_auxiliary_filling_app.py +105 -0
- cars/applications/auxiliary_filling/auxiliary_filling_algo.py +475 -0
- cars/applications/auxiliary_filling/auxiliary_filling_from_sensors_app.py +632 -0
- cars/applications/auxiliary_filling/auxiliary_filling_wrappers.py +90 -0
- cars/applications/dem_generation/__init__.py +30 -0
- cars/applications/dem_generation/abstract_dem_generation_app.py +116 -0
- cars/applications/dem_generation/bulldozer_config/base_config.yaml +46 -0
- cars/applications/dem_generation/bulldozer_dem_app.py +641 -0
- cars/applications/dem_generation/bulldozer_memory.py +55 -0
- cars/applications/dem_generation/dem_generation_algo.py +107 -0
- cars/applications/dem_generation/dem_generation_constants.py +32 -0
- cars/applications/dem_generation/dem_generation_wrappers.py +323 -0
- cars/applications/dense_match_filling/__init__.py +30 -0
- cars/applications/dense_match_filling/abstract_dense_match_filling_app.py +242 -0
- cars/applications/dense_match_filling/fill_disp_algo.py +113 -0
- cars/applications/dense_match_filling/fill_disp_constants.py +39 -0
- cars/applications/dense_match_filling/fill_disp_wrappers.py +83 -0
- cars/applications/dense_match_filling/zero_padding_app.py +302 -0
- cars/applications/dense_matching/__init__.py +30 -0
- cars/applications/dense_matching/abstract_dense_matching_app.py +261 -0
- cars/applications/dense_matching/census_mccnn_sgm_app.py +1461 -0
- cars/applications/dense_matching/cpp/__init__.py +0 -0
- cars/applications/dense_matching/cpp/dense_matching_cpp.cpython-313-x86_64-linux-gnu.so +0 -0
- cars/applications/dense_matching/cpp/dense_matching_cpp.py +94 -0
- cars/applications/dense_matching/cpp/includes/dense_matching.hpp +58 -0
- cars/applications/dense_matching/cpp/meson.build +9 -0
- cars/applications/dense_matching/cpp/src/bindings.cpp +13 -0
- cars/applications/dense_matching/cpp/src/dense_matching.cpp +207 -0
- cars/applications/dense_matching/dense_matching_algo.py +401 -0
- cars/applications/dense_matching/dense_matching_constants.py +89 -0
- cars/applications/dense_matching/dense_matching_wrappers.py +951 -0
- cars/applications/dense_matching/disparity_grid_algo.py +597 -0
- cars/applications/dense_matching/loaders/__init__.py +23 -0
- cars/applications/dense_matching/loaders/config_census_sgm_default.json +31 -0
- cars/applications/dense_matching/loaders/config_census_sgm_homogeneous.json +30 -0
- cars/applications/dense_matching/loaders/config_census_sgm_mountain_and_vegetation.json +30 -0
- cars/applications/dense_matching/loaders/config_census_sgm_shadow.json +30 -0
- cars/applications/dense_matching/loaders/config_census_sgm_sparse.json +36 -0
- cars/applications/dense_matching/loaders/config_census_sgm_urban.json +30 -0
- cars/applications/dense_matching/loaders/config_mapping.json +13 -0
- cars/applications/dense_matching/loaders/config_mccnn.json +28 -0
- cars/applications/dense_matching/loaders/global_land_cover_map.tif +0 -0
- cars/applications/dense_matching/loaders/pandora_loader.py +593 -0
- cars/applications/dsm_filling/__init__.py +32 -0
- cars/applications/dsm_filling/abstract_dsm_filling_app.py +101 -0
- cars/applications/dsm_filling/border_interpolation_app.py +278 -0
- cars/applications/dsm_filling/bulldozer_config/base_config.yaml +44 -0
- cars/applications/dsm_filling/bulldozer_filling_app.py +288 -0
- cars/applications/dsm_filling/exogenous_filling_app.py +341 -0
- cars/applications/dsm_merging/__init__.py +28 -0
- cars/applications/dsm_merging/abstract_dsm_merging_app.py +101 -0
- cars/applications/dsm_merging/weighted_fusion_app.py +639 -0
- cars/applications/grid_correction/__init__.py +30 -0
- cars/applications/grid_correction/abstract_grid_correction_app.py +103 -0
- cars/applications/grid_correction/grid_correction_app.py +557 -0
- cars/applications/grid_generation/__init__.py +30 -0
- cars/applications/grid_generation/abstract_grid_generation_app.py +142 -0
- cars/applications/grid_generation/epipolar_grid_generation_app.py +327 -0
- cars/applications/grid_generation/grid_generation_algo.py +388 -0
- cars/applications/grid_generation/grid_generation_constants.py +46 -0
- cars/applications/grid_generation/transform_grid.py +88 -0
- cars/applications/ground_truth_reprojection/__init__.py +30 -0
- cars/applications/ground_truth_reprojection/abstract_ground_truth_reprojection_app.py +137 -0
- cars/applications/ground_truth_reprojection/direct_localization_app.py +629 -0
- cars/applications/ground_truth_reprojection/ground_truth_reprojection_algo.py +275 -0
- cars/applications/point_cloud_outlier_removal/__init__.py +30 -0
- cars/applications/point_cloud_outlier_removal/abstract_outlier_removal_app.py +385 -0
- cars/applications/point_cloud_outlier_removal/outlier_removal_algo.py +392 -0
- cars/applications/point_cloud_outlier_removal/outlier_removal_constants.py +43 -0
- cars/applications/point_cloud_outlier_removal/small_components_app.py +522 -0
- cars/applications/point_cloud_outlier_removal/statistical_app.py +528 -0
- cars/applications/rasterization/__init__.py +30 -0
- cars/applications/rasterization/abstract_pc_rasterization_app.py +183 -0
- cars/applications/rasterization/rasterization_algo.py +534 -0
- cars/applications/rasterization/rasterization_constants.py +38 -0
- cars/applications/rasterization/rasterization_wrappers.py +639 -0
- cars/applications/rasterization/simple_gaussian_app.py +1152 -0
- cars/applications/resampling/__init__.py +28 -0
- cars/applications/resampling/abstract_resampling_app.py +187 -0
- cars/applications/resampling/bicubic_resampling_app.py +760 -0
- cars/applications/resampling/resampling_algo.py +590 -0
- cars/applications/resampling/resampling_constants.py +36 -0
- cars/applications/resampling/resampling_wrappers.py +309 -0
- cars/applications/sensors_subsampling/__init__.py +32 -0
- cars/applications/sensors_subsampling/abstract_subsampling_app.py +109 -0
- cars/applications/sensors_subsampling/rasterio_subsampling_app.py +420 -0
- cars/applications/sensors_subsampling/subsampling_algo.py +108 -0
- cars/applications/sparse_matching/__init__.py +30 -0
- cars/applications/sparse_matching/abstract_sparse_matching_app.py +599 -0
- cars/applications/sparse_matching/sift_app.py +724 -0
- cars/applications/sparse_matching/sparse_matching_algo.py +360 -0
- cars/applications/sparse_matching/sparse_matching_constants.py +66 -0
- cars/applications/sparse_matching/sparse_matching_wrappers.py +282 -0
- cars/applications/triangulation/__init__.py +32 -0
- cars/applications/triangulation/abstract_triangulation_app.py +227 -0
- cars/applications/triangulation/line_of_sight_intersection_app.py +1243 -0
- cars/applications/triangulation/pc_transform.py +552 -0
- cars/applications/triangulation/triangulation_algo.py +371 -0
- cars/applications/triangulation/triangulation_constants.py +38 -0
- cars/applications/triangulation/triangulation_wrappers.py +259 -0
- cars/bundleadjustment.py +750 -0
- cars/cars.py +179 -0
- cars/conf/__init__.py +23 -0
- cars/conf/geoid/egm96.grd +0 -0
- cars/conf/geoid/egm96.grd.hdr +15 -0
- cars/conf/input_parameters.py +156 -0
- cars/conf/mask_cst.py +35 -0
- cars/core/__init__.py +23 -0
- cars/core/cars_logging.py +402 -0
- cars/core/constants.py +191 -0
- cars/core/constants_disparity.py +50 -0
- cars/core/datasets.py +140 -0
- cars/core/geometry/__init__.py +27 -0
- cars/core/geometry/abstract_geometry.py +1130 -0
- cars/core/geometry/shareloc_geometry.py +604 -0
- cars/core/inputs.py +568 -0
- cars/core/outputs.py +176 -0
- cars/core/preprocessing.py +722 -0
- cars/core/projection.py +843 -0
- cars/core/roi_tools.py +215 -0
- cars/core/tiling.py +774 -0
- cars/core/utils.py +164 -0
- cars/data_structures/__init__.py +23 -0
- cars/data_structures/cars_dataset.py +1544 -0
- cars/data_structures/cars_dict.py +74 -0
- cars/data_structures/corresponding_tiles_tools.py +186 -0
- cars/data_structures/dataframe_converter.py +185 -0
- cars/data_structures/format_transformation.py +297 -0
- cars/devibrate.py +689 -0
- cars/extractroi.py +264 -0
- cars/orchestrator/__init__.py +23 -0
- cars/orchestrator/achievement_tracker.py +125 -0
- cars/orchestrator/cluster/__init__.py +37 -0
- cars/orchestrator/cluster/abstract_cluster.py +250 -0
- cars/orchestrator/cluster/abstract_dask_cluster.py +381 -0
- cars/orchestrator/cluster/dask_cluster_tools.py +103 -0
- cars/orchestrator/cluster/dask_config/README.md +94 -0
- cars/orchestrator/cluster/dask_config/dask.yaml +21 -0
- cars/orchestrator/cluster/dask_config/distributed.yaml +70 -0
- cars/orchestrator/cluster/dask_config/jobqueue.yaml +26 -0
- cars/orchestrator/cluster/dask_config/reference_confs/dask-schema.yaml +137 -0
- cars/orchestrator/cluster/dask_config/reference_confs/dask.yaml +26 -0
- cars/orchestrator/cluster/dask_config/reference_confs/distributed-schema.yaml +1009 -0
- cars/orchestrator/cluster/dask_config/reference_confs/distributed.yaml +273 -0
- cars/orchestrator/cluster/dask_config/reference_confs/jobqueue.yaml +212 -0
- cars/orchestrator/cluster/dask_jobqueue_utils.py +204 -0
- cars/orchestrator/cluster/local_dask_cluster.py +116 -0
- cars/orchestrator/cluster/log_wrapper.py +728 -0
- cars/orchestrator/cluster/mp_cluster/__init__.py +27 -0
- cars/orchestrator/cluster/mp_cluster/mp_factorizer.py +212 -0
- cars/orchestrator/cluster/mp_cluster/mp_objects.py +535 -0
- cars/orchestrator/cluster/mp_cluster/mp_tools.py +93 -0
- cars/orchestrator/cluster/mp_cluster/mp_wrapper.py +505 -0
- cars/orchestrator/cluster/mp_cluster/multiprocessing_cluster.py +986 -0
- cars/orchestrator/cluster/mp_cluster/multiprocessing_profiler.py +399 -0
- cars/orchestrator/cluster/pbs_dask_cluster.py +207 -0
- cars/orchestrator/cluster/sequential_cluster.py +139 -0
- cars/orchestrator/cluster/slurm_dask_cluster.py +234 -0
- cars/orchestrator/memory_tools.py +47 -0
- cars/orchestrator/orchestrator.py +755 -0
- cars/orchestrator/orchestrator_constants.py +29 -0
- cars/orchestrator/registry/__init__.py +23 -0
- cars/orchestrator/registry/abstract_registry.py +143 -0
- cars/orchestrator/registry/compute_registry.py +106 -0
- cars/orchestrator/registry/id_generator.py +116 -0
- cars/orchestrator/registry/replacer_registry.py +213 -0
- cars/orchestrator/registry/saver_registry.py +363 -0
- cars/orchestrator/registry/unseen_registry.py +118 -0
- cars/orchestrator/tiles_profiler.py +279 -0
- cars/pipelines/__init__.py +26 -0
- cars/pipelines/conf_resolution/conf_final_resolution.yaml +5 -0
- cars/pipelines/conf_resolution/conf_first_resolution.yaml +4 -0
- cars/pipelines/conf_resolution/conf_intermediate_resolution.yaml +2 -0
- cars/pipelines/default/__init__.py +26 -0
- cars/pipelines/default/default_pipeline.py +1095 -0
- cars/pipelines/filling/__init__.py +26 -0
- cars/pipelines/filling/filling.py +981 -0
- cars/pipelines/formatting/__init__.py +26 -0
- cars/pipelines/formatting/formatting.py +190 -0
- cars/pipelines/merging/__init__.py +26 -0
- cars/pipelines/merging/merging.py +439 -0
- cars/pipelines/parameters/__init__.py +0 -0
- cars/pipelines/parameters/advanced_parameters.py +256 -0
- cars/pipelines/parameters/advanced_parameters_constants.py +68 -0
- cars/pipelines/parameters/application_parameters.py +72 -0
- cars/pipelines/parameters/depth_map_inputs.py +0 -0
- cars/pipelines/parameters/dsm_inputs.py +349 -0
- cars/pipelines/parameters/dsm_inputs_constants.py +25 -0
- cars/pipelines/parameters/output_constants.py +52 -0
- cars/pipelines/parameters/output_parameters.py +435 -0
- cars/pipelines/parameters/sensor_inputs.py +859 -0
- cars/pipelines/parameters/sensor_inputs_constants.py +51 -0
- cars/pipelines/parameters/sensor_loaders/__init__.py +29 -0
- cars/pipelines/parameters/sensor_loaders/basic_classif_loader.py +86 -0
- cars/pipelines/parameters/sensor_loaders/basic_image_loader.py +98 -0
- cars/pipelines/parameters/sensor_loaders/pivot_classif_loader.py +90 -0
- cars/pipelines/parameters/sensor_loaders/pivot_image_loader.py +105 -0
- cars/pipelines/parameters/sensor_loaders/sensor_loader.py +93 -0
- cars/pipelines/parameters/sensor_loaders/sensor_loader_template.py +71 -0
- cars/pipelines/parameters/sensor_loaders/slurp_classif_loader.py +86 -0
- cars/pipelines/pipeline.py +119 -0
- cars/pipelines/pipeline_constants.py +38 -0
- cars/pipelines/pipeline_template.py +135 -0
- cars/pipelines/subsampling/__init__.py +26 -0
- cars/pipelines/subsampling/subsampling.py +358 -0
- cars/pipelines/surface_modeling/__init__.py +26 -0
- cars/pipelines/surface_modeling/surface_modeling.py +2098 -0
- cars/pipelines/tie_points/__init__.py +26 -0
- cars/pipelines/tie_points/tie_points.py +536 -0
- cars/starter.py +167 -0
- cars-1.0.0rc3.dist-info/METADATA +289 -0
- cars-1.0.0rc3.dist-info/RECORD +220 -0
- cars-1.0.0rc3.dist-info/WHEEL +6 -0
- cars-1.0.0rc3.dist-info/entry_points.txt +8 -0
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
# coding: utf8
|
|
3
|
+
#
|
|
4
|
+
# Copyright (c) 2020 Centre National d'Etudes Spatiales (CNES).
|
|
5
|
+
#
|
|
6
|
+
# This file is part of CARS
|
|
7
|
+
# (see https://github.com/CNES/cars).
|
|
8
|
+
#
|
|
9
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
10
|
+
# you may not use this file except in compliance with the License.
|
|
11
|
+
# You may obtain a copy of the License at
|
|
12
|
+
#
|
|
13
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
14
|
+
#
|
|
15
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
16
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
17
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
18
|
+
# See the License for the specific language governing permissions and
|
|
19
|
+
# limitations under the License.
|
|
20
|
+
#
|
|
21
|
+
"""
|
|
22
|
+
this module contains the abstract grid generation application class.
|
|
23
|
+
"""
|
|
24
|
+
import logging
|
|
25
|
+
from abc import ABCMeta, abstractmethod
|
|
26
|
+
from typing import Dict
|
|
27
|
+
|
|
28
|
+
from cars.applications.application import Application
|
|
29
|
+
from cars.applications.application_template import ApplicationTemplate
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
@Application.register("grid_correction")
|
|
33
|
+
class GridCorrection(ApplicationTemplate, metaclass=ABCMeta):
|
|
34
|
+
"""
|
|
35
|
+
AbstractGridCorrection
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
available_applications: Dict = {}
|
|
39
|
+
default_application = "default"
|
|
40
|
+
|
|
41
|
+
def __new__(cls, conf=None): # pylint: disable=W0613
|
|
42
|
+
"""
|
|
43
|
+
Return the required application
|
|
44
|
+
:raises:
|
|
45
|
+
- KeyError when the required application is not registered
|
|
46
|
+
|
|
47
|
+
:param conf: configuration for grid generation
|
|
48
|
+
:return: a application_to_use object
|
|
49
|
+
"""
|
|
50
|
+
|
|
51
|
+
grid_method = cls.default_application
|
|
52
|
+
|
|
53
|
+
if bool(conf) is False or "method" not in conf:
|
|
54
|
+
logging.info(
|
|
55
|
+
"Grid correction method not specified, default "
|
|
56
|
+
" {} is used".format(grid_method)
|
|
57
|
+
)
|
|
58
|
+
else:
|
|
59
|
+
grid_method = conf.get("method", cls.default_application)
|
|
60
|
+
|
|
61
|
+
if grid_method not in cls.available_applications:
|
|
62
|
+
logging.error(
|
|
63
|
+
"No GridCorrection application named {} registered".format(
|
|
64
|
+
grid_method
|
|
65
|
+
)
|
|
66
|
+
)
|
|
67
|
+
raise KeyError(
|
|
68
|
+
"No GridCorrection application named {} registered".format(
|
|
69
|
+
grid_method
|
|
70
|
+
)
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
logging.info(
|
|
74
|
+
"The GridCorrection({}) application will be used".format(
|
|
75
|
+
grid_method
|
|
76
|
+
)
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
return super(GridCorrection, cls).__new__(
|
|
80
|
+
cls.available_applications[grid_method]
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
def __init_subclass__(cls, short_name, **kwargs): # pylint: disable=E0302
|
|
84
|
+
super().__init_subclass__(**kwargs)
|
|
85
|
+
cls.available_applications[short_name] = cls
|
|
86
|
+
|
|
87
|
+
def __init__(self, conf=None):
|
|
88
|
+
"""
|
|
89
|
+
Init function of GridGeneration
|
|
90
|
+
|
|
91
|
+
:param conf: configuration
|
|
92
|
+
:return: an application_to_use object
|
|
93
|
+
"""
|
|
94
|
+
|
|
95
|
+
super().__init__(conf=conf)
|
|
96
|
+
|
|
97
|
+
@abstractmethod
|
|
98
|
+
def run( # pylint: disable=too-many-positional-arguments
|
|
99
|
+
self,
|
|
100
|
+
):
|
|
101
|
+
"""
|
|
102
|
+
Run GridCorrection application
|
|
103
|
+
"""
|
|
@@ -0,0 +1,557 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
# coding: utf8
|
|
3
|
+
#
|
|
4
|
+
# Copyright (c) 2020 Centre National d'Etudes Spatiales (CNES).
|
|
5
|
+
#
|
|
6
|
+
# This file is part of CARS
|
|
7
|
+
# (see https://github.com/CNES/cars).
|
|
8
|
+
#
|
|
9
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
10
|
+
# you may not use this file except in compliance with the License.
|
|
11
|
+
# You may obtain a copy of the License at
|
|
12
|
+
#
|
|
13
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
14
|
+
#
|
|
15
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
16
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
17
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
18
|
+
# See the License for the specific language governing permissions and
|
|
19
|
+
# limitations under the License.
|
|
20
|
+
#
|
|
21
|
+
"""
|
|
22
|
+
this module contains the epipolar grid correction application class.
|
|
23
|
+
"""
|
|
24
|
+
# Standard imports
|
|
25
|
+
from __future__ import absolute_import
|
|
26
|
+
|
|
27
|
+
# Standard imports
|
|
28
|
+
import logging
|
|
29
|
+
import os
|
|
30
|
+
|
|
31
|
+
import numpy as np
|
|
32
|
+
|
|
33
|
+
# Third party imports
|
|
34
|
+
import rasterio as rio
|
|
35
|
+
|
|
36
|
+
# Third party imports
|
|
37
|
+
from json_checker import And, Checker
|
|
38
|
+
from scipy.interpolate import LinearNDInterpolator
|
|
39
|
+
from scipy.spatial import Delaunay # pylint: disable=E0611
|
|
40
|
+
|
|
41
|
+
import cars.orchestrator.orchestrator as ocht
|
|
42
|
+
from cars.applications import application_constants
|
|
43
|
+
from cars.applications.grid_correction.abstract_grid_correction_app import (
|
|
44
|
+
GridCorrection,
|
|
45
|
+
)
|
|
46
|
+
from cars.applications.grid_generation import (
|
|
47
|
+
grid_generation_algo,
|
|
48
|
+
)
|
|
49
|
+
from cars.applications.grid_generation import (
|
|
50
|
+
grid_generation_constants as grid_constants,
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
# CARS imports
|
|
54
|
+
from cars.core.utils import safe_makedirs
|
|
55
|
+
from cars.orchestrator.cluster.log_wrapper import cars_profile
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
class GridCorrectionApp(GridCorrection, short_name="default"):
|
|
59
|
+
"""
|
|
60
|
+
EpipolarGridGeneration
|
|
61
|
+
"""
|
|
62
|
+
|
|
63
|
+
def __init__(self, conf=None):
|
|
64
|
+
"""
|
|
65
|
+
Init function of EpipolarGridGeneration
|
|
66
|
+
|
|
67
|
+
:param conf: configuration for grid generation
|
|
68
|
+
:return: a application_to_use object
|
|
69
|
+
"""
|
|
70
|
+
|
|
71
|
+
super().__init__(conf=conf)
|
|
72
|
+
|
|
73
|
+
# check conf
|
|
74
|
+
self.used_method = self.used_config["method"]
|
|
75
|
+
self.nb_matches = self.used_config["nb_matches"]
|
|
76
|
+
self.save_intermediate_data = self.used_config["save_intermediate_data"]
|
|
77
|
+
|
|
78
|
+
def check_conf(self, conf):
|
|
79
|
+
"""
|
|
80
|
+
Check configuration
|
|
81
|
+
|
|
82
|
+
:param conf: configuration to check
|
|
83
|
+
:type conf: dict
|
|
84
|
+
|
|
85
|
+
:return: overloaded configuration
|
|
86
|
+
:rtype: dict
|
|
87
|
+
|
|
88
|
+
"""
|
|
89
|
+
|
|
90
|
+
# Init conf
|
|
91
|
+
if conf is not None:
|
|
92
|
+
overloaded_conf = conf.copy()
|
|
93
|
+
else:
|
|
94
|
+
conf = {}
|
|
95
|
+
overloaded_conf = {}
|
|
96
|
+
|
|
97
|
+
# Overload conf
|
|
98
|
+
overloaded_conf["method"] = conf.get("method", "default")
|
|
99
|
+
overloaded_conf["nb_matches"] = conf.get("nb_matches", 90)
|
|
100
|
+
overloaded_conf["save_intermediate_data"] = conf.get(
|
|
101
|
+
"save_intermediate_data", False
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
grid_generation_schema = {
|
|
105
|
+
"method": str,
|
|
106
|
+
"nb_matches": And(int, lambda x: x > 0),
|
|
107
|
+
"save_intermediate_data": bool,
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
# Check conf
|
|
111
|
+
checker = Checker(grid_generation_schema)
|
|
112
|
+
checker.validate(overloaded_conf)
|
|
113
|
+
|
|
114
|
+
return overloaded_conf
|
|
115
|
+
|
|
116
|
+
def get_minimum_nb_matches(self):
|
|
117
|
+
"""
|
|
118
|
+
Get the minimum number of matches required for grid correction
|
|
119
|
+
"""
|
|
120
|
+
|
|
121
|
+
return self.nb_matches
|
|
122
|
+
|
|
123
|
+
@cars_profile(name="Correct grid")
|
|
124
|
+
def correct_grid(self, grid, grid_correction, pair_folder, save_grid=None):
|
|
125
|
+
"""
|
|
126
|
+
Correct grid
|
|
127
|
+
|
|
128
|
+
:param grid: grid to correct
|
|
129
|
+
:type grid: dict
|
|
130
|
+
:param grid_correction: grid correction to apply
|
|
131
|
+
:type grid_correction: Tuple(np.ndarray, np.ndarray)
|
|
132
|
+
(coefsx_2d, coefsy_2d) , each of size (2,2)
|
|
133
|
+
:param pair_folder: directory where grids are saved: either in
|
|
134
|
+
pair_folder/tmp, or at the root of pair_folder if save_grid is True
|
|
135
|
+
:type pair_folder: str
|
|
136
|
+
:param save_grid: if True grids are saved in root of pair_folder,
|
|
137
|
+
instead of tmp
|
|
138
|
+
:type save_grid: bool
|
|
139
|
+
"""
|
|
140
|
+
|
|
141
|
+
coefsx_2d, coefsy_2d = grid_correction
|
|
142
|
+
|
|
143
|
+
with rio.open(grid["path"]) as right_grid:
|
|
144
|
+
right_grid_row = right_grid.read(1)
|
|
145
|
+
right_grid_col = right_grid.read(2)
|
|
146
|
+
|
|
147
|
+
origin = grid["grid_origin"]
|
|
148
|
+
spacing = grid["grid_spacing"]
|
|
149
|
+
|
|
150
|
+
# Form 3D array with grid positions
|
|
151
|
+
x_values_1d = np.linspace(
|
|
152
|
+
origin[0],
|
|
153
|
+
origin[0] + right_grid_row.shape[0] * spacing[0],
|
|
154
|
+
right_grid_row.shape[0],
|
|
155
|
+
)
|
|
156
|
+
y_values_1d = np.linspace(
|
|
157
|
+
origin[1],
|
|
158
|
+
origin[1] + right_grid_row.shape[1] * spacing[1],
|
|
159
|
+
right_grid_row.shape[1],
|
|
160
|
+
)
|
|
161
|
+
x_values_2d, y_values_2d = np.meshgrid(y_values_1d, x_values_1d)
|
|
162
|
+
|
|
163
|
+
# Compute corresponding point in sensor geometry
|
|
164
|
+
# (grid encodes (x_sensor -
|
|
165
|
+
# x_epi,y_sensor - y__epi)
|
|
166
|
+
|
|
167
|
+
# Interpolate the regression model at grid position
|
|
168
|
+
correction_grid_x = np.polynomial.polynomial.polyval2d(
|
|
169
|
+
x_values_2d, y_values_2d, coefsx_2d
|
|
170
|
+
)
|
|
171
|
+
correction_grid_y = np.polynomial.polynomial.polyval2d(
|
|
172
|
+
x_values_2d, y_values_2d, coefsy_2d
|
|
173
|
+
)
|
|
174
|
+
|
|
175
|
+
# Compute corrected grid
|
|
176
|
+
corrected_grid_x = right_grid_row - correction_grid_x
|
|
177
|
+
corrected_grid_y = right_grid_col - correction_grid_y
|
|
178
|
+
corrected_right_grid = np.stack(
|
|
179
|
+
(corrected_grid_x, corrected_grid_y), axis=2
|
|
180
|
+
)
|
|
181
|
+
|
|
182
|
+
# create new grid dict
|
|
183
|
+
corrected_grid_right = grid.copy()
|
|
184
|
+
|
|
185
|
+
# Dump corrected grid
|
|
186
|
+
grid_origin = grid["grid_origin"]
|
|
187
|
+
grid_spacing = grid["grid_spacing"]
|
|
188
|
+
|
|
189
|
+
# Get save folder (permanent or temporay according to
|
|
190
|
+
# save_grid parameter)
|
|
191
|
+
if save_grid:
|
|
192
|
+
safe_makedirs(pair_folder)
|
|
193
|
+
save_folder = os.path.join(
|
|
194
|
+
pair_folder, "corrected_right_epi_grid.tif"
|
|
195
|
+
)
|
|
196
|
+
else:
|
|
197
|
+
safe_makedirs(os.path.join(pair_folder, "tmp"))
|
|
198
|
+
save_folder = os.path.join(
|
|
199
|
+
pair_folder, "tmp", "corrected_right_epi_grid.tif"
|
|
200
|
+
)
|
|
201
|
+
|
|
202
|
+
grid_generation_algo.write_grid(
|
|
203
|
+
corrected_right_grid, save_folder, grid_origin, grid_spacing
|
|
204
|
+
)
|
|
205
|
+
|
|
206
|
+
corrected_grid_right["path"] = save_folder
|
|
207
|
+
|
|
208
|
+
return corrected_grid_right
|
|
209
|
+
|
|
210
|
+
@cars_profile(name="Epi Grid Generation")
|
|
211
|
+
def run( # pylint: disable=too-many-positional-arguments
|
|
212
|
+
self,
|
|
213
|
+
matches,
|
|
214
|
+
grid_right,
|
|
215
|
+
save_matches=False,
|
|
216
|
+
minimum_nb_matches=100,
|
|
217
|
+
pair_folder="",
|
|
218
|
+
pair_key="pair_0",
|
|
219
|
+
orchestrator=None,
|
|
220
|
+
save_corrected_grid=None,
|
|
221
|
+
):
|
|
222
|
+
"""
|
|
223
|
+
Estimates grid correction, and correct matches
|
|
224
|
+
|
|
225
|
+
:param matches: matches
|
|
226
|
+
:type matches: np.ndarray
|
|
227
|
+
:param grid_right: grid to correct
|
|
228
|
+
:type grid_right: dict
|
|
229
|
+
:param save_matches: true is matches needs to be saved
|
|
230
|
+
:type save_matches: bool
|
|
231
|
+
:param minimum_nb_matches: minimum number of matches required
|
|
232
|
+
:type minimum_nb_matches: int
|
|
233
|
+
:param pair_folder: folder used for current pair
|
|
234
|
+
:type pair_folder: str
|
|
235
|
+
|
|
236
|
+
:return: grid_correction to apply, corrected_matches, info before,
|
|
237
|
+
info after
|
|
238
|
+
:rtype: Tuple(np.ndarray, np.ndarray) , np.ndarray, dict, dict
|
|
239
|
+
grid_correction is : (coefsx_2d, coefsy_2d) , each of size (2,2)
|
|
240
|
+
|
|
241
|
+
"""
|
|
242
|
+
|
|
243
|
+
# Default orchestrator
|
|
244
|
+
if orchestrator is None:
|
|
245
|
+
# Create default sequential orchestrator for current application
|
|
246
|
+
# be awere, no out_json will be shared between orchestrators
|
|
247
|
+
# No files saved
|
|
248
|
+
cars_orchestrator = ocht.Orchestrator(
|
|
249
|
+
orchestrator_conf={"mode": "sequential"}
|
|
250
|
+
)
|
|
251
|
+
else:
|
|
252
|
+
cars_orchestrator = orchestrator
|
|
253
|
+
|
|
254
|
+
if matches.shape[0] < minimum_nb_matches:
|
|
255
|
+
logging.error(
|
|
256
|
+
"Insufficient amount of matches found"
|
|
257
|
+
", can not safely estimate epipolar error correction"
|
|
258
|
+
)
|
|
259
|
+
|
|
260
|
+
raise ValueError(
|
|
261
|
+
f"Insufficient amount of matches found (< {minimum_nb_matches})"
|
|
262
|
+
", can not safely estimate epipolar error correction"
|
|
263
|
+
)
|
|
264
|
+
|
|
265
|
+
# Get grids attributes
|
|
266
|
+
with rio.open(grid_right["path"]) as right_grid:
|
|
267
|
+
right_grid_row = right_grid.read(1)
|
|
268
|
+
right_grid_col = right_grid.read(2)
|
|
269
|
+
|
|
270
|
+
origin = grid_right["grid_origin"]
|
|
271
|
+
spacing = grid_right["grid_spacing"]
|
|
272
|
+
|
|
273
|
+
# Form 3D array with grid positions
|
|
274
|
+
x_values_1d = np.arange(
|
|
275
|
+
origin[0],
|
|
276
|
+
origin[0] + right_grid_row.shape[0] * spacing[0],
|
|
277
|
+
spacing[0],
|
|
278
|
+
)
|
|
279
|
+
y_values_1d = np.arange(
|
|
280
|
+
origin[1],
|
|
281
|
+
origin[1] + right_grid_row.shape[1] * spacing[1],
|
|
282
|
+
spacing[1],
|
|
283
|
+
)
|
|
284
|
+
x_values_2d, y_values_2d = np.meshgrid(y_values_1d, x_values_1d)
|
|
285
|
+
|
|
286
|
+
# Compute corresponding point in sensor geometry
|
|
287
|
+
# (grid encodes (x_sensor -
|
|
288
|
+
# x_epi,y_sensor - y__epi)
|
|
289
|
+
|
|
290
|
+
# Extract matches for convenience
|
|
291
|
+
matches_y1 = matches[:, 1]
|
|
292
|
+
matches_x2 = matches[:, 2]
|
|
293
|
+
matches_y2 = matches[:, 3]
|
|
294
|
+
|
|
295
|
+
# Map real matches to sensor geometry
|
|
296
|
+
points = np.column_stack((np.ravel(x_values_2d), np.ravel(y_values_2d)))
|
|
297
|
+
|
|
298
|
+
triangulation = Delaunay(points)
|
|
299
|
+
|
|
300
|
+
values = np.ravel(right_grid_row)
|
|
301
|
+
|
|
302
|
+
interpolator = LinearNDInterpolator(triangulation, values)
|
|
303
|
+
sensor_matches_raw_x = interpolator(matches_x2, matches_y2)
|
|
304
|
+
|
|
305
|
+
# Simulate matches that have no epipolar error (i.e. y2 == y1) and map
|
|
306
|
+
# them to sensor geometry
|
|
307
|
+
sensor_matches_perfect_x = interpolator(matches_x2, matches_y1)
|
|
308
|
+
|
|
309
|
+
values = np.ravel(right_grid_col)
|
|
310
|
+
interpolator = LinearNDInterpolator(triangulation, values)
|
|
311
|
+
sensor_matches_raw_y = interpolator(matches_x2, matches_y2)
|
|
312
|
+
|
|
313
|
+
sensor_matches_perfect_y = interpolator(matches_x2, matches_y1)
|
|
314
|
+
|
|
315
|
+
# Compute epipolar error in sensor geometry in both direction
|
|
316
|
+
epipolar_error_x = sensor_matches_perfect_x - sensor_matches_raw_x
|
|
317
|
+
epipolar_error_y = sensor_matches_perfect_y - sensor_matches_raw_y
|
|
318
|
+
|
|
319
|
+
# Output epipolar error stats for monitoring
|
|
320
|
+
mean_epipolar_error = [
|
|
321
|
+
np.mean(epipolar_error_x),
|
|
322
|
+
np.mean(epipolar_error_y),
|
|
323
|
+
]
|
|
324
|
+
median_epipolar_error = [
|
|
325
|
+
np.median(epipolar_error_x),
|
|
326
|
+
np.median(epipolar_error_y),
|
|
327
|
+
]
|
|
328
|
+
std_epipolar_error = [
|
|
329
|
+
np.std(epipolar_error_x),
|
|
330
|
+
np.std(epipolar_error_y),
|
|
331
|
+
]
|
|
332
|
+
rms_epipolar_error = np.mean(
|
|
333
|
+
np.sqrt(
|
|
334
|
+
epipolar_error_x * epipolar_error_x
|
|
335
|
+
+ epipolar_error_y * epipolar_error_y
|
|
336
|
+
)
|
|
337
|
+
)
|
|
338
|
+
rmsd_epipolar_error = np.std(
|
|
339
|
+
np.sqrt(
|
|
340
|
+
epipolar_error_x * epipolar_error_x
|
|
341
|
+
+ epipolar_error_y * epipolar_error_y
|
|
342
|
+
)
|
|
343
|
+
)
|
|
344
|
+
|
|
345
|
+
in_stats = {
|
|
346
|
+
"mean_epipolar_error": mean_epipolar_error,
|
|
347
|
+
"median_epipolar_error": median_epipolar_error,
|
|
348
|
+
"std_epipolar_error": std_epipolar_error,
|
|
349
|
+
"rms_epipolar_error": rms_epipolar_error,
|
|
350
|
+
"rmsd_epipolar_error": rmsd_epipolar_error,
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
logging.debug(
|
|
354
|
+
"Epipolar error before correction: \n"
|
|
355
|
+
"x = {:.3f} +/- {:.3f} pixels \n"
|
|
356
|
+
"y = {:.3f} +/- {:.3f} pixels \n"
|
|
357
|
+
"rmse = {:.3f} +/- {:.3f} pixels \n"
|
|
358
|
+
"medianx = {:.3f} pixels \n"
|
|
359
|
+
"mediany = {:.3f} pixels".format(
|
|
360
|
+
mean_epipolar_error[0],
|
|
361
|
+
std_epipolar_error[0],
|
|
362
|
+
mean_epipolar_error[1],
|
|
363
|
+
std_epipolar_error[1],
|
|
364
|
+
rms_epipolar_error,
|
|
365
|
+
rmsd_epipolar_error,
|
|
366
|
+
median_epipolar_error[0],
|
|
367
|
+
median_epipolar_error[1],
|
|
368
|
+
)
|
|
369
|
+
)
|
|
370
|
+
|
|
371
|
+
# Perform bilinear regression for both component of epipolar error
|
|
372
|
+
nan_mask = np.logical_and(
|
|
373
|
+
~np.isnan(epipolar_error_x), ~np.isnan(epipolar_error_y)
|
|
374
|
+
)
|
|
375
|
+
lstsq_input = np.array(
|
|
376
|
+
[
|
|
377
|
+
matches_x2[nan_mask] * 0 + 1,
|
|
378
|
+
matches_x2[nan_mask],
|
|
379
|
+
matches_y2[nan_mask],
|
|
380
|
+
]
|
|
381
|
+
).T
|
|
382
|
+
coefsx, residx, __, __ = np.linalg.lstsq(
|
|
383
|
+
lstsq_input, epipolar_error_x[nan_mask], rcond=None
|
|
384
|
+
)
|
|
385
|
+
coefsy, residy, __, __ = np.linalg.lstsq(
|
|
386
|
+
lstsq_input, epipolar_error_y[nan_mask], rcond=None
|
|
387
|
+
)
|
|
388
|
+
|
|
389
|
+
# Normalize residuals by number of matches
|
|
390
|
+
rmsex = np.sqrt(residx / matches.shape[0])
|
|
391
|
+
rmsey = np.sqrt(residy / matches.shape[1])
|
|
392
|
+
|
|
393
|
+
logging.debug(
|
|
394
|
+
"Root Mean Square Error of correction estimation:"
|
|
395
|
+
"rmsex={} pixels, rmsey={} pixels".format(rmsex, rmsey)
|
|
396
|
+
)
|
|
397
|
+
|
|
398
|
+
# Reshape coefs to 2D (expected by np.polynomial.polyval2d)
|
|
399
|
+
coefsx_2d = np.ndarray((2, 2))
|
|
400
|
+
coefsx_2d[0, 0] = coefsx[0]
|
|
401
|
+
coefsx_2d[1, 0] = coefsx[1]
|
|
402
|
+
coefsx_2d[0, 1] = coefsx[2]
|
|
403
|
+
coefsx_2d[1, 1] = 0.0
|
|
404
|
+
|
|
405
|
+
coefsy_2d = np.ndarray((2, 2))
|
|
406
|
+
coefsy_2d[0, 0] = coefsy[0]
|
|
407
|
+
coefsy_2d[1, 0] = coefsy[1]
|
|
408
|
+
coefsy_2d[0, 1] = coefsy[2]
|
|
409
|
+
coefsy_2d[1, 1] = 0.0
|
|
410
|
+
|
|
411
|
+
grid_correction = (coefsx_2d, coefsy_2d)
|
|
412
|
+
|
|
413
|
+
# Map corrected matches to sensor geometry
|
|
414
|
+
sensor_matches_corrected_x = (
|
|
415
|
+
sensor_matches_raw_x
|
|
416
|
+
+ np.polynomial.polynomial.polyval2d(
|
|
417
|
+
matches_x2, matches_y2, coefsx_2d
|
|
418
|
+
)
|
|
419
|
+
)
|
|
420
|
+
sensor_matches_corrected_y = (
|
|
421
|
+
sensor_matches_raw_y
|
|
422
|
+
+ np.polynomial.polynomial.polyval2d(
|
|
423
|
+
matches_x2, matches_y2, coefsy_2d
|
|
424
|
+
)
|
|
425
|
+
)
|
|
426
|
+
|
|
427
|
+
# Map corrected matches to epipolar geometry
|
|
428
|
+
points = np.column_stack(
|
|
429
|
+
(np.ravel(right_grid_row), np.ravel(right_grid_col))
|
|
430
|
+
)
|
|
431
|
+
triangulation = Delaunay(points)
|
|
432
|
+
|
|
433
|
+
values = np.ravel(x_values_2d)
|
|
434
|
+
interpolator = LinearNDInterpolator(triangulation, values)
|
|
435
|
+
epipolar_matches_corrected_x = interpolator(
|
|
436
|
+
sensor_matches_corrected_x, sensor_matches_corrected_y
|
|
437
|
+
)
|
|
438
|
+
|
|
439
|
+
values = np.ravel(y_values_2d)
|
|
440
|
+
interpolator = LinearNDInterpolator(triangulation, values)
|
|
441
|
+
epipolar_matches_corrected_y = interpolator(
|
|
442
|
+
sensor_matches_corrected_x, sensor_matches_corrected_y
|
|
443
|
+
)
|
|
444
|
+
|
|
445
|
+
corrected_matches = np.copy(matches)
|
|
446
|
+
corrected_matches[:, 2] = epipolar_matches_corrected_x
|
|
447
|
+
corrected_matches[:, 3] = epipolar_matches_corrected_y
|
|
448
|
+
|
|
449
|
+
# Compute epipolar error in sensor geometry in both direction after
|
|
450
|
+
# correction
|
|
451
|
+
corrected_epipolar_error_x = (
|
|
452
|
+
sensor_matches_perfect_x - sensor_matches_corrected_x
|
|
453
|
+
)
|
|
454
|
+
corrected_epipolar_error_y = (
|
|
455
|
+
sensor_matches_perfect_y - sensor_matches_corrected_y
|
|
456
|
+
)
|
|
457
|
+
|
|
458
|
+
# Output corrected epipolar error stats for monitoring
|
|
459
|
+
mean_corrected_epipolar_error = [
|
|
460
|
+
np.mean(corrected_epipolar_error_x),
|
|
461
|
+
np.mean(corrected_epipolar_error_y),
|
|
462
|
+
]
|
|
463
|
+
median_corrected_epipolar_error = [
|
|
464
|
+
np.median(corrected_epipolar_error_x),
|
|
465
|
+
np.median(corrected_epipolar_error_y),
|
|
466
|
+
]
|
|
467
|
+
std_corrected_epipolar_error = [
|
|
468
|
+
np.std(corrected_epipolar_error_x),
|
|
469
|
+
np.std(corrected_epipolar_error_y),
|
|
470
|
+
]
|
|
471
|
+
rms_corrected_epipolar_error = np.mean(
|
|
472
|
+
np.sqrt(
|
|
473
|
+
corrected_epipolar_error_x * corrected_epipolar_error_x
|
|
474
|
+
+ corrected_epipolar_error_y * corrected_epipolar_error_y
|
|
475
|
+
)
|
|
476
|
+
)
|
|
477
|
+
rmsd_corrected_epipolar_error = np.std(
|
|
478
|
+
np.sqrt(
|
|
479
|
+
corrected_epipolar_error_x * corrected_epipolar_error_x
|
|
480
|
+
+ corrected_epipolar_error_y * corrected_epipolar_error_y
|
|
481
|
+
)
|
|
482
|
+
)
|
|
483
|
+
|
|
484
|
+
out_stats = {
|
|
485
|
+
"mean_epipolar_error": mean_corrected_epipolar_error,
|
|
486
|
+
"median_epipolar_error": median_corrected_epipolar_error,
|
|
487
|
+
"std_epipolar_error": std_corrected_epipolar_error,
|
|
488
|
+
"rms_epipolar_error": rms_corrected_epipolar_error,
|
|
489
|
+
"rmsd_epipolar_error": rmsd_corrected_epipolar_error,
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
logging.debug(
|
|
493
|
+
"Epipolar error after correction: \n"
|
|
494
|
+
"x = {:.3f} +/- {:.3f} pixels \n"
|
|
495
|
+
"y = {:.3f} +/- {:.3f} pixels \n"
|
|
496
|
+
"rmse = {:.3f} +/- {:.3f} pixels \n"
|
|
497
|
+
"medianx = {:.3f} pixels \n"
|
|
498
|
+
"mediany = {:.3f} pixels".format(
|
|
499
|
+
mean_corrected_epipolar_error[0],
|
|
500
|
+
std_corrected_epipolar_error[0],
|
|
501
|
+
mean_corrected_epipolar_error[1],
|
|
502
|
+
std_corrected_epipolar_error[1],
|
|
503
|
+
rms_corrected_epipolar_error,
|
|
504
|
+
rmsd_corrected_epipolar_error,
|
|
505
|
+
median_corrected_epipolar_error[0],
|
|
506
|
+
median_corrected_epipolar_error[1],
|
|
507
|
+
)
|
|
508
|
+
)
|
|
509
|
+
|
|
510
|
+
corrected_epipolar_error = (
|
|
511
|
+
corrected_matches[:, 1] - corrected_matches[:, 3]
|
|
512
|
+
)
|
|
513
|
+
logging.info(
|
|
514
|
+
"Epipolar error after correction: mean = {:.3f} pix., "
|
|
515
|
+
"standard deviation = {:.3f} pix., max = {:.3f} pix.".format(
|
|
516
|
+
np.mean(corrected_epipolar_error),
|
|
517
|
+
np.std(corrected_epipolar_error),
|
|
518
|
+
np.max(np.fabs(corrected_epipolar_error)),
|
|
519
|
+
)
|
|
520
|
+
)
|
|
521
|
+
|
|
522
|
+
# Export filtered matches
|
|
523
|
+
matches_array_path = None
|
|
524
|
+
current_out_dir = None
|
|
525
|
+
if save_matches:
|
|
526
|
+
logging.info("Writing matches file")
|
|
527
|
+
if pair_folder is None:
|
|
528
|
+
logging.error("Pair folder not provided")
|
|
529
|
+
else:
|
|
530
|
+
safe_makedirs(pair_folder)
|
|
531
|
+
current_out_dir = pair_folder
|
|
532
|
+
matches_array_path = os.path.join(
|
|
533
|
+
current_out_dir, "corrected_filtered_matches.npy"
|
|
534
|
+
)
|
|
535
|
+
np.save(matches_array_path, corrected_matches)
|
|
536
|
+
|
|
537
|
+
# Update orchestrator out_json
|
|
538
|
+
corrected_matches_infos = {
|
|
539
|
+
application_constants.APPLICATION_TAG: {
|
|
540
|
+
grid_constants.GRID_CORRECTION_TAG: {pair_key: {}}
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
cars_orchestrator.update_out_info(corrected_matches_infos)
|
|
544
|
+
|
|
545
|
+
corrected_grid_right = self.correct_grid(
|
|
546
|
+
grid_right,
|
|
547
|
+
grid_correction,
|
|
548
|
+
pair_folder,
|
|
549
|
+
save_corrected_grid,
|
|
550
|
+
)
|
|
551
|
+
|
|
552
|
+
return (
|
|
553
|
+
corrected_grid_right,
|
|
554
|
+
corrected_matches,
|
|
555
|
+
in_stats,
|
|
556
|
+
out_stats,
|
|
557
|
+
)
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# !/usr/bin/env python
|
|
2
|
+
# coding: utf8
|
|
3
|
+
#
|
|
4
|
+
# Copyright (c) 2020 Centre National d'Etudes Spatiales (CNES).
|
|
5
|
+
#
|
|
6
|
+
# This file is part of CARS
|
|
7
|
+
# (see https://github.com/CNES/cars).
|
|
8
|
+
#
|
|
9
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
10
|
+
# you may not use this file except in compliance with the License.
|
|
11
|
+
# You may obtain a copy of the License at
|
|
12
|
+
#
|
|
13
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
14
|
+
#
|
|
15
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
16
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
17
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
18
|
+
# See the License for the specific language governing permissions and
|
|
19
|
+
# limitations under the License.
|
|
20
|
+
#
|
|
21
|
+
"""
|
|
22
|
+
CARS grid_generation module init file
|
|
23
|
+
"""
|
|
24
|
+
# flake8: noqa: F401
|
|
25
|
+
|
|
26
|
+
from cars.applications.grid_generation.abstract_grid_generation_app import (
|
|
27
|
+
GridGeneration,
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
from . import epipolar_grid_generation_app
|