31 const float depth_scale,
32 const float depth_max,
33 const std::vector<OdometryConvergenceCriteria>& criteria,
41 const float depth_scale,
42 const float depth_max,
43 const std::vector<OdometryConvergenceCriteria>& criteria,
51 const float depth_scale,
52 const float depth_max,
53 const std::vector<OdometryConvergenceCriteria>& criteria,
60 const Tensor& init_source_to_target,
61 const float depth_scale,
62 const float depth_max,
63 const std::vector<OdometryConvergenceCriteria>& criteria,
82 Image source_depth_processed =
84 Image target_depth_processed =
92 source_processed, target_processed, intrinsics_d, trans_d,
93 depth_scale, depth_max, criteria,
params);
96 source_processed, target_processed, intrinsics_d, trans_d,
97 depth_scale, depth_max, criteria,
params);
100 intrinsics_d, trans_d, depth_scale,
101 depth_max, criteria,
params);
114 const float depth_scale,
115 const float depth_max,
116 const std::vector<OdometryConvergenceCriteria>& criteria,
118 int64_t n_levels = int64_t(criteria.size());
119 std::vector<Tensor> source_vertex_maps(n_levels);
120 std::vector<Tensor> target_vertex_maps(n_levels);
121 std::vector<Tensor> target_normal_maps(n_levels);
122 std::vector<Tensor> intrinsic_matrices(n_levels);
127 Tensor intrinsics_pyr = intrinsics;
130 for (int64_t i = 0; i < n_levels; ++i) {
131 Image source_vertex_map =
133 Image target_vertex_map =
136 Image target_depth_curr_smooth =
138 Image target_vertex_map_smooth =
142 source_vertex_maps[n_levels - 1 - i] = source_vertex_map.
AsTensor();
143 target_vertex_maps[n_levels - 1 - i] = target_vertex_map.
AsTensor();
144 target_normal_maps[n_levels - 1 - i] = target_normal_map.
AsTensor();
146 intrinsic_matrices[n_levels - 1 - i] = intrinsics_pyr.
Clone();
148 if (i != n_levels - 1) {
150 params.depth_outlier_trunc_ * 2, NAN);
152 params.depth_outlier_trunc_ * 2, NAN);
155 intrinsics_pyr[-1][-1] = 1;
160 for (int64_t i = 0; i < n_levels; ++i) {
161 for (
int iter = 0; iter < criteria[i].max_iteration_; ++iter) {
163 source_vertex_maps[i], target_vertex_maps[i],
164 target_normal_maps[i], intrinsic_matrices[i],
166 params.depth_huber_delta_);
168 delta_result.transformation_.Matmul(
result.transformation_);
170 iter, delta_result.inlier_rmse_,
171 delta_result.fitness_);
175 criteria[i].relative_fitness_ &&
178 criteria[i].relative_rmse_) {
182 result.inlier_rmse_ = delta_result.inlier_rmse_;
183 result.fitness_ = delta_result.fitness_;
195 const float depth_scale,
196 const float depth_max,
197 const std::vector<OdometryConvergenceCriteria>& criteria,
199 int64_t n_levels = int64_t(criteria.size());
200 std::vector<Tensor> source_intensity(n_levels);
201 std::vector<Tensor> target_intensity(n_levels);
203 std::vector<Tensor> source_depth(n_levels);
204 std::vector<Tensor> target_depth(n_levels);
205 std::vector<Tensor> target_intensity_dx(n_levels);
206 std::vector<Tensor> target_intensity_dy(n_levels);
208 std::vector<Tensor> source_vertex_maps(n_levels);
210 std::vector<Tensor> intrinsic_matrices(n_levels);
218 Tensor intrinsics_pyr = intrinsics;
221 for (int64_t i = 0; i < n_levels; ++i) {
222 source_depth[n_levels - 1 - i] = source_depth_curr.
AsTensor().
Clone();
223 target_depth[n_levels - 1 - i] = target_depth_curr.
AsTensor().
Clone();
225 source_intensity[n_levels - 1 - i] =
227 target_intensity[n_levels - 1 - i] =
230 Image source_vertex_map =
232 source_vertex_maps[n_levels - 1 - i] = source_vertex_map.
AsTensor();
234 auto target_intensity_grad = target_intensity_curr.
FilterSobel();
235 target_intensity_dx[n_levels - 1 - i] =
236 target_intensity_grad.first.AsTensor();
237 target_intensity_dy[n_levels - 1 - i] =
238 target_intensity_grad.second.AsTensor();
240 intrinsic_matrices[n_levels - 1 - i] = intrinsics_pyr.
Clone();
242 if (i != n_levels - 1) {
244 params.depth_outlier_trunc_ * 2, NAN);
246 params.depth_outlier_trunc_ * 2, NAN);
247 source_intensity_curr = source_intensity_curr.
PyrDown();
248 target_intensity_curr = target_intensity_curr.
PyrDown();
251 intrinsics_pyr[-1][-1] = 1;
257 for (int64_t i = 0; i < n_levels; ++i) {
258 for (
int iter = 0; iter < criteria[i].max_iteration_; ++iter) {
260 source_depth[i], target_depth[i], source_intensity[i],
261 target_intensity[i], target_intensity_dx[i],
262 target_intensity_dy[i], source_vertex_maps[i],
263 intrinsic_matrices[i],
result.transformation_,
264 params.depth_outlier_trunc_,
params.intensity_huber_delta_);
266 delta_result.transformation_.Matmul(
result.transformation_);
268 iter, delta_result.inlier_rmse_,
269 delta_result.fitness_);
273 criteria[i].relative_fitness_ &&
276 criteria[i].relative_rmse_) {
280 result.inlier_rmse_ = delta_result.inlier_rmse_;
281 result.fitness_ = delta_result.fitness_;
293 const float depth_scale,
294 const float depth_max,
295 const std::vector<OdometryConvergenceCriteria>& criteria,
297 int64_t n_levels = int64_t(criteria.size());
298 std::vector<Tensor> source_intensity(n_levels);
299 std::vector<Tensor> target_intensity(n_levels);
301 std::vector<Tensor> source_depth(n_levels);
302 std::vector<Tensor> target_depth(n_levels);
303 std::vector<Tensor> target_intensity_dx(n_levels);
304 std::vector<Tensor> target_intensity_dy(n_levels);
306 std::vector<Tensor> target_depth_dx(n_levels);
307 std::vector<Tensor> target_depth_dy(n_levels);
309 std::vector<Tensor> source_vertex_maps(n_levels);
311 std::vector<Tensor> intrinsic_matrices(n_levels);
319 Tensor intrinsics_pyr = intrinsics;
321 for (int64_t i = 0; i < n_levels; ++i) {
322 source_depth[n_levels - 1 - i] = source_depth_curr.
AsTensor().
Clone();
323 target_depth[n_levels - 1 - i] = target_depth_curr.
AsTensor().
Clone();
325 source_intensity[n_levels - 1 - i] =
327 target_intensity[n_levels - 1 - i] =
330 Image source_vertex_map =
332 source_vertex_maps[n_levels - 1 - i] = source_vertex_map.
AsTensor();
334 auto target_intensity_grad = target_intensity_curr.
FilterSobel();
335 target_intensity_dx[n_levels - 1 - i] =
336 target_intensity_grad.first.AsTensor();
337 target_intensity_dy[n_levels - 1 - i] =
338 target_intensity_grad.second.AsTensor();
340 auto target_depth_grad = target_depth_curr.
FilterSobel();
341 target_depth_dx[n_levels - 1 - i] = target_depth_grad.first.AsTensor();
342 target_depth_dy[n_levels - 1 - i] = target_depth_grad.second.AsTensor();
344 intrinsic_matrices[n_levels - 1 - i] = intrinsics_pyr.
Clone();
345 if (i != n_levels - 1) {
347 params.depth_outlier_trunc_ * 2, NAN);
349 params.depth_outlier_trunc_ * 2, NAN);
350 source_intensity_curr = source_intensity_curr.
PyrDown();
351 target_intensity_curr = target_intensity_curr.
PyrDown();
354 intrinsics_pyr[-1][-1] = 1;
360 for (int64_t i = 0; i < n_levels; ++i) {
361 for (
int iter = 0; iter < criteria[i].max_iteration_; ++iter) {
363 source_depth[i], target_depth[i], source_intensity[i],
364 target_intensity[i], target_depth_dx[i], target_depth_dy[i],
365 target_intensity_dx[i], target_intensity_dy[i],
366 source_vertex_maps[i], intrinsic_matrices[i],
368 params.depth_huber_delta_,
params.intensity_huber_delta_);
370 delta_result.transformation_.Matmul(
result.transformation_);
372 iter, delta_result.inlier_rmse_,
373 delta_result.fitness_);
377 criteria[i].relative_fitness_ &&
380 criteria[i].relative_rmse_) {
384 result.inlier_rmse_ = delta_result.inlier_rmse_;
385 result.fitness_ = delta_result.fitness_;
393 const Tensor& source_vertex_map,
394 const Tensor& target_vertex_map,
395 const Tensor& target_normal_map,
397 const Tensor& init_source_to_target,
398 const float depth_outlier_trunc,
399 const float depth_huber_delta) {
402 float inlier_residual;
405 source_vertex_map, target_vertex_map, target_normal_map, intrinsics,
406 init_source_to_target, se3_delta, inlier_residual, inlier_count,
407 depth_outlier_trunc, depth_huber_delta);
409 if (inlier_count <= 0) {
415 inlier_residual / inlier_count,
416 double(inlier_count) /
double(source_vertex_map.
GetShape(0) *
421 const Tensor& source_depth,
422 const Tensor& target_depth,
423 const Tensor& source_intensity,
424 const Tensor& target_intensity,
425 const Tensor& target_intensity_dx,
426 const Tensor& target_intensity_dy,
427 const Tensor& source_vertex_map,
429 const Tensor& init_source_to_target,
430 const float depth_outlier_trunc,
431 const float intensity_huber_delta) {
434 float inlier_residual;
437 source_depth, target_depth, source_intensity, target_intensity,
438 target_intensity_dx, target_intensity_dy, source_vertex_map,
439 intrinsics, init_source_to_target, se3_delta, inlier_residual,
440 inlier_count, depth_outlier_trunc, intensity_huber_delta);
442 if (inlier_count <= 0) {
448 inlier_residual / inlier_count,
449 double(inlier_count) /
double(source_vertex_map.
GetShape(0) *
454 const Tensor& target_depth,
455 const Tensor& source_intensity,
456 const Tensor& target_intensity,
457 const Tensor& target_depth_dx,
458 const Tensor& target_depth_dy,
459 const Tensor& target_intensity_dx,
460 const Tensor& target_intensity_dy,
461 const Tensor& source_vertex_map,
463 const Tensor& init_source_to_target,
464 const float depth_outlier_trunc,
465 const float depth_huber_delta,
466 const float intensity_huber_delta) {
469 float inlier_residual;
472 source_depth, target_depth, source_intensity, target_intensity,
473 target_depth_dx, target_depth_dy, target_intensity_dx,
474 target_intensity_dy, source_vertex_map, intrinsics,
475 init_source_to_target, se3_delta, inlier_residual, inlier_count,
476 depth_outlier_trunc, depth_huber_delta, intensity_huber_delta);
478 if (inlier_count <= 0) {
484 inlier_residual / inlier_count,
485 double(inlier_count) /
double(source_vertex_map.
GetShape(0) *
494 const float dist_thr,
495 const float depth_scale,
496 const float depth_max) {
499 Image source_depth_processed =
501 Image target_depth_processed =
503 Image source_vertex_map =
505 Image target_vertex_map =
510 intrinsic, source_to_target, dist_thr * dist_thr, information);
cmdLineReadable * params[]
#define AssertTensorDevice(tensor,...)
#define AssertTensorShape(tensor,...)
Tensor Clone() const
Copy Tensor to the same device.
SizeVector GetShape() const
Tensor To(Dtype dtype, bool copy=false) const
The Image class stores image with customizable rows, cols, channels, dtype and device.
Image ClipTransform(float scale, float min_value, float max_value, float clip_fill=0.0f) const
Return new image after scaling and clipping image values.
Image PyrDown() const
Return a new downsampled image with pyramid downsampling.
Image PyrDownDepth(float diff_threshold, float invalid_fill=0.f) const
Edge and invalid value preserving downsampling by 2 specifically for depth images.
Image CreateVertexMap(const core::Tensor &intrinsics, float invalid_fill=0.0f)
Create a vertex map from a depth image using unprojection.
core::Device GetDevice() const override
Get device of the image.
Image RGBToGray() const
Converts a 3-channel RGB image to a new 1-channel Grayscale image.
Image To(const core::Device &device, bool copy=false) const
Transfer the image to a specified device.
Image CreateNormalMap(float invalid_fill=0.0f)
Create a normal map from a vertex map.
std::pair< Image, Image > FilterSobel(int kernel_size=3) const
Return a pair of new gradient images (dx, dy) after Sobel filtering.
core::Tensor AsTensor() const
Returns the underlying Tensor of the Image.
Image FilterBilateral(int kernel_size=3, float value_sigma=20.0f, float distance_sigma=10.0f) const
Return a new image after bilateral filtering.
RGBDImage A pair of color and depth images.
Image depth_
The depth image.
Image color_
The color image.
__host__ __device__ int2 abs(int2 v)
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 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 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)
core::Tensor PoseToTransformation(const core::Tensor &pose)
Convert pose to the transformation matrix.
OdometryResult RGBDOdometryMultiScale(const RGBDImage &source, const RGBDImage &target, const Tensor &intrinsics, const Tensor &init_source_to_target, const float depth_scale, const float depth_max, const std::vector< OdometryConvergenceCriteria > &criteria, const Method method, const OdometryLossParams ¶ms)
Create an RGBD image pyramid given the original source and target RGBD images, and perform hierarchic...
OdometryResult RGBDOdometryMultiScalePointToPlane(const RGBDImage &source, const RGBDImage &target, const Tensor &intrinsics, const Tensor &trans, const float depth_scale, const float depth_max, const std::vector< OdometryConvergenceCriteria > &criteria, const OdometryLossParams ¶ms)
core::Tensor ComputeOdometryInformationMatrix(const geometry::Image &source_depth, const geometry::Image &target_depth, const core::Tensor &intrinsic, const core::Tensor &source_to_target, const float dist_thr, const float depth_scale, const float depth_max)
OdometryResult RGBDOdometryMultiScaleIntensity(const RGBDImage &source, const RGBDImage &target, const Tensor &intrinsic, const Tensor &trans, const float depth_scale, const float depth_max, const std::vector< OdometryConvergenceCriteria > &criteria, const OdometryLossParams ¶ms)
OdometryResult RGBDOdometryMultiScaleHybrid(const RGBDImage &source, const RGBDImage &target, const Tensor &intrinsics, const Tensor &trans, const float depth_scale, const float depth_max, const std::vector< OdometryConvergenceCriteria > &criteria, const OdometryLossParams ¶ms)
OdometryResult ComputeOdometryResultPointToPlane(const Tensor &source_vertex_map, const Tensor &target_vertex_map, const Tensor &target_normal_map, const Tensor &intrinsics, const Tensor &init_source_to_target, const float depth_outlier_trunc, const float depth_huber_delta)
Estimates the 4x4 rigid transformation T from source to target, with inlier rmse and fitness....
OdometryResult ComputeOdometryResultHybrid(const Tensor &source_depth, const Tensor &target_depth, const Tensor &source_intensity, const Tensor &target_intensity, const Tensor &target_depth_dx, const Tensor &target_depth_dy, const Tensor &target_intensity_dx, const Tensor &target_intensity_dy, const Tensor &source_vertex_map, const Tensor &intrinsics, const Tensor &init_source_to_target, const float depth_outlier_trunc, const float depth_huber_delta, const float intensity_huber_delta)
Estimates the 4x4 rigid transformation T from source to target, with inlier rmse and fitness....
OdometryResult ComputeOdometryResultIntensity(const Tensor &source_depth, const Tensor &target_depth, const Tensor &source_intensity, const Tensor &target_intensity, const Tensor &target_intensity_dx, const Tensor &target_intensity_dy, const Tensor &source_vertex_map, const Tensor &intrinsics, const Tensor &init_source_to_target, const float depth_outlier_trunc, const float intensity_huber_delta)
Estimates the 4x4 rigid transformation T from source to target, with inlier rmse and fitness....
Generic file read and write utility for python interface.