cars 1.0.0a3__cp311-cp311-win_amd64.whl → 1.0.0a4__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 +3 -3
- cars/applications/__init__.py +0 -3
- cars/applications/application_template.py +20 -0
- cars/applications/auxiliary_filling/abstract_auxiliary_filling_app.py +12 -2
- cars/applications/auxiliary_filling/auxiliary_filling_algo.py +2 -2
- cars/applications/auxiliary_filling/auxiliary_filling_from_sensors_app.py +80 -36
- cars/applications/dem_generation/dem_generation_algo.py +1 -1
- cars/applications/dem_generation/dem_generation_wrappers.py +23 -57
- cars/applications/dem_generation/dichotomic_generation_app.py +3 -3
- cars/applications/dem_generation/rasterization_app.py +100 -41
- cars/applications/dense_match_filling/__init__.py +1 -1
- cars/applications/dense_match_filling/abstract_dense_match_filling_app.py +2 -15
- cars/applications/dense_match_filling/fill_disp_algo.py +32 -373
- cars/applications/dense_match_filling/fill_disp_wrappers.py +0 -343
- cars/applications/dense_match_filling/zero_padding_app.py +10 -5
- cars/applications/dense_matching/abstract_dense_matching_app.py +2 -1
- cars/applications/dense_matching/census_mccnn_sgm_app.py +38 -39
- 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 +48 -14
- cars/applications/dense_matching/dense_matching_wrappers.py +11 -3
- cars/applications/dense_matching/disparity_grid_algo.py +84 -62
- cars/applications/dense_matching/loaders/pandora_loader.py +91 -33
- cars/applications/dsm_filling/border_interpolation_app.py +1 -7
- cars/applications/dsm_filling/bulldozer_filling_app.py +2 -8
- cars/applications/dsm_filling/exogenous_filling_app.py +4 -9
- cars/applications/grid_generation/abstract_grid_generation_app.py +1 -1
- cars/applications/grid_generation/epipolar_grid_generation_app.py +4 -2
- cars/applications/grid_generation/grid_correction_app.py +4 -1
- cars/applications/grid_generation/grid_generation_algo.py +7 -2
- cars/applications/ground_truth_reprojection/abstract_ground_truth_reprojection_app.py +1 -1
- cars/applications/ground_truth_reprojection/direct_localization_app.py +2 -2
- cars/applications/ground_truth_reprojection/ground_truth_reprojection_algo.py +2 -1
- cars/applications/point_cloud_fusion/abstract_pc_fusion_app.py +0 -155
- cars/applications/point_cloud_fusion/mapping_to_terrain_tiles_app.py +0 -658
- cars/applications/point_cloud_fusion/pc_fusion_algo.py +0 -1339
- cars/applications/point_cloud_fusion/pc_fusion_wrappers.py +0 -869
- cars/applications/point_cloud_outlier_removal/abstract_outlier_removal_app.py +2 -1
- cars/applications/point_cloud_outlier_removal/outlier_removal_algo.py +9 -8
- cars/applications/point_cloud_outlier_removal/small_components_app.py +96 -267
- cars/applications/point_cloud_outlier_removal/statistical_app.py +116 -275
- cars/applications/rasterization/abstract_pc_rasterization_app.py +1 -1
- cars/applications/rasterization/rasterization_algo.py +18 -6
- cars/applications/rasterization/rasterization_wrappers.py +2 -1
- cars/applications/rasterization/simple_gaussian_app.py +60 -113
- cars/applications/resampling/abstract_resampling_app.py +1 -1
- cars/applications/resampling/bicubic_resampling_app.py +3 -1
- cars/applications/resampling/resampling_algo.py +16 -4
- cars/applications/resampling/resampling_wrappers.py +3 -1
- cars/applications/sparse_matching/abstract_sparse_matching_app.py +1 -1
- cars/applications/sparse_matching/sift_app.py +3 -3
- cars/applications/sparse_matching/sparse_matching_algo.py +3 -2
- cars/applications/sparse_matching/sparse_matching_wrappers.py +1 -1
- cars/applications/triangulation/abstract_triangulation_app.py +1 -1
- cars/applications/triangulation/line_of_sight_intersection_app.py +13 -11
- cars/applications/triangulation/pc_transform.py +552 -0
- cars/applications/triangulation/triangulation_algo.py +6 -4
- cars/applications/triangulation/triangulation_wrappers.py +1 -0
- cars/bundleadjustment.py +6 -6
- cars/cars.py +11 -9
- cars/core/cars_logging.py +80 -49
- cars/core/constants.py +0 -1
- cars/core/datasets.py +5 -2
- cars/core/geometry/abstract_geometry.py +256 -25
- cars/core/geometry/shareloc_geometry.py +110 -82
- cars/core/inputs.py +57 -19
- cars/core/outputs.py +1 -1
- cars/core/preprocessing.py +17 -3
- cars/core/projection.py +9 -6
- cars/core/tiling.py +10 -3
- cars/data_structures/cars_dataset.py +5 -5
- cars/data_structures/corresponding_tiles_tools.py +0 -103
- cars/data_structures/format_transformation.py +4 -1
- cars/devibrate.py +6 -3
- cars/extractroi.py +20 -21
- cars/orchestrator/cluster/abstract_cluster.py +15 -5
- cars/orchestrator/cluster/abstract_dask_cluster.py +6 -2
- cars/orchestrator/cluster/dask_jobqueue_utils.py +1 -1
- cars/orchestrator/cluster/log_wrapper.py +148 -21
- cars/orchestrator/cluster/mp_cluster/multiprocessing_cluster.py +11 -3
- cars/orchestrator/cluster/mp_cluster/multiprocessing_profiler.py +2 -2
- cars/orchestrator/cluster/pbs_dask_cluster.py +1 -1
- cars/orchestrator/cluster/sequential_cluster.py +5 -4
- cars/orchestrator/cluster/slurm_dask_cluster.py +1 -1
- cars/orchestrator/orchestrator.py +14 -3
- cars/orchestrator/registry/id_generator.py +1 -0
- cars/orchestrator/registry/saver_registry.py +2 -2
- cars/pipelines/conf_resolution/conf_final_resolution.json +5 -3
- cars/pipelines/default/default_pipeline.py +462 -1073
- cars/pipelines/parameters/advanced_parameters.py +74 -64
- cars/pipelines/parameters/advanced_parameters_constants.py +2 -5
- cars/pipelines/parameters/application_parameters.py +71 -0
- cars/pipelines/parameters/depth_map_inputs.py +0 -314
- cars/pipelines/parameters/dsm_inputs.py +40 -4
- cars/pipelines/parameters/output_parameters.py +2 -2
- cars/pipelines/parameters/sensor_inputs.py +30 -75
- cars/pipelines/parameters/sensor_inputs_constants.py +0 -2
- cars/pipelines/parameters/sensor_loaders/__init__.py +4 -3
- cars/pipelines/parameters/sensor_loaders/basic_classif_loader.py +106 -0
- cars/pipelines/parameters/sensor_loaders/{basic_sensor_loader.py → basic_image_loader.py} +16 -22
- cars/pipelines/parameters/sensor_loaders/pivot_classif_loader.py +121 -0
- cars/pipelines/parameters/sensor_loaders/{pivot_sensor_loader.py → pivot_image_loader.py} +10 -21
- cars/pipelines/parameters/sensor_loaders/sensor_loader.py +4 -6
- cars/pipelines/parameters/sensor_loaders/sensor_loader_template.py +1 -3
- cars/pipelines/pipeline_template.py +1 -3
- cars/pipelines/unit/unit_pipeline.py +527 -1016
- cars/starter.py +4 -3
- cars-1.0.0a4.dist-info/DELVEWHEEL +2 -0
- {cars-1.0.0a3.dist-info → cars-1.0.0a4.dist-info}/METADATA +135 -53
- {cars-1.0.0a3.dist-info → cars-1.0.0a4.dist-info}/RECORD +115 -131
- cars.libs/libgcc_s_seh-1-b2494fcbd4d80cf2c98fdd5261f6d850.dll +0 -0
- cars.libs/libstdc++-6-e9b0d12ae0e9555bbae55e8dfd08c3f7.dll +0 -0
- cars.libs/libwinpthread-1-7882d1b093714ccdfaf4e0789a817792.dll +0 -0
- cars/applications/dense_match_filling/cpp/__init__.py +0 -0
- cars/applications/dense_match_filling/cpp/dense_match_filling_cpp.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/cpp/dense_match_filling_cpp.py +0 -72
- cars/applications/dense_match_filling/cpp/includes/dense_match_filling.hpp +0 -46
- cars/applications/dense_match_filling/cpp/meson.build +0 -9
- cars/applications/dense_match_filling/cpp/src/bindings.cpp +0 -11
- cars/applications/dense_match_filling/cpp/src/dense_match_filling.cpp +0 -142
- cars/applications/dense_match_filling/plane_app.py +0 -556
- cars/applications/hole_detection/__init__.py +0 -30
- cars/applications/hole_detection/abstract_hole_detection_app.py +0 -125
- cars/applications/hole_detection/cloud_to_bbox_app.py +0 -346
- cars/applications/hole_detection/hole_detection_algo.py +0 -144
- cars/applications/hole_detection/hole_detection_wrappers.py +0 -53
- cars/applications/point_cloud_denoising/__init__.py +0 -29
- cars/applications/point_cloud_denoising/abstract_pc_denoising_app.py +0 -273
- cars/applications/point_cloud_fusion/__init__.py +0 -30
- cars/applications/point_cloud_fusion/cloud_fusion_constants.py +0 -39
- cars/applications/sparse_matching/pandora_sparse_matching_app.py +0 -0
- cars/pipelines/parameters/depth_map_inputs_constants.py +0 -25
- cars-1.0.0a3.dist-info/DELVEWHEEL +0 -2
- 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.0a3.dist-info → cars-1.0.0a4.dist-info}/WHEEL +0 -0
- {cars-1.0.0a3.dist-info → cars-1.0.0a4.dist-info}/entry_points.txt +0 -0
|
@@ -30,7 +30,7 @@ import numpy as np
|
|
|
30
30
|
import rasterio as rio
|
|
31
31
|
import shareloc.geofunctions.rectification as rectif
|
|
32
32
|
import xarray as xr
|
|
33
|
-
from json_checker import Checker
|
|
33
|
+
from json_checker import And, Checker
|
|
34
34
|
from shareloc.dtm_reader import dtm_reader
|
|
35
35
|
from shareloc.geofunctions import localization
|
|
36
36
|
from shareloc.geofunctions.rectification_grid import RectificationGrid
|
|
@@ -41,7 +41,7 @@ from shareloc.geomodels.rpc import RPC
|
|
|
41
41
|
from shareloc.image import Image
|
|
42
42
|
|
|
43
43
|
from cars.core import constants as cst
|
|
44
|
-
from cars.core import
|
|
44
|
+
from cars.core import projection
|
|
45
45
|
from cars.core.geometry.abstract_geometry import AbstractGeometry
|
|
46
46
|
|
|
47
47
|
GRID_TYPE = "GRID"
|
|
@@ -56,7 +56,7 @@ class SharelocGeometry(AbstractGeometry):
|
|
|
56
56
|
Shareloc geometry class
|
|
57
57
|
"""
|
|
58
58
|
|
|
59
|
-
def __init__(
|
|
59
|
+
def __init__( # pylint: disable=too-many-positional-arguments
|
|
60
60
|
self,
|
|
61
61
|
geometry_plugin_conf,
|
|
62
62
|
dem=None,
|
|
@@ -64,6 +64,7 @@ class SharelocGeometry(AbstractGeometry):
|
|
|
64
64
|
default_alt=None,
|
|
65
65
|
pairs_for_roi=None,
|
|
66
66
|
scaling_coeff=1,
|
|
67
|
+
output_dem_dir=None,
|
|
67
68
|
):
|
|
68
69
|
|
|
69
70
|
super().__init__(
|
|
@@ -73,50 +74,27 @@ class SharelocGeometry(AbstractGeometry):
|
|
|
73
74
|
default_alt=default_alt,
|
|
74
75
|
pairs_for_roi=pairs_for_roi,
|
|
75
76
|
scaling_coeff=scaling_coeff,
|
|
77
|
+
output_dem_dir=output_dem_dir,
|
|
76
78
|
)
|
|
77
79
|
|
|
78
|
-
self.dem_roi = None
|
|
79
|
-
self.roi_shareloc = None
|
|
80
|
-
self.elevation = None
|
|
81
|
-
|
|
82
|
-
# a margin is needed for cubic interpolation
|
|
83
|
-
self.rectification_grid_margin = 0
|
|
84
|
-
if self.interpolator == "cubic":
|
|
85
|
-
self.rectification_grid_margin = 5
|
|
86
|
-
|
|
87
|
-
# compute roi only when generating geometry object with dem
|
|
88
|
-
# even if dem is None
|
|
89
|
-
if geoid is not None and pairs_for_roi is not None:
|
|
90
|
-
self.dem_roi_epsg = 4326
|
|
91
|
-
if dem is not None:
|
|
92
|
-
# Get dem epsg
|
|
93
|
-
self.dem_roi_epsg = inputs.rasterio_get_epsg(dem)
|
|
94
|
-
|
|
95
|
-
self.roi_shareloc = self.get_roi(
|
|
96
|
-
pairs_for_roi,
|
|
97
|
-
self.dem_roi_epsg,
|
|
98
|
-
z_min=0,
|
|
99
|
-
z_max=0,
|
|
100
|
-
margin=self.dem_roi_margin,
|
|
101
|
-
)
|
|
102
|
-
# change convention
|
|
103
|
-
self.dem_roi = [
|
|
104
|
-
self.roi_shareloc[1],
|
|
105
|
-
self.roi_shareloc[0],
|
|
106
|
-
self.roi_shareloc[3],
|
|
107
|
-
self.roi_shareloc[2],
|
|
108
|
-
]
|
|
109
|
-
|
|
110
80
|
if dem is not None:
|
|
111
|
-
|
|
112
81
|
# fill_nodata option should be set when dealing with void in DTM
|
|
113
|
-
# see shareloc DTM limitations in sphinx doc for further
|
|
114
|
-
|
|
82
|
+
# see shareloc DTM limitations in sphinx doc for further detailsd
|
|
115
83
|
try:
|
|
84
|
+
if self.dem_roi is None:
|
|
85
|
+
roi_shareloc = None
|
|
86
|
+
else:
|
|
87
|
+
# From (x, y) to (y, x)
|
|
88
|
+
roi_shareloc = [
|
|
89
|
+
self.dem_roi[1],
|
|
90
|
+
self.dem_roi[0],
|
|
91
|
+
self.dem_roi[3],
|
|
92
|
+
self.dem_roi[2],
|
|
93
|
+
]
|
|
116
94
|
dtm_image = dtm_reader(
|
|
117
|
-
dem,
|
|
118
|
-
geoid,
|
|
119
|
-
roi=
|
|
95
|
+
self.dem,
|
|
96
|
+
self.geoid,
|
|
97
|
+
roi=roi_shareloc,
|
|
120
98
|
roi_is_in_physical_space=True,
|
|
121
99
|
fill_nodata="mean",
|
|
122
100
|
fill_value=0.0,
|
|
@@ -143,7 +121,56 @@ class SharelocGeometry(AbstractGeometry):
|
|
|
143
121
|
else:
|
|
144
122
|
self.elevation = default_alt
|
|
145
123
|
|
|
146
|
-
def
|
|
124
|
+
def check_conf(self, conf):
|
|
125
|
+
"""
|
|
126
|
+
Check configuration
|
|
127
|
+
|
|
128
|
+
:param conf: configuration to check
|
|
129
|
+
:type conf: str or dict
|
|
130
|
+
|
|
131
|
+
:return: full dict
|
|
132
|
+
:rtype: dict
|
|
133
|
+
|
|
134
|
+
"""
|
|
135
|
+
|
|
136
|
+
if conf is None:
|
|
137
|
+
raise RuntimeError("Geometry plugin configuration is None")
|
|
138
|
+
|
|
139
|
+
overloaded_conf = {}
|
|
140
|
+
|
|
141
|
+
if isinstance(conf, str):
|
|
142
|
+
conf = {"plugin_name": conf}
|
|
143
|
+
|
|
144
|
+
# overload conf
|
|
145
|
+
overloaded_conf["plugin_name"] = conf.get(
|
|
146
|
+
"plugin_name", "SharelocGeometry"
|
|
147
|
+
)
|
|
148
|
+
overloaded_conf["interpolator"] = conf.get("interpolator", "cubic")
|
|
149
|
+
overloaded_conf["dem_roi_margin"] = conf.get(
|
|
150
|
+
"dem_roi_margin", [0.25, 0.02]
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
geometry_schema = {
|
|
154
|
+
"plugin_name": str,
|
|
155
|
+
"interpolator": And(str, lambda x: x in ["cubic", "linear"]),
|
|
156
|
+
"dem_roi_margin": [float],
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
# Check conf
|
|
160
|
+
checker = Checker(geometry_schema)
|
|
161
|
+
checker.validate(overloaded_conf)
|
|
162
|
+
|
|
163
|
+
return overloaded_conf
|
|
164
|
+
|
|
165
|
+
def get_roi( # pylint: disable=too-many-positional-arguments
|
|
166
|
+
self,
|
|
167
|
+
pairs_for_roi,
|
|
168
|
+
epsg,
|
|
169
|
+
z_min=0,
|
|
170
|
+
z_max=0,
|
|
171
|
+
linear_margin=0,
|
|
172
|
+
constant_margin=0.012,
|
|
173
|
+
):
|
|
147
174
|
"""
|
|
148
175
|
Compute region of interest for intersection of DEM
|
|
149
176
|
|
|
@@ -151,35 +178,17 @@ class SharelocGeometry(AbstractGeometry):
|
|
|
151
178
|
:type pairs_for_roi: List[(str, dict, str, dict)]
|
|
152
179
|
:param dem_epsg: output EPSG code for ROI
|
|
153
180
|
:type dem_epsg: int
|
|
154
|
-
:param
|
|
155
|
-
:type
|
|
181
|
+
:param linear_margin: margin for ROI (factor of initial ROI size)
|
|
182
|
+
:type linear_margin: float
|
|
183
|
+
:param constant_margin: margin for ROI in degrees
|
|
184
|
+
:type constant_margin: float
|
|
156
185
|
"""
|
|
186
|
+
base_roi = super().get_roi(
|
|
187
|
+
pairs_for_roi, epsg, z_min, z_max, linear_margin, constant_margin
|
|
188
|
+
)
|
|
189
|
+
|
|
157
190
|
coords_list = []
|
|
158
|
-
for image1, geomodel1,
|
|
159
|
-
# Footprint of left image with altitude z_min
|
|
160
|
-
coords_list.extend(
|
|
161
|
-
self.image_envelope(
|
|
162
|
-
image1["main_file"], geomodel1, elevation=z_min
|
|
163
|
-
)
|
|
164
|
-
)
|
|
165
|
-
# Footprint of left image with altitude z_max
|
|
166
|
-
coords_list.extend(
|
|
167
|
-
self.image_envelope(
|
|
168
|
-
image1["main_file"], geomodel1, elevation=z_max
|
|
169
|
-
)
|
|
170
|
-
)
|
|
171
|
-
# Footprint of right image with altitude z_min
|
|
172
|
-
coords_list.extend(
|
|
173
|
-
self.image_envelope(
|
|
174
|
-
image2["main_file"], geomodel2, elevation=z_min
|
|
175
|
-
)
|
|
176
|
-
)
|
|
177
|
-
# Footprint of right image with altitude z_max
|
|
178
|
-
coords_list.extend(
|
|
179
|
-
self.image_envelope(
|
|
180
|
-
image2["main_file"], geomodel2, elevation=z_max
|
|
181
|
-
)
|
|
182
|
-
)
|
|
191
|
+
for image1, geomodel1, _, geomodel2 in pairs_for_roi:
|
|
183
192
|
# Footprint of rectification grid (with margins)
|
|
184
193
|
image1 = SharelocGeometry.load_image(image1["main_file"])
|
|
185
194
|
geomodel1 = self.load_geom_model(geomodel1)
|
|
@@ -206,28 +215,45 @@ class SharelocGeometry(AbstractGeometry):
|
|
|
206
215
|
)
|
|
207
216
|
lat_min, lon_min, lat_max, lon_max = list(epipolar_extent)
|
|
208
217
|
coords_list.extend([(lon_min, lat_min), (lon_max, lat_max)])
|
|
218
|
+
|
|
209
219
|
lon_list, lat_list = list(zip(*coords_list)) # noqa: B905
|
|
210
220
|
roi = [
|
|
211
|
-
min(
|
|
212
|
-
min(
|
|
213
|
-
max(
|
|
214
|
-
max(
|
|
221
|
+
min(lon_list) - constant_margin,
|
|
222
|
+
min(lat_list) - constant_margin,
|
|
223
|
+
max(lon_list) + constant_margin,
|
|
224
|
+
max(lat_list) + constant_margin,
|
|
215
225
|
]
|
|
216
226
|
points = np.array(
|
|
217
227
|
[
|
|
218
|
-
(roi[
|
|
219
|
-
(roi[
|
|
220
|
-
(roi[
|
|
221
|
-
(roi[
|
|
228
|
+
(roi[0], roi[1], 0),
|
|
229
|
+
(roi[2], roi[3], 0),
|
|
230
|
+
(roi[0], roi[1], 0),
|
|
231
|
+
(roi[2], roi[3], 0),
|
|
222
232
|
]
|
|
223
233
|
)
|
|
224
234
|
new_points = projection.point_cloud_conversion(points, 4326, epsg)
|
|
225
235
|
roi = [
|
|
226
|
-
min(new_points[:, 1]),
|
|
227
236
|
min(new_points[:, 0]),
|
|
228
|
-
|
|
237
|
+
min(new_points[:, 1]),
|
|
229
238
|
max(new_points[:, 0]),
|
|
239
|
+
max(new_points[:, 1]),
|
|
240
|
+
]
|
|
241
|
+
|
|
242
|
+
lon_size = roi[2] - roi[0]
|
|
243
|
+
lat_size = roi[3] - roi[1]
|
|
244
|
+
|
|
245
|
+
roi[0] -= linear_margin * lon_size
|
|
246
|
+
roi[1] -= linear_margin * lat_size
|
|
247
|
+
roi[2] += linear_margin * lon_size
|
|
248
|
+
roi[3] += linear_margin * lat_size
|
|
249
|
+
|
|
250
|
+
roi = [
|
|
251
|
+
min(roi[0], base_roi[0]),
|
|
252
|
+
min(roi[1], base_roi[1]),
|
|
253
|
+
max(roi[2], base_roi[2]),
|
|
254
|
+
max(roi[3], base_roi[3]),
|
|
230
255
|
]
|
|
256
|
+
|
|
231
257
|
return roi
|
|
232
258
|
|
|
233
259
|
@staticmethod
|
|
@@ -306,7 +332,7 @@ class SharelocGeometry(AbstractGeometry):
|
|
|
306
332
|
|
|
307
333
|
return sensor, overloaded_geomodel
|
|
308
334
|
|
|
309
|
-
def triangulate(
|
|
335
|
+
def triangulate( # pylint: disable=too-many-positional-arguments
|
|
310
336
|
self,
|
|
311
337
|
sensor1,
|
|
312
338
|
sensor2,
|
|
@@ -317,6 +343,7 @@ class SharelocGeometry(AbstractGeometry):
|
|
|
317
343
|
grid1: Union[dict, RectificationGrid],
|
|
318
344
|
grid2: Union[dict, RectificationGrid],
|
|
319
345
|
roi_key: Union[None, str] = None,
|
|
346
|
+
interpolation_method=None,
|
|
320
347
|
) -> np.ndarray:
|
|
321
348
|
"""
|
|
322
349
|
Performs triangulation from cars disparity or matches dataset
|
|
@@ -398,6 +425,7 @@ class SharelocGeometry(AbstractGeometry):
|
|
|
398
425
|
|
|
399
426
|
return llh
|
|
400
427
|
|
|
428
|
+
# pylint: disable=too-many-positional-arguments
|
|
401
429
|
def generate_epipolar_grids(
|
|
402
430
|
self,
|
|
403
431
|
sensor1,
|
|
@@ -481,7 +509,7 @@ class SharelocGeometry(AbstractGeometry):
|
|
|
481
509
|
disp_to_alt_ratio,
|
|
482
510
|
)
|
|
483
511
|
|
|
484
|
-
def direct_loc(
|
|
512
|
+
def direct_loc( # pylint: disable=too-many-positional-arguments
|
|
485
513
|
self,
|
|
486
514
|
sensor,
|
|
487
515
|
geomodel,
|
|
@@ -526,7 +554,7 @@ class SharelocGeometry(AbstractGeometry):
|
|
|
526
554
|
)
|
|
527
555
|
return latlonalt
|
|
528
556
|
|
|
529
|
-
def inverse_loc(
|
|
557
|
+
def inverse_loc( # pylint: disable=too-many-positional-arguments
|
|
530
558
|
self,
|
|
531
559
|
sensor,
|
|
532
560
|
geomodel,
|
cars/core/inputs.py
CHANGED
|
@@ -35,6 +35,7 @@ import fiona
|
|
|
35
35
|
import numpy as np
|
|
36
36
|
import rasterio as rio
|
|
37
37
|
import xarray as xr
|
|
38
|
+
from affine import Affine
|
|
38
39
|
from json_checker import Checker
|
|
39
40
|
from pyproj import CRS
|
|
40
41
|
from rasterio.warp import Resampling, calculate_default_transform, reproject
|
|
@@ -107,7 +108,7 @@ def rasterio_get_values(raster_file: str, x_list, y_list, proj_function):
|
|
|
107
108
|
cloud_out = proj_function(cloud_in, 4326, file_espg)
|
|
108
109
|
|
|
109
110
|
# get the transform and inverse
|
|
110
|
-
aff_tr =
|
|
111
|
+
aff_tr = rasterio_get_transform(raster_file)
|
|
111
112
|
np_tr = np.array(
|
|
112
113
|
[
|
|
113
114
|
[aff_tr[0], aff_tr[1], aff_tr[2]],
|
|
@@ -120,17 +121,28 @@ def rasterio_get_values(raster_file: str, x_list, y_list, proj_function):
|
|
|
120
121
|
# convert sensor to pixel coordinates
|
|
121
122
|
pix_pos = np.hstack([cloud_out, np.ones((len(cloud_out), 1))])
|
|
122
123
|
pix_pos = inv_tr @ pix_pos.T
|
|
123
|
-
pix_pos = pix_pos.T[:, [1, 0]].astype(
|
|
124
|
+
pix_pos = pix_pos.T[:, [1, 0]].astype(
|
|
125
|
+
int
|
|
126
|
+
) # convention (row, col) i.e. (y, x)
|
|
127
|
+
|
|
128
|
+
# crop to dem bounds
|
|
129
|
+
ul_corner = np.array([0, 0])
|
|
130
|
+
lr_corner = np.array([descriptor.height, descriptor.width])
|
|
131
|
+
pix_pos_clipped = np.clip(pix_pos, ul_corner, lr_corner)
|
|
132
|
+
out_of_bounds_pix = np.any(pix_pos != pix_pos_clipped, axis=1)
|
|
133
|
+
pix_pos = pix_pos_clipped
|
|
124
134
|
|
|
125
135
|
# get the data needed
|
|
126
136
|
min_pt = pix_pos.min(axis=0)
|
|
127
137
|
max_pt = pix_pos.max(axis=0)
|
|
128
138
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
window = Window(min_pt[1], min_pt[0],
|
|
139
|
+
height = max_pt[0] - min_pt[0] + 1
|
|
140
|
+
width = max_pt[1] - min_pt[1] + 1
|
|
141
|
+
window = Window(min_pt[1], min_pt[0], width, height)
|
|
132
142
|
|
|
133
143
|
data = descriptor.read(1, window=window)
|
|
144
|
+
if data.size == 0:
|
|
145
|
+
return None
|
|
134
146
|
|
|
135
147
|
# read the data for all points
|
|
136
148
|
max_sampled_pos = np.array(data.shape)[:2] - 1
|
|
@@ -142,6 +154,7 @@ def rasterio_get_values(raster_file: str, x_list, y_list, proj_function):
|
|
|
142
154
|
|
|
143
155
|
if nodata_value is not None:
|
|
144
156
|
z_list[z_list == nodata_value] = np.nan
|
|
157
|
+
z_list[out_of_bounds_pix] = np.nan
|
|
145
158
|
|
|
146
159
|
return z_list
|
|
147
160
|
|
|
@@ -253,19 +266,32 @@ def rasterio_get_pixel_points(raster_file: str, terrain_points) -> list:
|
|
|
253
266
|
|
|
254
267
|
pixel_points = []
|
|
255
268
|
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
terrain_points[row, 1],
|
|
263
|
-
)
|
|
269
|
+
for row in range(terrain_points.shape[0]):
|
|
270
|
+
pixel_points.append(
|
|
271
|
+
rio.transform.rowcol(
|
|
272
|
+
rasterio_get_transform(raster_file),
|
|
273
|
+
terrain_points[row, 0],
|
|
274
|
+
terrain_points[row, 1],
|
|
264
275
|
)
|
|
276
|
+
)
|
|
265
277
|
|
|
266
278
|
return np.array(pixel_points)
|
|
267
279
|
|
|
268
280
|
|
|
281
|
+
def rasterio_get_resolution(raster_file: str) -> Tuple[float, float]:
|
|
282
|
+
"""
|
|
283
|
+
Get the resolution of raster_file
|
|
284
|
+
|
|
285
|
+
:param raster_file: Image file
|
|
286
|
+
:return: The resolution (res_x, res_y)
|
|
287
|
+
:rtype: tuple
|
|
288
|
+
"""
|
|
289
|
+
transform = list(rasterio_get_transform(raster_file))
|
|
290
|
+
res_x = transform[0]
|
|
291
|
+
res_y = transform[4]
|
|
292
|
+
return (abs(res_x), abs(res_y))
|
|
293
|
+
|
|
294
|
+
|
|
269
295
|
def rasterio_get_bounds(
|
|
270
296
|
raster_file: str, apply_resolution_sign=False
|
|
271
297
|
) -> Tuple[int, int]:
|
|
@@ -278,8 +304,7 @@ def rasterio_get_bounds(
|
|
|
278
304
|
|
|
279
305
|
# get sign of resolution
|
|
280
306
|
if apply_resolution_sign:
|
|
281
|
-
|
|
282
|
-
transform = list(profile["transform"])
|
|
307
|
+
transform = list(rasterio_get_transform(raster_file))
|
|
283
308
|
res_x = transform[0]
|
|
284
309
|
res_y = transform[4]
|
|
285
310
|
res_x /= abs(res_x)
|
|
@@ -354,15 +379,28 @@ def rasterio_get_profile(raster_file: str) -> Dict:
|
|
|
354
379
|
return descriptor.profile
|
|
355
380
|
|
|
356
381
|
|
|
357
|
-
def rasterio_get_transform(raster_file: str) -> Dict:
|
|
382
|
+
def rasterio_get_transform(raster_file: str, convention: str = None) -> Dict:
|
|
358
383
|
"""
|
|
359
384
|
Get the transform of an image file
|
|
360
385
|
|
|
361
386
|
:param raster_file: Image file
|
|
387
|
+
:param convention: The convention to follow: None, "north" or "south"
|
|
362
388
|
:return: The transform of the given image
|
|
363
389
|
"""
|
|
364
|
-
with rio.open(raster_file, "r") as
|
|
365
|
-
|
|
390
|
+
with rio.open(raster_file, "r") as dsc:
|
|
391
|
+
src_tr = dsc.transform
|
|
392
|
+
|
|
393
|
+
if convention == "north" and src_tr.e < 0:
|
|
394
|
+
src_tr = Affine(
|
|
395
|
+
src_tr.a, src_tr.b, src_tr.c, -src_tr.d, -src_tr.e, -src_tr.f
|
|
396
|
+
)
|
|
397
|
+
|
|
398
|
+
elif convention == "south" and src_tr.e > 0:
|
|
399
|
+
src_tr = Affine(
|
|
400
|
+
src_tr.a, src_tr.b, src_tr.c, -src_tr.d, -src_tr.e, -src_tr.f
|
|
401
|
+
)
|
|
402
|
+
|
|
403
|
+
return src_tr
|
|
366
404
|
|
|
367
405
|
|
|
368
406
|
def rasterio_get_epsg(raster_file: str) -> int:
|
|
@@ -423,7 +461,7 @@ def rasterio_transform_epsg(file_name, new_epsg):
|
|
|
423
461
|
reproject(
|
|
424
462
|
source=rio.band(src, i),
|
|
425
463
|
destination=rio.band(dst, i),
|
|
426
|
-
src_transform=
|
|
464
|
+
src_transform=rasterio_get_transform(file_name),
|
|
427
465
|
src_crs=src.crs,
|
|
428
466
|
dst_transform=transform,
|
|
429
467
|
dst_crs=new_epsg,
|
cars/core/outputs.py
CHANGED
|
@@ -110,7 +110,7 @@ def write_vector(polys, path_to_file, epsg, driver="GPKG"):
|
|
|
110
110
|
vector_file.write(poly_dict)
|
|
111
111
|
|
|
112
112
|
|
|
113
|
-
def rasterio_write_georaster(
|
|
113
|
+
def rasterio_write_georaster( # pylint: disable=too-many-positional-arguments
|
|
114
114
|
raster_file: str,
|
|
115
115
|
data: np.ndarray,
|
|
116
116
|
profile: dict = None,
|
cars/core/preprocessing.py
CHANGED
|
@@ -72,13 +72,26 @@ def get_utm_zone_as_epsg_code(lon, lat):
|
|
|
72
72
|
)
|
|
73
73
|
return 32632
|
|
74
74
|
|
|
75
|
+
if lat > 84:
|
|
76
|
+
logging.warning(
|
|
77
|
+
"Since the latitude is above 84°, the EPSG 32661 will be used."
|
|
78
|
+
)
|
|
79
|
+
return 32661
|
|
80
|
+
|
|
81
|
+
if lat < -80:
|
|
82
|
+
logging.warning(
|
|
83
|
+
"Since the latitude is under -80°, the EPSG 32761 will be used."
|
|
84
|
+
)
|
|
85
|
+
return 32761
|
|
86
|
+
|
|
75
87
|
zone = utm.from_latlon(lat, lon)[2]
|
|
76
88
|
|
|
77
89
|
north_south = 600 if lat >= 0 else 700
|
|
78
90
|
return 32000 + north_south + zone
|
|
79
91
|
|
|
80
92
|
|
|
81
|
-
|
|
93
|
+
@cars_profile(name="Compute terrain bbox")
|
|
94
|
+
def compute_terrain_bbox( # pylint: disable=too-many-positional-arguments # noqa: 751
|
|
82
95
|
sensor_image_left,
|
|
83
96
|
sensor_image_right,
|
|
84
97
|
epipolar_image_left,
|
|
@@ -375,7 +388,7 @@ def compute_roi_poly(input_roi_poly, input_roi_epsg, epsg):
|
|
|
375
388
|
|
|
376
389
|
|
|
377
390
|
@cars_profile(name="Compute epsg")
|
|
378
|
-
def compute_epsg(
|
|
391
|
+
def compute_epsg( # pylint: disable=too-many-positional-arguments
|
|
379
392
|
sensor_image_left,
|
|
380
393
|
sensor_image_right,
|
|
381
394
|
grid_left,
|
|
@@ -518,6 +531,7 @@ def crop_terrain_bounds_with_roi(roi_poly, xmin, ymin, xmax, ymax):
|
|
|
518
531
|
return new_xmin, new_ymin, new_xmax, new_ymax
|
|
519
532
|
|
|
520
533
|
|
|
534
|
+
@cars_profile(name="Compute terrain bounds")
|
|
521
535
|
def compute_terrain_bounds(list_of_terrain_roi, roi_poly=None, resolution=0.5):
|
|
522
536
|
"""
|
|
523
537
|
Compute Terrain bounds of merged pairs
|
|
@@ -650,7 +664,7 @@ def convert_optimal_tile_size_with_epsg(
|
|
|
650
664
|
|
|
651
665
|
|
|
652
666
|
@cars_profile(name="Compute epipolar roi")
|
|
653
|
-
def compute_epipolar_roi(
|
|
667
|
+
def compute_epipolar_roi( # pylint: disable=too-many-positional-arguments
|
|
654
668
|
terrain_roi_poly,
|
|
655
669
|
terrain_roi_epsg,
|
|
656
670
|
geometry_plugin,
|
cars/core/projection.py
CHANGED
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
Projection module:
|
|
23
23
|
contains some general purpose functions using polygons and data projections
|
|
24
24
|
"""
|
|
25
|
-
# pylint: disable=too-many-lines
|
|
25
|
+
# pylint: disable=C0302(too-many-lines)
|
|
26
26
|
|
|
27
27
|
# Standard imports
|
|
28
28
|
import logging
|
|
@@ -42,6 +42,7 @@ from shapely.ops import transform
|
|
|
42
42
|
|
|
43
43
|
from cars.core import constants as cst
|
|
44
44
|
from cars.core import inputs, outputs, utils
|
|
45
|
+
from cars.orchestrator.cluster.log_wrapper import cars_profile
|
|
45
46
|
|
|
46
47
|
|
|
47
48
|
def compute_dem_intersection_with_poly( # noqa: C901
|
|
@@ -219,7 +220,7 @@ def geo_to_ecef(
|
|
|
219
220
|
)[0]
|
|
220
221
|
|
|
221
222
|
|
|
222
|
-
def ecef_to_enu(
|
|
223
|
+
def ecef_to_enu( # pylint: disable=too-many-positional-arguments
|
|
223
224
|
x_ecef: np.ndarray,
|
|
224
225
|
y_ecef: np.ndarray,
|
|
225
226
|
z_ecef: np.ndarray,
|
|
@@ -269,7 +270,7 @@ def ecef_to_enu(
|
|
|
269
270
|
return x_east, y_north, z_up
|
|
270
271
|
|
|
271
272
|
|
|
272
|
-
def geo_to_enu(
|
|
273
|
+
def geo_to_enu( # pylint: disable=too-many-positional-arguments
|
|
273
274
|
lat: np.ndarray,
|
|
274
275
|
lon: np.ndarray,
|
|
275
276
|
alt: np.ndarray,
|
|
@@ -318,7 +319,7 @@ def enu_to_aer(
|
|
|
318
319
|
return azimuth, elevation, xyz_range
|
|
319
320
|
|
|
320
321
|
|
|
321
|
-
def geo_to_aer(
|
|
322
|
+
def geo_to_aer( # pylint: disable=too-many-positional-arguments
|
|
322
323
|
lat: np.ndarray,
|
|
323
324
|
lon: np.ndarray,
|
|
324
325
|
alt: np.ndarray,
|
|
@@ -529,6 +530,8 @@ def ground_polygon_from_envelopes(
|
|
|
529
530
|
return inter, inter.bounds
|
|
530
531
|
|
|
531
532
|
|
|
533
|
+
# pylint: disable=too-many-positional-arguments
|
|
534
|
+
@cars_profile(name="Ground intersection envelopes", interval=0.5)
|
|
532
535
|
def ground_intersection_envelopes(
|
|
533
536
|
sensor1,
|
|
534
537
|
sensor2,
|
|
@@ -595,7 +598,7 @@ def ground_intersection_envelopes(
|
|
|
595
598
|
return inter_poly, (inter_xmin, inter_ymin, inter_xmax, inter_ymax)
|
|
596
599
|
|
|
597
600
|
|
|
598
|
-
def get_ground_direction(
|
|
601
|
+
def get_ground_direction( # pylint: disable=too-many-positional-arguments
|
|
599
602
|
sensor,
|
|
600
603
|
geomodel,
|
|
601
604
|
geometry_plugin: str,
|
|
@@ -668,7 +671,7 @@ def get_ground_direction(
|
|
|
668
671
|
return np.array([lat0, lon0, alt0, lat, lon, alt])
|
|
669
672
|
|
|
670
673
|
|
|
671
|
-
def get_ground_angles(
|
|
674
|
+
def get_ground_angles( # pylint: disable=too-many-positional-arguments
|
|
672
675
|
sensor1,
|
|
673
676
|
sensor2,
|
|
674
677
|
geomodel1,
|
cars/core/tiling.py
CHANGED
|
@@ -40,8 +40,10 @@ from scipy.spatial import tsearch # pylint: disable=no-name-in-module
|
|
|
40
40
|
from shapely.geometry import box, mapping
|
|
41
41
|
from shapely.geometry.multipolygon import MultiPolygon
|
|
42
42
|
|
|
43
|
+
from cars.orchestrator.cluster.log_wrapper import cars_profile
|
|
43
44
|
|
|
44
|
-
|
|
45
|
+
|
|
46
|
+
def grid( # pylint: disable=too-many-positional-arguments
|
|
45
47
|
xmin: float, ymin: float, xmax: float, ymax: float, xsplit: int, ysplit: int
|
|
46
48
|
) -> np.ndarray:
|
|
47
49
|
"""
|
|
@@ -74,6 +76,7 @@ def grid(
|
|
|
74
76
|
return out_grid
|
|
75
77
|
|
|
76
78
|
|
|
79
|
+
@cars_profile(name="Transform four layers to two layers grid", interval=0.5)
|
|
77
80
|
def transform_four_layers_to_two_layers_grid(tiling_grid, terrain=False):
|
|
78
81
|
"""
|
|
79
82
|
Transform a 4 layer grid: (N, M, 4) containing
|
|
@@ -115,6 +118,7 @@ def transform_four_layers_to_two_layers_grid(tiling_grid, terrain=False):
|
|
|
115
118
|
return arr
|
|
116
119
|
|
|
117
120
|
|
|
121
|
+
@cars_profile(name="Transform disp range grid to two layers", interval=0.5)
|
|
118
122
|
def transform_disp_range_grid_to_two_layers(disp_min_grid, disp_max_grid):
|
|
119
123
|
"""
|
|
120
124
|
Transform tiling disp min and max to N+1 M+1 array corresponding
|
|
@@ -154,7 +158,7 @@ def transform_disp_range_grid_to_two_layers(disp_min_grid, disp_max_grid):
|
|
|
154
158
|
return disp_min, disp_max
|
|
155
159
|
|
|
156
160
|
|
|
157
|
-
def generate_tiling_grid(
|
|
161
|
+
def generate_tiling_grid( # pylint: disable=too-many-positional-arguments
|
|
158
162
|
row_min: float,
|
|
159
163
|
col_min: float,
|
|
160
164
|
row_max: float,
|
|
@@ -199,7 +203,9 @@ def generate_tiling_grid(
|
|
|
199
203
|
return out_grid
|
|
200
204
|
|
|
201
205
|
|
|
202
|
-
def split(
|
|
206
|
+
def split(
|
|
207
|
+
xmin, ymin, xmax, ymax, xsplit, ysplit
|
|
208
|
+
): # pylint: disable=too-many-positional-arguments
|
|
203
209
|
"""
|
|
204
210
|
Split a region defined by [xmin, xmax] x [ymin, ymax]
|
|
205
211
|
in splits of xsplit x ysplit size
|
|
@@ -561,6 +567,7 @@ def region_hash_string(region: Tuple):
|
|
|
561
567
|
return "{}_{}_{}_{}".format(region[0], region[1], region[2], region[3])
|
|
562
568
|
|
|
563
569
|
|
|
570
|
+
# pylint: disable=too-many-positional-arguments
|
|
564
571
|
def get_corresponding_tiles_row_col(
|
|
565
572
|
terrain_tiling_grid: np.ndarray,
|
|
566
573
|
row: int,
|
|
@@ -339,7 +339,7 @@ class CarsDataset:
|
|
|
339
339
|
|
|
340
340
|
return new_window
|
|
341
341
|
|
|
342
|
-
def create_grid(
|
|
342
|
+
def create_grid( # pylint: disable=too-many-positional-arguments
|
|
343
343
|
self,
|
|
344
344
|
nb_col: int,
|
|
345
345
|
nb_row: int,
|
|
@@ -435,7 +435,7 @@ class CarsDataset:
|
|
|
435
435
|
tiles_row.append(None)
|
|
436
436
|
self.tiles.append(tiles_row)
|
|
437
437
|
|
|
438
|
-
def generate_descriptor(
|
|
438
|
+
def generate_descriptor( # pylint: disable=too-many-positional-arguments
|
|
439
439
|
self, future_result, file_name, tag=None, dtype=None, nodata=None
|
|
440
440
|
):
|
|
441
441
|
"""
|
|
@@ -579,7 +579,7 @@ def run_save_arrays(future_result, file_name, tag=None, descriptor=None):
|
|
|
579
579
|
)
|
|
580
580
|
|
|
581
581
|
|
|
582
|
-
def run_save_points(
|
|
582
|
+
def run_save_points( # pylint: disable=too-many-positional-arguments
|
|
583
583
|
future_result,
|
|
584
584
|
file_name,
|
|
585
585
|
overwrite=False,
|
|
@@ -840,7 +840,7 @@ def save_single_tile_dict(dict_cars, tile_path_name: str):
|
|
|
840
840
|
dict_cars.attrs = saved_dict_cars_attrs
|
|
841
841
|
|
|
842
842
|
|
|
843
|
-
def fill_dataset(
|
|
843
|
+
def fill_dataset( # pylint: disable=too-many-positional-arguments
|
|
844
844
|
dataset,
|
|
845
845
|
saving_info=None,
|
|
846
846
|
window=None,
|
|
@@ -939,7 +939,7 @@ def fill_dict(data_dict, saving_info=None, attributes=None):
|
|
|
939
939
|
data_dict.attrs[SAVING_INFO] = saving_info
|
|
940
940
|
|
|
941
941
|
|
|
942
|
-
def save_all_dataframe(
|
|
942
|
+
def save_all_dataframe( # pylint: disable=too-many-positional-arguments
|
|
943
943
|
dataframe,
|
|
944
944
|
file_name,
|
|
945
945
|
save_by_pair=False,
|