ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
RGBDOdometry.cpp
Go to the documentation of this file.
1 // ----------------------------------------------------------------------------
2 // - CloudViewer: www.cloudViewer.org -
3 // ----------------------------------------------------------------------------
4 // Copyright (c) 2018-2024 www.cloudViewer.org
5 // SPDX-License-Identifier: MIT
6 // ----------------------------------------------------------------------------
7 
9 
12 
13 namespace cloudViewer {
14 namespace t {
15 namespace pipelines {
16 namespace kernel {
17 namespace odometry {
18 
20  const core::Tensor &source_vertex_map,
21  const core::Tensor &target_vertex_map,
22  const core::Tensor &target_normal_map,
23  const core::Tensor &intrinsics,
24  const core::Tensor &init_source_to_target,
25  core::Tensor &delta,
26  float &inlier_residual,
27  int &inlier_count,
28  const float depth_outlier_trunc,
29  const float depth_huber_delta) {
30  // Only Float32 is supported as of now. TODO. Support Float64.
31  core::AssertTensorDtypes(source_vertex_map, {core::Float32});
32 
33  const core::Dtype supported_dtype = source_vertex_map.GetDtype();
34  const core::Device device = source_vertex_map.GetDevice();
35 
36  core::AssertTensorDtype(target_vertex_map, supported_dtype);
37  core::AssertTensorDtype(target_normal_map, supported_dtype);
38 
39  core::AssertTensorDevice(target_vertex_map, device);
40  core::AssertTensorDevice(target_normal_map, device);
41 
42  core::AssertTensorShape(intrinsics, {3, 3});
43  core::AssertTensorShape(init_source_to_target, {4, 4});
44 
45  static const core::Device host("CPU:0");
46  core::Tensor intrinsics_d = intrinsics.To(host, core::Float64).Contiguous();
47  core::Tensor trans_d =
48  init_source_to_target.To(host, core::Float64).Contiguous();
49 
50  if (device.IsCPU()) {
52  source_vertex_map, target_vertex_map, target_normal_map,
53  intrinsics_d, trans_d, delta, inlier_residual, inlier_count,
54  depth_outlier_trunc, depth_huber_delta);
55  } else if (device.IsCUDA()) {
56  core::CUDAScopedDevice scoped_device(source_vertex_map.GetDevice());
57  CUDA_CALL(ComputeOdometryResultPointToPlaneCUDA, source_vertex_map,
58  target_vertex_map, target_normal_map, intrinsics_d, trans_d,
59  delta, inlier_residual, inlier_count, depth_outlier_trunc,
60  depth_huber_delta);
61  } else {
62  utility::LogError("Unimplemented device.");
63  }
64 }
65 
67  const core::Tensor &target_depth,
68  const core::Tensor &source_intensity,
69  const core::Tensor &target_intensity,
70  const core::Tensor &target_intensity_dx,
71  const core::Tensor &target_intensity_dy,
72  const core::Tensor &source_vertex_map,
73  const core::Tensor &intrinsics,
74  const core::Tensor &init_source_to_target,
75  core::Tensor &delta,
76  float &inlier_residual,
77  int &inlier_count,
78  const float depth_outlier_trunc,
79  const float intensity_huber_delta) {
80  // Only Float32 is supported as of now. TODO. Support Float64.
81  core::AssertTensorDtypes(source_vertex_map, {core::Float32});
82 
83  const core::Dtype supported_dtype = source_vertex_map.GetDtype();
84  const core::Device device = source_vertex_map.GetDevice();
85 
86  core::AssertTensorDtype(source_depth, supported_dtype);
87  core::AssertTensorDtype(target_depth, supported_dtype);
88  core::AssertTensorDtype(source_intensity, supported_dtype);
89  core::AssertTensorDtype(target_intensity, supported_dtype);
90  core::AssertTensorDtype(target_intensity_dx, supported_dtype);
91  core::AssertTensorDtype(target_intensity_dy, supported_dtype);
92 
93  core::AssertTensorDevice(source_depth, device);
94  core::AssertTensorDevice(target_depth, device);
95  core::AssertTensorDevice(source_intensity, device);
96  core::AssertTensorDevice(target_intensity, device);
97  core::AssertTensorDevice(target_intensity_dx, device);
98  core::AssertTensorDevice(target_intensity_dy, device);
99 
100  core::AssertTensorShape(intrinsics, {3, 3});
101  core::AssertTensorShape(init_source_to_target, {4, 4});
102 
103  static const core::Device host("CPU:0");
104  core::Tensor intrinsics_d = intrinsics.To(host, core::Float64).Contiguous();
105  core::Tensor trans_d =
106  init_source_to_target.To(host, core::Float64).Contiguous();
107 
108  if (device.IsCPU()) {
110  source_depth, target_depth, source_intensity, target_intensity,
111  target_intensity_dx, target_intensity_dy, source_vertex_map,
112  intrinsics_d, trans_d, delta, inlier_residual, inlier_count,
113  depth_outlier_trunc, intensity_huber_delta);
114  } else if (device.IsCUDA()) {
115  core::CUDAScopedDevice scoped_device(source_depth.GetDevice());
116  CUDA_CALL(ComputeOdometryResultIntensityCUDA, source_depth,
117  target_depth, source_intensity, target_intensity,
118  target_intensity_dx, target_intensity_dy, source_vertex_map,
119  intrinsics_d, trans_d, delta, inlier_residual, inlier_count,
120  depth_outlier_trunc, intensity_huber_delta);
121  } else {
122  utility::LogError("Unimplemented device.");
123  }
124 }
125 
126 void ComputeOdometryResultHybrid(const core::Tensor &source_depth,
127  const core::Tensor &target_depth,
128  const core::Tensor &source_intensity,
129  const core::Tensor &target_intensity,
130  const core::Tensor &target_depth_dx,
131  const core::Tensor &target_depth_dy,
132  const core::Tensor &target_intensity_dx,
133  const core::Tensor &target_intensity_dy,
134  const core::Tensor &source_vertex_map,
135  const core::Tensor &intrinsics,
136  const core::Tensor &init_source_to_target,
137  core::Tensor &delta,
138  float &inlier_residual,
139  int &inlier_count,
140  const float depth_outlier_trunc,
141  const float depth_huber_delta,
142  const float intensity_huber_delta) {
143  // Only Float32 is supported as of now. TODO. Support Float64.
144  core::AssertTensorDtypes(source_vertex_map, {core::Float32});
145 
146  const core::Dtype supported_dtype = source_vertex_map.GetDtype();
147  const core::Device device = source_vertex_map.GetDevice();
148 
149  core::AssertTensorDtype(source_depth, supported_dtype);
150  core::AssertTensorDtype(target_depth, supported_dtype);
151  core::AssertTensorDtype(source_intensity, supported_dtype);
152  core::AssertTensorDtype(target_intensity, supported_dtype);
153  core::AssertTensorDtype(target_depth_dx, supported_dtype);
154  core::AssertTensorDtype(target_depth_dy, supported_dtype);
155  core::AssertTensorDtype(target_intensity_dx, supported_dtype);
156  core::AssertTensorDtype(target_intensity_dy, supported_dtype);
157 
158  core::AssertTensorDevice(source_depth, device);
159  core::AssertTensorDevice(target_depth, device);
160  core::AssertTensorDevice(source_intensity, device);
161  core::AssertTensorDevice(target_intensity, device);
162  core::AssertTensorDevice(target_depth_dx, device);
163  core::AssertTensorDevice(target_depth_dy, device);
164  core::AssertTensorDevice(target_intensity_dx, device);
165  core::AssertTensorDevice(target_intensity_dy, device);
166 
167  core::AssertTensorShape(intrinsics, {3, 3});
168  core::AssertTensorShape(init_source_to_target, {4, 4});
169 
170  static const core::Device host("CPU:0");
171  core::Tensor intrinsics_d = intrinsics.To(host, core::Float64).Contiguous();
172  core::Tensor trans_d =
173  init_source_to_target.To(host, core::Float64).Contiguous();
174 
175  if (device.IsCPU()) {
177  source_depth, target_depth, source_intensity, target_intensity,
178  target_depth_dx, target_depth_dy, target_intensity_dx,
179  target_intensity_dy, source_vertex_map, intrinsics_d, trans_d,
180  delta, inlier_residual, inlier_count, depth_outlier_trunc,
181  depth_huber_delta, intensity_huber_delta);
182  } else if (device.IsCUDA()) {
183  core::CUDAScopedDevice scoped_device(source_depth.GetDevice());
184  CUDA_CALL(ComputeOdometryResultHybridCUDA, source_depth, target_depth,
185  source_intensity, target_intensity, target_depth_dx,
186  target_depth_dy, target_intensity_dx, target_intensity_dy,
187  source_vertex_map, intrinsics_d, trans_d, delta,
188  inlier_residual, inlier_count, depth_outlier_trunc,
189  depth_huber_delta, intensity_huber_delta);
190  } else {
191  utility::LogError("Unimplemented device.");
192  }
193 }
194 
195 void ComputeOdometryInformationMatrix(const core::Tensor &source_vertex_map,
196  const core::Tensor &target_vertex_map,
197  const core::Tensor &intrinsic,
198  const core::Tensor &source_to_target,
199  const float square_dist_thr,
200  core::Tensor &information) {
201  core::AssertTensorDtypes(source_vertex_map, {core::Float32});
202 
203  const core::Dtype supported_dtype = source_vertex_map.GetDtype();
204  const core::Device device = source_vertex_map.GetDevice();
205 
206  core::AssertTensorDtype(target_vertex_map, supported_dtype);
207  core::AssertTensorDevice(target_vertex_map, device);
208 
209  core::AssertTensorShape(intrinsic, {3, 3});
210  core::AssertTensorShape(source_to_target, {4, 4});
211 
212  static const core::Device host("CPU:0");
213  core::Tensor intrinsics_d = intrinsic.To(host, core::Float64).Contiguous();
214  core::Tensor trans_d =
215  source_to_target.To(host, core::Float64).Contiguous();
216 
217  if (device.GetType() == core::Device::DeviceType::CPU) {
219  source_vertex_map, target_vertex_map, intrinsic,
220  source_to_target, square_dist_thr, information);
221  } else if (device.GetType() == core::Device::DeviceType::CUDA) {
222  CUDA_CALL(ComputeOdometryInformationMatrixCUDA, source_vertex_map,
223  target_vertex_map, intrinsic, source_to_target,
224  square_dist_thr, information);
225  } else {
226  utility::LogError("Unimplemented device.");
227  }
228 }
229 
230 } // namespace odometry
231 } // namespace kernel
232 } // namespace pipelines
233 } // namespace t
234 } // namespace cloudViewer
Common CUDA utilities.
#define CUDA_CALL(cuda_function,...)
Definition: CUDAUtils.h:49
#define AssertTensorDevice(tensor,...)
Definition: TensorCheck.h:45
#define AssertTensorDtype(tensor,...)
Definition: TensorCheck.h:21
#define AssertTensorDtypes(tensor,...)
Definition: TensorCheck.h:33
#define AssertTensorShape(tensor,...)
Definition: TensorCheck.h:61
When CUDA is not enabled, this is a dummy class.
Definition: CUDAUtils.h:214
bool IsCUDA() const
Returns true iff device type is CUDA.
Definition: Device.h:49
DeviceType GetType() const
Returns type of the device, e.g. DeviceType::CPU, DeviceType::CUDA.
Definition: Device.h:58
bool IsCPU() const
Returns true iff device type is CPU.
Definition: Device.h:46
Tensor Contiguous() const
Definition: Tensor.cpp:772
Dtype GetDtype() const
Definition: Tensor.h:1164
Device GetDevice() const override
Definition: Tensor.cpp:1435
Tensor To(Dtype dtype, bool copy=false) const
Definition: Tensor.cpp:739
#define LogError(...)
Definition: Logging.h:60
const Dtype Float64
Definition: Dtype.cpp:43
const Dtype Float32
Definition: Dtype.cpp:42
void ComputeOdometryInformationMatrixCPU(const core::Tensor &source_vertex_map, const core::Tensor &target_vertex_map, const core::Tensor &intrinsic, const core::Tensor &source_to_target, const float square_dist_thr, core::Tensor &information)
void ComputeOdometryResultIntensity(const core::Tensor &source_depth, const core::Tensor &target_depth, const core::Tensor &source_intensity, const core::Tensor &target_intensity, const core::Tensor &target_intensity_dx, const core::Tensor &target_intensity_dy, const core::Tensor &source_vertex_map, const core::Tensor &intrinsics, const core::Tensor &init_source_to_target, core::Tensor &delta, float &inlier_residual, int &inlier_count, const float depth_outlier_trunc, const float intensity_huber_delta)
void ComputeOdometryResultHybridCPU(const core::Tensor &source_depth, const core::Tensor &target_depth, const core::Tensor &source_intensity, const core::Tensor &target_intensity, const core::Tensor &target_depth_dx, const core::Tensor &target_depth_dy, const core::Tensor &target_intensity_dx, const core::Tensor &target_intensity_dy, const core::Tensor &source_vertex_map, const core::Tensor &intrinsics, const core::Tensor &init_source_to_target, core::Tensor &delta, float &inlier_residual, int &inlier_count, const float depth_outlier_trunc, const float depth_huber_delta, const float intensity_huber_delta)
void ComputeOdometryResultPointToPlane(const core::Tensor &source_vertex_map, const core::Tensor &target_vertex_map, const core::Tensor &target_normal_map, const core::Tensor &intrinsics, const core::Tensor &init_source_to_target, core::Tensor &delta, float &inlier_residual, int &inlier_count, const float depth_outlier_trunc, const float depth_huber_delta)
void ComputeOdometryResultPointToPlaneCPU(const core::Tensor &source_vertex_map, const core::Tensor &target_vertex_map, const core::Tensor &target_normal_map, const core::Tensor &intrinsics, const core::Tensor &init_source_to_target, core::Tensor &delta, float &inlier_residual, int &inlier_count, const float depth_outlier_trunc, const float depth_huber_delta)
void ComputeOdometryInformationMatrix(const core::Tensor &source_vertex_map, const core::Tensor &target_vertex_map, const core::Tensor &intrinsic, const core::Tensor &source_to_target, const float square_dist_thr, core::Tensor &information)
void ComputeOdometryResultHybrid(const core::Tensor &source_depth, const core::Tensor &target_depth, const core::Tensor &source_intensity, const core::Tensor &target_intensity, const core::Tensor &target_depth_dx, const core::Tensor &target_depth_dy, const core::Tensor &target_intensity_dx, const core::Tensor &target_intensity_dy, const core::Tensor &source_vertex_map, const core::Tensor &intrinsics, const core::Tensor &init_source_to_target, core::Tensor &delta, float &inlier_residual, int &inlier_count, const float depth_outlier_trunc, const float depth_huber_delta, const float intensity_huber_delta)
void ComputeOdometryResultIntensityCPU(const core::Tensor &source_depth, const core::Tensor &target_depth, const core::Tensor &source_intensity, const core::Tensor &target_intensity, const core::Tensor &target_intensity_dx, const core::Tensor &target_intensity_dy, const core::Tensor &source_vertex_map, const core::Tensor &intrinsics, const core::Tensor &init_source_to_target, core::Tensor &delta, float &inlier_residual, int &inlier_count, const float depth_outlier_trunc, const float intensity_huber_delta)
Generic file read and write utility for python interface.