cars 1.0.0rc2__cp312-cp312-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of cars might be problematic. Click here for more details.
- cars/__init__.py +86 -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 +42 -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.cp312-win_amd64.dll.a +0 -0
- cars/applications/dense_matching/cpp/dense_matching_cpp.cp312-win_amd64.pyd +0 -0
- cars/applications/dense_matching/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 +1119 -0
- cars/core/geometry/shareloc_geometry.py +598 -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 +1088 -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 +186 -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 +438 -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.0rc2.dist-info/DELVEWHEEL +2 -0
- cars-1.0.0rc2.dist-info/METADATA +289 -0
- cars-1.0.0rc2.dist-info/RECORD +225 -0
- cars-1.0.0rc2.dist-info/WHEEL +4 -0
- cars-1.0.0rc2.dist-info/entry_points.txt +8 -0
- cars.libs/libgcc_s_seh-1-b2494fcbd4d80cf2c98fdd5261f6d850.dll +0 -0
- cars.libs/libstdc++-6-e9b0d12ae0e9555bbae55e8dfd08c3f7.dll +0 -0
- cars.libs/libwinpthread-1-7882d1b093714ccdfaf4e0789a817792.dll +0 -0
|
@@ -0,0 +1,101 @@
|
|
|
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 dsm filling 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("dsm_filling")
|
|
33
|
+
class DsmFilling(ApplicationTemplate, metaclass=ABCMeta):
|
|
34
|
+
"""
|
|
35
|
+
DsmFilling
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
available_applications: Dict = {}
|
|
39
|
+
default_application = "bulldozer"
|
|
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 orchestrator: orchestrator used
|
|
48
|
+
:param conf: configuration for filling
|
|
49
|
+
:return: an application_to_use object
|
|
50
|
+
"""
|
|
51
|
+
|
|
52
|
+
dsm_filling_method = cls.default_application
|
|
53
|
+
if bool(conf) is False:
|
|
54
|
+
logging.info(
|
|
55
|
+
"dsm_filling method not specified, default"
|
|
56
|
+
" {} is used".format(dsm_filling_method)
|
|
57
|
+
)
|
|
58
|
+
else:
|
|
59
|
+
dsm_filling_method = conf["method"]
|
|
60
|
+
|
|
61
|
+
if dsm_filling_method not in cls.available_applications:
|
|
62
|
+
logging.error(
|
|
63
|
+
"No dsm_filling application named {} registered".format(
|
|
64
|
+
dsm_filling_method
|
|
65
|
+
)
|
|
66
|
+
)
|
|
67
|
+
raise KeyError(
|
|
68
|
+
"No dsm_filling application named {} registered".format(
|
|
69
|
+
dsm_filling_method
|
|
70
|
+
)
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
logging.info(
|
|
74
|
+
"The DsmFilling {} application will be used".format(
|
|
75
|
+
dsm_filling_method
|
|
76
|
+
)
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
return super(DsmFilling, cls).__new__(
|
|
80
|
+
cls.available_applications[dsm_filling_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 DSM Filling
|
|
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(self):
|
|
99
|
+
"""
|
|
100
|
+
Run dsm filling using initial elevation and the current dsm
|
|
101
|
+
"""
|
|
@@ -0,0 +1,278 @@
|
|
|
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 border interpolation dsm filling application class.
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
import logging
|
|
26
|
+
import os
|
|
27
|
+
import shutil
|
|
28
|
+
import warnings
|
|
29
|
+
|
|
30
|
+
import numpy as np
|
|
31
|
+
import rasterio as rio
|
|
32
|
+
import scipy
|
|
33
|
+
import skimage
|
|
34
|
+
from json_checker import Checker, Or
|
|
35
|
+
from pyproj import CRS
|
|
36
|
+
from rasterio.errors import NodataShadowWarning
|
|
37
|
+
from shapely import Polygon
|
|
38
|
+
|
|
39
|
+
from cars.core import inputs, projection
|
|
40
|
+
from cars.orchestrator.cluster.log_wrapper import cars_profile
|
|
41
|
+
|
|
42
|
+
from .abstract_dsm_filling_app import DsmFilling
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class BorderInterpolation(DsmFilling, short_name="border_interpolation"):
|
|
46
|
+
"""
|
|
47
|
+
Border interpolation
|
|
48
|
+
"""
|
|
49
|
+
|
|
50
|
+
def __init__(self, conf=None):
|
|
51
|
+
"""
|
|
52
|
+
Init function of BorderInterpolation
|
|
53
|
+
|
|
54
|
+
:param conf: configuration for BulldozerFilling
|
|
55
|
+
:return: an application_to_use object
|
|
56
|
+
"""
|
|
57
|
+
super().__init__(conf=conf)
|
|
58
|
+
|
|
59
|
+
# check conf
|
|
60
|
+
self.used_method = self.used_config["method"]
|
|
61
|
+
self.classification = self.used_config["classification"]
|
|
62
|
+
self.component_min_size = self.used_config["component_min_size"]
|
|
63
|
+
self.border_size = self.used_config["border_size"]
|
|
64
|
+
self.percentile = self.used_config["percentile"]
|
|
65
|
+
self.save_intermediate_data = self.used_config["save_intermediate_data"]
|
|
66
|
+
|
|
67
|
+
def check_conf(self, conf):
|
|
68
|
+
|
|
69
|
+
# init conf
|
|
70
|
+
if conf is not None:
|
|
71
|
+
overloaded_conf = conf.copy()
|
|
72
|
+
else:
|
|
73
|
+
conf = {}
|
|
74
|
+
overloaded_conf = {}
|
|
75
|
+
|
|
76
|
+
# Overload conf
|
|
77
|
+
overloaded_conf["method"] = conf.get("method", "border_interpolation")
|
|
78
|
+
overloaded_conf["classification"] = conf.get("classification", "nodata")
|
|
79
|
+
if isinstance(overloaded_conf["classification"], str):
|
|
80
|
+
overloaded_conf["classification"] = [
|
|
81
|
+
overloaded_conf["classification"]
|
|
82
|
+
]
|
|
83
|
+
overloaded_conf["component_min_size"] = conf.get(
|
|
84
|
+
"component_min_size", 5
|
|
85
|
+
)
|
|
86
|
+
overloaded_conf["border_size"] = conf.get("border_size", 10)
|
|
87
|
+
overloaded_conf["percentile"] = conf.get("percentile", 10)
|
|
88
|
+
overloaded_conf["save_intermediate_data"] = conf.get(
|
|
89
|
+
"save_intermediate_data", False
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
rectification_schema = {
|
|
93
|
+
"method": str,
|
|
94
|
+
"classification": Or(None, [str]),
|
|
95
|
+
"component_min_size": int,
|
|
96
|
+
"border_size": int,
|
|
97
|
+
"percentile": Or(int, float),
|
|
98
|
+
"save_intermediate_data": bool,
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
# Check conf
|
|
102
|
+
checker = Checker(rectification_schema)
|
|
103
|
+
checker.validate(overloaded_conf)
|
|
104
|
+
|
|
105
|
+
return overloaded_conf
|
|
106
|
+
|
|
107
|
+
@cars_profile(name="Border interpolation filling")
|
|
108
|
+
def run( # pylint: disable=too-many-positional-arguments # noqa C901
|
|
109
|
+
self,
|
|
110
|
+
dsm_file,
|
|
111
|
+
classif_file,
|
|
112
|
+
filling_file,
|
|
113
|
+
dtm_file,
|
|
114
|
+
dump_dir,
|
|
115
|
+
roi_polys,
|
|
116
|
+
roi_epsg,
|
|
117
|
+
dsm_dir=None,
|
|
118
|
+
):
|
|
119
|
+
"""
|
|
120
|
+
Run dsm filling using initial elevation and the current dsm
|
|
121
|
+
Replaces dsm.tif by the filled dsm. Adds a new band
|
|
122
|
+
to filling.tif if it exists.
|
|
123
|
+
The old dsm is saved in dump_dir.
|
|
124
|
+
|
|
125
|
+
roi_poly can any of these objects :
|
|
126
|
+
- a list of Shapely Polygons
|
|
127
|
+
- a Shapely Polygon
|
|
128
|
+
"""
|
|
129
|
+
|
|
130
|
+
if dsm_dir is not None:
|
|
131
|
+
dsm_path_out = os.path.join(dsm_dir, "dsm.tif")
|
|
132
|
+
filling_path_out = os.path.join(dsm_dir, "filling.tif")
|
|
133
|
+
else:
|
|
134
|
+
dsm_path_out = dsm_file
|
|
135
|
+
filling_path_out = filling_file
|
|
136
|
+
|
|
137
|
+
if self.classification is None:
|
|
138
|
+
self.classification = ["nodata"]
|
|
139
|
+
logging.error(
|
|
140
|
+
"Filling method 'border_interpolation' needs a classification"
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
if not os.path.exists(dump_dir):
|
|
144
|
+
os.makedirs(dump_dir)
|
|
145
|
+
|
|
146
|
+
old_dsm_path = os.path.join(dump_dir, "dsm_not_filled.tif")
|
|
147
|
+
new_dsm_path = os.path.join(dump_dir, "dsm_filled.tif")
|
|
148
|
+
|
|
149
|
+
# get dsm to be filled and its metadata
|
|
150
|
+
with rio.open(dsm_file) as in_dsm:
|
|
151
|
+
dsm = in_dsm.read(1)
|
|
152
|
+
dsm_tr = in_dsm.transform
|
|
153
|
+
dsm_crs = in_dsm.crs
|
|
154
|
+
dsm_meta = in_dsm.meta
|
|
155
|
+
dsm_nodata = in_dsm.nodata
|
|
156
|
+
|
|
157
|
+
roi_raster = np.ones(dsm.shape)
|
|
158
|
+
|
|
159
|
+
if isinstance(roi_polys, list):
|
|
160
|
+
roi_polys_outepsg = []
|
|
161
|
+
for poly in roi_polys:
|
|
162
|
+
if isinstance(poly, Polygon):
|
|
163
|
+
roi_poly_outepsg = projection.polygon_projection_crs(
|
|
164
|
+
poly, CRS(roi_epsg), dsm_crs
|
|
165
|
+
)
|
|
166
|
+
roi_polys_outepsg.append(roi_poly_outepsg)
|
|
167
|
+
|
|
168
|
+
roi_raster = rio.features.rasterize(
|
|
169
|
+
roi_polys_outepsg, out_shape=roi_raster.shape, transform=dsm_tr
|
|
170
|
+
)
|
|
171
|
+
elif isinstance(roi_polys, Polygon):
|
|
172
|
+
roi_poly_outepsg = projection.polygon_projection_crs(
|
|
173
|
+
roi_polys, CRS(roi_epsg), dsm_crs
|
|
174
|
+
)
|
|
175
|
+
roi_raster = rio.features.rasterize(
|
|
176
|
+
[roi_poly_outepsg], out_shape=roi_raster.shape, transform=dsm_tr
|
|
177
|
+
)
|
|
178
|
+
|
|
179
|
+
# get dtm to fill the dsm
|
|
180
|
+
if dtm_file is not None:
|
|
181
|
+
logging.info(
|
|
182
|
+
"Use DTM file {} for border interpolation".format(dtm_file)
|
|
183
|
+
)
|
|
184
|
+
with rio.open(dtm_file) as in_dtm:
|
|
185
|
+
dtm = in_dtm.read(1)
|
|
186
|
+
dtm_nodata = in_dtm.nodata
|
|
187
|
+
else:
|
|
188
|
+
logging.info(
|
|
189
|
+
"No DTM provided : DSM {} will be used for "
|
|
190
|
+
"border interpolation".format(dsm_file)
|
|
191
|
+
)
|
|
192
|
+
dtm = dsm.copy()
|
|
193
|
+
dtm_nodata = dsm_nodata
|
|
194
|
+
dtm[dtm == dtm_nodata] = np.nan
|
|
195
|
+
|
|
196
|
+
if self.save_intermediate_data:
|
|
197
|
+
with rio.open(old_dsm_path, "w", **dsm_meta) as out_dsm:
|
|
198
|
+
out_dsm.write(dsm, 1)
|
|
199
|
+
|
|
200
|
+
if classif_file is not None:
|
|
201
|
+
classif_descriptions = inputs.get_descriptions_bands(classif_file)
|
|
202
|
+
else:
|
|
203
|
+
classif_descriptions = []
|
|
204
|
+
combined_mask = np.zeros_like(dsm).astype(np.uint8)
|
|
205
|
+
for label in self.classification:
|
|
206
|
+
if label in classif_descriptions:
|
|
207
|
+
index_classif = classif_descriptions.index(label) + 1
|
|
208
|
+
with rio.open(classif_file) as in_classif:
|
|
209
|
+
classif = in_classif.read(index_classif)
|
|
210
|
+
|
|
211
|
+
with warnings.catch_warnings():
|
|
212
|
+
warnings.simplefilter("ignore", NodataShadowWarning)
|
|
213
|
+
classif_msk = in_classif.read_masks(1)
|
|
214
|
+
|
|
215
|
+
classif[classif_msk == 0] = 0
|
|
216
|
+
filling_mask = np.logical_and(classif, roi_raster > 0)
|
|
217
|
+
else:
|
|
218
|
+
logging.error(
|
|
219
|
+
"Label {} not found in classification "
|
|
220
|
+
"descriptions {}".format(label, classif_descriptions)
|
|
221
|
+
)
|
|
222
|
+
continue
|
|
223
|
+
logging.info(
|
|
224
|
+
"Filling of {} with Bulldozer DTM using "
|
|
225
|
+
"border interpolation".format(label)
|
|
226
|
+
)
|
|
227
|
+
filling_mask[classif_msk == 0] = 0
|
|
228
|
+
filling_mask = skimage.morphology.binary_opening(
|
|
229
|
+
filling_mask,
|
|
230
|
+
footprint=[
|
|
231
|
+
(np.ones((self.component_min_size, 1)), 1),
|
|
232
|
+
(np.ones((1, self.component_min_size)), 1),
|
|
233
|
+
],
|
|
234
|
+
)
|
|
235
|
+
features, num_features = scipy.ndimage.label(filling_mask)
|
|
236
|
+
logging.info("Filling of {} features".format(num_features))
|
|
237
|
+
features_boundaries = skimage.morphology.dilation(
|
|
238
|
+
features,
|
|
239
|
+
footprint=[
|
|
240
|
+
(np.ones((self.border_size, 1)), 1),
|
|
241
|
+
(np.ones((1, self.border_size)), 1),
|
|
242
|
+
],
|
|
243
|
+
)
|
|
244
|
+
features_boundaries[filling_mask] = 0
|
|
245
|
+
borders_file_path = os.path.join(
|
|
246
|
+
dump_dir, "borders_of_{}.tif".format(label)
|
|
247
|
+
)
|
|
248
|
+
if self.save_intermediate_data:
|
|
249
|
+
with rio.open(
|
|
250
|
+
borders_file_path, "w", **dsm_meta
|
|
251
|
+
) as out_borders:
|
|
252
|
+
out_borders.write(features_boundaries, 1)
|
|
253
|
+
for feature_id in range(1, num_features + 1):
|
|
254
|
+
altitude = np.nanpercentile(
|
|
255
|
+
dtm[features_boundaries == feature_id], self.percentile
|
|
256
|
+
)
|
|
257
|
+
if altitude is not None:
|
|
258
|
+
dsm[features == feature_id] = altitude
|
|
259
|
+
combined_mask = np.logical_or(combined_mask, filling_mask)
|
|
260
|
+
|
|
261
|
+
with rio.open(dsm_path_out, "w", **dsm_meta) as out_dsm:
|
|
262
|
+
out_dsm.write(dsm, 1)
|
|
263
|
+
if self.save_intermediate_data:
|
|
264
|
+
shutil.copy2(dsm_path_out, new_dsm_path)
|
|
265
|
+
|
|
266
|
+
if filling_file is not None:
|
|
267
|
+
with rio.open(filling_file, "r") as src:
|
|
268
|
+
fill_meta = src.meta
|
|
269
|
+
bands = [src.read(i + 1) for i in range(src.count)]
|
|
270
|
+
bands_desc = [src.descriptions[i] for i in range(src.count)]
|
|
271
|
+
fill_meta["count"] += 1
|
|
272
|
+
bands.append(combined_mask.astype(np.uint8))
|
|
273
|
+
bands_desc.append("border_interpolation")
|
|
274
|
+
|
|
275
|
+
with rio.open(filling_path_out, "w", **fill_meta) as out:
|
|
276
|
+
for i, band in enumerate(bands):
|
|
277
|
+
out.write(band, i + 1)
|
|
278
|
+
out.set_band_description(i + 1, bands_desc[i])
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# both paths will be overwritten in the filling application
|
|
2
|
+
dsm_path: "path/to/dsm"
|
|
3
|
+
output_dir: "path/to/output"
|
|
4
|
+
|
|
5
|
+
# everything else will be used directly as-is
|
|
6
|
+
|
|
7
|
+
#-------------------------#
|
|
8
|
+
# Options #
|
|
9
|
+
#-------------------------#
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
max_object_size : 16
|
|
13
|
+
# If True, keep the intermediate results
|
|
14
|
+
developer_mode : False
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
#-------------------------#
|
|
18
|
+
# Advanced settings #
|
|
19
|
+
#-------------------------#
|
|
20
|
+
# [Optional] - Altimetric height accuracy of the input DSM (m). If null, use the default value: 2*planimetric resolution
|
|
21
|
+
dsm_z_accuracy: null
|
|
22
|
+
# [Optional] - Maximum slope of the observed landscape terrain (%)
|
|
23
|
+
# former slope_threshold
|
|
24
|
+
max_ground_slope: 2.0
|
|
25
|
+
# [Optional] - If True, activate the ground pre-detection
|
|
26
|
+
activate_ground_anchors : False
|
|
27
|
+
# [Optional] - If True, keep the intermediate results
|
|
28
|
+
developer_mode : False
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
#-------------------------#
|
|
32
|
+
# Bulldozer core settings #
|
|
33
|
+
#-------------------------#
|
|
34
|
+
# /!\ Modify those data at your own risk (it is suggested to keep the default values) /!\
|
|
35
|
+
|
|
36
|
+
# [Optional] - DtmExtraction parameters
|
|
37
|
+
# former uniform_filter_size
|
|
38
|
+
cloth_tension_force : 3
|
|
39
|
+
prevent_unhook_iter : 10
|
|
40
|
+
num_outer_iter : 50
|
|
41
|
+
num_inner_iter : 10
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
|