Open3D (C++ API)  0.20.0
Loading...
Searching...
No Matches
RegistrationImpl.h
Go to the documentation of this file.
1// ----------------------------------------------------------------------------
2// - Open3D: www.open3d.org -
3// ----------------------------------------------------------------------------
4// Copyright (c) 2018-2026 www.open3d.org
5// SPDX-License-Identifier: MIT
6// ----------------------------------------------------------------------------
7
8// Private header. Do not include in Open3d.h.
9
10#pragma once
11
12#include <cmath>
13
15#include "open3d/core/Tensor.h"
19
20#ifndef __CUDACC__
21using std::abs;
22#endif
23
24namespace open3d {
25namespace t {
26namespace pipelines {
27namespace kernel {
28
29void ComputePosePointToPlaneCPU(const core::Tensor &source_points,
30 const core::Tensor &target_points,
31 const core::Tensor &target_normals,
32 const core::Tensor &correspondence_indices,
33 core::Tensor &pose,
34 float &residual,
35 int &inlier_count,
36 const core::Dtype &dtype,
37 const core::Device &device,
38 const registration::RobustKernel &kernel);
39
40void ComputePoseSymmetricCPU(const core::Tensor &source_points,
41 const core::Tensor &target_points,
42 const core::Tensor &source_normals,
43 const core::Tensor &target_normals,
44 const core::Tensor &correspondence_indices,
45 const core::Tensor &source_mean,
46 const core::Tensor &target_mean,
47 core::Tensor &pose,
48 float &residual,
49 int &inlier_count,
50 const core::Dtype &dtype,
51 const core::Device &device,
52 const registration::RobustKernel &kernel);
53
54void ComputePoseColoredICPCPU(const core::Tensor &source_points,
55 const core::Tensor &source_colors,
56 const core::Tensor &target_points,
57 const core::Tensor &target_normals,
58 const core::Tensor &target_colors,
59 const core::Tensor &target_color_gradients,
60 const core::Tensor &correspondence_indices,
61 core::Tensor &pose,
62 float &residual,
63 int &inlier_count,
64 const core::Dtype &dtype,
65 const core::Device &device,
66 const registration::RobustKernel &kernel,
67 const double &lambda_geometric);
68
70 const core::Tensor &source_points,
71 const core::Tensor &source_dopplers,
72 const core::Tensor &source_directions,
73 const core::Tensor &target_points,
74 const core::Tensor &target_normals,
75 const core::Tensor &correspondence_indices,
76 core::Tensor &output_pose,
77 float &residual,
78 int &inlier_count,
79 const core::Dtype &dtype,
80 const core::Device &device,
81 const core::Tensor &R_S_to_V,
82 const core::Tensor &r_v_to_s_in_V,
83 const core::Tensor &w_v_in_V,
84 const core::Tensor &v_v_in_V,
85 const double period,
86 const bool reject_dynamic_outliers,
87 const double doppler_outlier_threshold,
88 const registration::RobustKernel &kernel_geometric,
89 const registration::RobustKernel &kernel_doppler,
90 const double lambda_doppler);
91
92#ifdef BUILD_CUDA_MODULE
93void ComputePosePointToPlaneCUDA(const core::Tensor &source_points,
94 const core::Tensor &target_points,
95 const core::Tensor &target_normals,
96 const core::Tensor &correspondence_indices,
97 core::Tensor &pose,
98 float &residual,
99 int &inlier_count,
100 const core::Dtype &dtype,
101 const core::Device &device,
102 const registration::RobustKernel &kernel);
103
104void ComputePoseSymmetricCUDA(const core::Tensor &source_points,
105 const core::Tensor &target_points,
106 const core::Tensor &source_normals,
107 const core::Tensor &target_normals,
108 const core::Tensor &correspondence_indices,
109 const core::Tensor &source_mean,
110 const core::Tensor &target_mean,
111 core::Tensor &pose,
112 float &residual,
113 int &inlier_count,
114 const core::Dtype &dtype,
115 const core::Device &device,
116 const registration::RobustKernel &kernel);
117
118void ComputePoseColoredICPCUDA(const core::Tensor &source_points,
119 const core::Tensor &source_colors,
120 const core::Tensor &target_points,
121 const core::Tensor &target_normals,
122 const core::Tensor &target_colors,
123 const core::Tensor &target_color_gradients,
124 const core::Tensor &correspondence_indices,
125 core::Tensor &pose,
126 float &residual,
127 int &inlier_count,
128 const core::Dtype &dtype,
129 const core::Device &device,
130 const registration::RobustKernel &kernel,
131 const double &lambda_geometric);
132
133void ComputePoseDopplerICPCUDA(
134 const core::Tensor &source_points,
135 const core::Tensor &source_dopplers,
136 const core::Tensor &source_directions,
137 const core::Tensor &target_points,
138 const core::Tensor &target_normals,
139 const core::Tensor &correspondence_indices,
140 core::Tensor &output_pose,
141 float &residual,
142 int &inlier_count,
143 const core::Dtype &dtype,
144 const core::Device &device,
145 const core::Tensor &R_S_to_V,
146 const core::Tensor &r_v_to_s_in_V,
147 const core::Tensor &w_v_in_V,
148 const core::Tensor &v_v_in_V,
149 const double period,
150 const bool reject_dynamic_outliers,
151 const double doppler_outlier_threshold,
152 const registration::RobustKernel &kernel_geometric,
153 const registration::RobustKernel &kernel_doppler,
154 const double lambda_doppler);
155#endif
156
157void ComputeRtPointToPointCPU(const core::Tensor &source_points,
158 const core::Tensor &target_points,
159 const core::Tensor &correspondence_indices,
160 core::Tensor &R,
161 core::Tensor &t,
162 int &inlier_count,
163 const core::Dtype &dtype,
164 const core::Device &device);
165
166void ComputeInformationMatrixCPU(const core::Tensor &target_points,
167 const core::Tensor &correspondence_indices,
168 core::Tensor &information_matrix,
169 const core::Dtype &dtype,
170 const core::Device &device);
171
172#ifdef BUILD_CUDA_MODULE
173void ComputeInformationMatrixCUDA(const core::Tensor &target_points,
174 const core::Tensor &correspondence_indices,
175 core::Tensor &information_matrix,
176 const core::Dtype &dtype,
177 const core::Device &device);
178#endif
179
180#ifdef BUILD_SYCL_MODULE
181void ComputePosePointToPlaneSYCL(const core::Tensor &source_points,
182 const core::Tensor &target_points,
183 const core::Tensor &target_normals,
184 const core::Tensor &correspondence_indices,
185 core::Tensor &pose,
186 float &residual,
187 int &inlier_count,
188 const core::Dtype &dtype,
189 const core::Device &device,
190 const registration::RobustKernel &kernel);
191
192void ComputePoseSymmetricSYCL(const core::Tensor &source_points,
193 const core::Tensor &target_points,
194 const core::Tensor &source_normals,
195 const core::Tensor &target_normals,
196 const core::Tensor &correspondence_indices,
197 const core::Tensor &source_mean,
198 const core::Tensor &target_mean,
199 core::Tensor &pose,
200 float &residual,
201 int &inlier_count,
202 const core::Dtype &dtype,
203 const core::Device &device,
204 const registration::RobustKernel &kernel);
205
206void ComputePoseColoredICPSYCL(const core::Tensor &source_points,
207 const core::Tensor &source_colors,
208 const core::Tensor &target_points,
209 const core::Tensor &target_normals,
210 const core::Tensor &target_colors,
211 const core::Tensor &target_color_gradients,
212 const core::Tensor &correspondence_indices,
213 core::Tensor &pose,
214 float &residual,
215 int &inlier_count,
216 const core::Dtype &dtype,
217 const core::Device &device,
218 const registration::RobustKernel &kernel,
219 const double &lambda_geometric);
220
222 const core::Tensor &source_points,
223 const core::Tensor &source_dopplers,
224 const core::Tensor &source_directions,
225 const core::Tensor &target_points,
226 const core::Tensor &target_normals,
227 const core::Tensor &correspondence_indices,
228 core::Tensor &output_pose,
229 float &residual,
230 int &inlier_count,
231 const core::Dtype &dtype,
232 const core::Device &device,
233 const core::Tensor &R_S_to_V,
234 const core::Tensor &r_v_to_s_in_V,
235 const core::Tensor &w_v_in_V,
236 const core::Tensor &v_v_in_V,
237 const double period,
238 const bool reject_dynamic_outliers,
239 const double doppler_outlier_threshold,
240 const registration::RobustKernel &kernel_geometric,
241 const registration::RobustKernel &kernel_doppler,
242 const double lambda_doppler);
243
244void ComputeInformationMatrixSYCL(const core::Tensor &target_points,
245 const core::Tensor &correspondence_indices,
246 core::Tensor &information_matrix,
247 const core::Dtype &dtype,
248 const core::Device &device);
249#endif
250
251template <typename scalar_t>
253 int64_t workload_idx,
254 const scalar_t *source_points_ptr,
255 const scalar_t *target_points_ptr,
256 const scalar_t *target_normals_ptr,
257 const int64_t *correspondence_indices,
258 scalar_t *J_ij,
259 scalar_t &r) {
260 if (correspondence_indices[workload_idx] == -1) {
261 return false;
262 }
263
264 const int64_t target_idx = 3 * correspondence_indices[workload_idx];
265 const int64_t source_idx = 3 * workload_idx;
266
267 const scalar_t &sx = source_points_ptr[source_idx + 0];
268 const scalar_t &sy = source_points_ptr[source_idx + 1];
269 const scalar_t &sz = source_points_ptr[source_idx + 2];
270 const scalar_t &tx = target_points_ptr[target_idx + 0];
271 const scalar_t &ty = target_points_ptr[target_idx + 1];
272 const scalar_t &tz = target_points_ptr[target_idx + 2];
273 const scalar_t &nx = target_normals_ptr[target_idx + 0];
274 const scalar_t &ny = target_normals_ptr[target_idx + 1];
275 const scalar_t &nz = target_normals_ptr[target_idx + 2];
276
277 r = (sx - tx) * nx + (sy - ty) * ny + (sz - tz) * nz;
278
279 J_ij[0] = nz * sy - ny * sz;
280 J_ij[1] = nx * sz - nz * sx;
281 J_ij[2] = ny * sx - nx * sy;
282 J_ij[3] = nx;
283 J_ij[4] = ny;
284 J_ij[5] = nz;
285
286 return true;
287}
288
289template bool GetJacobianPointToPlane(int64_t workload_idx,
290 const float *source_points_ptr,
291 const float *target_points_ptr,
292 const float *target_normals_ptr,
293 const int64_t *correspondence_indices,
294 float *J_ij,
295 float &r);
296
297template bool GetJacobianPointToPlane(int64_t workload_idx,
298 const double *source_points_ptr,
299 const double *target_points_ptr,
300 const double *target_normals_ptr,
301 const int64_t *correspondence_indices,
302 double *J_ij,
303 double &r);
304
323template <typename scalar_t>
325 int64_t workload_idx,
326 const scalar_t *source_points_ptr,
327 const scalar_t *target_points_ptr,
328 const scalar_t *source_normals_ptr,
329 const scalar_t *target_normals_ptr,
330 const int64_t *correspondence_indices,
331 const scalar_t *source_mean_ptr,
332 const scalar_t *target_mean_ptr,
333 scalar_t *J_ij,
334 scalar_t &centered_residual,
335 scalar_t &objective_residual) {
336 if (correspondence_indices[workload_idx] == -1) {
337 return false;
338 }
339
340 const int64_t target_idx = 3 * correspondence_indices[workload_idx];
341 const int64_t source_idx = 3 * workload_idx;
342
343 const scalar_t &sx = source_points_ptr[source_idx + 0];
344 const scalar_t &sy = source_points_ptr[source_idx + 1];
345 const scalar_t &sz = source_points_ptr[source_idx + 2];
346 const scalar_t &tx = target_points_ptr[target_idx + 0];
347 const scalar_t &ty = target_points_ptr[target_idx + 1];
348 const scalar_t &tz = target_points_ptr[target_idx + 2];
349 const scalar_t normal_dot = source_normals_ptr[source_idx + 0] *
350 target_normals_ptr[target_idx + 0] +
351 source_normals_ptr[source_idx + 1] *
352 target_normals_ptr[target_idx + 1] +
353 source_normals_ptr[source_idx + 2] *
354 target_normals_ptr[target_idx + 2];
355 const scalar_t normal_sign =
356 normal_dot < scalar_t(0) ? scalar_t(-1) : scalar_t(1);
357 const scalar_t nx = target_normals_ptr[target_idx + 0] +
358 normal_sign * source_normals_ptr[source_idx + 0];
359 const scalar_t ny = target_normals_ptr[target_idx + 1] +
360 normal_sign * source_normals_ptr[source_idx + 1];
361 const scalar_t nz = target_normals_ptr[target_idx + 2] +
362 normal_sign * source_normals_ptr[source_idx + 2];
363
364 const scalar_t sx_centered = sx - source_mean_ptr[0];
365 const scalar_t sy_centered = sy - source_mean_ptr[1];
366 const scalar_t sz_centered = sz - source_mean_ptr[2];
367 const scalar_t tx_centered = tx - target_mean_ptr[0];
368 const scalar_t ty_centered = ty - target_mean_ptr[1];
369 const scalar_t tz_centered = tz - target_mean_ptr[2];
370
371 const scalar_t sum_x = sx_centered + tx_centered;
372 const scalar_t sum_y = sy_centered + ty_centered;
373 const scalar_t sum_z = sz_centered + tz_centered;
374 J_ij[0] = sum_y * nz - sum_z * ny;
375 J_ij[1] = sum_z * nx - sum_x * nz;
376 J_ij[2] = sum_x * ny - sum_y * nx;
377 J_ij[3] = nx;
378 J_ij[4] = ny;
379 J_ij[5] = nz;
380
381 centered_residual = (sx_centered - tx_centered) * nx +
382 (sy_centered - ty_centered) * ny +
383 (sz_centered - tz_centered) * nz;
384 objective_residual = (sx - tx) * nx + (sy - ty) * ny + (sz - tz) * nz;
385
386 return true;
387}
388
389template bool GetJacobianSymmetric(int64_t workload_idx,
390 const float *source_points_ptr,
391 const float *target_points_ptr,
392 const float *source_normals_ptr,
393 const float *target_normals_ptr,
394 const int64_t *correspondence_indices,
395 const float *source_mean_ptr,
396 const float *target_mean_ptr,
397 float *J_ij,
398 float &centered_residual,
399 float &objective_residual);
400
401template bool GetJacobianSymmetric(int64_t workload_idx,
402 const double *source_points_ptr,
403 const double *target_points_ptr,
404 const double *source_normals_ptr,
405 const double *target_normals_ptr,
406 const int64_t *correspondence_indices,
407 const double *source_mean_ptr,
408 const double *target_mean_ptr,
409 double *J_ij,
410 double &centered_residual,
411 double &objective_residual);
412
413template <typename scalar_t>
415 const int64_t workload_idx,
416 const scalar_t *source_points_ptr,
417 const scalar_t *source_colors_ptr,
418 const scalar_t *target_points_ptr,
419 const scalar_t *target_normals_ptr,
420 const scalar_t *target_colors_ptr,
421 const scalar_t *target_color_gradients_ptr,
422 const int64_t *correspondence_indices,
423 const scalar_t &sqrt_lambda_geometric,
424 const scalar_t &sqrt_lambda_photometric,
425 scalar_t *J_G,
426 scalar_t *J_I,
427 scalar_t &r_G,
428 scalar_t &r_I) {
429 if (correspondence_indices[workload_idx] == -1) {
430 return false;
431 }
432
433 const int64_t target_idx = 3 * correspondence_indices[workload_idx];
434 const int64_t source_idx = 3 * workload_idx;
435
436 const scalar_t vs[3] = {source_points_ptr[source_idx],
437 source_points_ptr[source_idx + 1],
438 source_points_ptr[source_idx + 2]};
439
440 const scalar_t vt[3] = {target_points_ptr[target_idx],
441 target_points_ptr[target_idx + 1],
442 target_points_ptr[target_idx + 2]};
443
444 const scalar_t nt[3] = {target_normals_ptr[target_idx],
445 target_normals_ptr[target_idx + 1],
446 target_normals_ptr[target_idx + 2]};
447
448 const scalar_t d = (vs[0] - vt[0]) * nt[0] + (vs[1] - vt[1]) * nt[1] +
449 (vs[2] - vt[2]) * nt[2];
450
451 J_G[0] = sqrt_lambda_geometric * (-vs[2] * nt[1] + vs[1] * nt[2]);
452 J_G[1] = sqrt_lambda_geometric * (vs[2] * nt[0] - vs[0] * nt[2]);
453 J_G[2] = sqrt_lambda_geometric * (-vs[1] * nt[0] + vs[0] * nt[1]);
454 J_G[3] = sqrt_lambda_geometric * nt[0];
455 J_G[4] = sqrt_lambda_geometric * nt[1];
456 J_G[5] = sqrt_lambda_geometric * nt[2];
457 r_G = sqrt_lambda_geometric * d;
458
459 const scalar_t vs_proj[3] = {vs[0] - d * nt[0], vs[1] - d * nt[1],
460 vs[2] - d * nt[2]};
461
462 const scalar_t intensity_source =
463 (source_colors_ptr[source_idx] + source_colors_ptr[source_idx + 1] +
464 source_colors_ptr[source_idx + 2]) /
465 3.0;
466
467 const scalar_t intensity_target =
468 (target_colors_ptr[target_idx] + target_colors_ptr[target_idx + 1] +
469 target_colors_ptr[target_idx + 2]) /
470 3.0;
471
472 const scalar_t dit[3] = {target_color_gradients_ptr[target_idx],
473 target_color_gradients_ptr[target_idx + 1],
474 target_color_gradients_ptr[target_idx + 2]};
475
476 const scalar_t is_proj = dit[0] * (vs_proj[0] - vt[0]) +
477 dit[1] * (vs_proj[1] - vt[1]) +
478 dit[2] * (vs_proj[2] - vt[2]) + intensity_target;
479
480 const scalar_t s = dit[0] * nt[0] + dit[1] * nt[1] + dit[2] * nt[2];
481 const scalar_t ditM[3] = {s * nt[0] - dit[0], s * nt[1] - dit[1],
482 s * nt[2] - dit[2]};
483
484 J_I[0] = sqrt_lambda_photometric * (-vs[2] * ditM[1] + vs[1] * ditM[2]);
485 J_I[1] = sqrt_lambda_photometric * (vs[2] * ditM[0] - vs[0] * ditM[2]);
486 J_I[2] = sqrt_lambda_photometric * (-vs[1] * ditM[0] + vs[0] * ditM[1]);
487 J_I[3] = sqrt_lambda_photometric * ditM[0];
488 J_I[4] = sqrt_lambda_photometric * ditM[1];
489 J_I[5] = sqrt_lambda_photometric * ditM[2];
490 r_I = sqrt_lambda_photometric * (intensity_source - is_proj);
491
492 return true;
493}
494
495template bool GetJacobianColoredICP(const int64_t workload_idx,
496 const float *source_points_ptr,
497 const float *source_colors_ptr,
498 const float *target_points_ptr,
499 const float *target_normals_ptr,
500 const float *target_colors_ptr,
501 const float *target_color_gradients_ptr,
502 const int64_t *correspondence_indices,
503 const float &sqrt_lambda_geometric,
504 const float &sqrt_lambda_photometric,
505 float *J_G,
506 float *J_I,
507 float &r_G,
508 float &r_I);
509
510template bool GetJacobianColoredICP(const int64_t workload_idx,
511 const double *source_points_ptr,
512 const double *source_colors_ptr,
513 const double *target_points_ptr,
514 const double *target_normals_ptr,
515 const double *target_colors_ptr,
516 const double *target_color_gradients_ptr,
517 const int64_t *correspondence_indices,
518 const double &sqrt_lambda_geometric,
519 const double &sqrt_lambda_photometric,
520 double *J_G,
521 double *J_I,
522 double &r_G,
523 double &r_I);
524
525template <typename scalar_t>
527 const scalar_t *R_S_to_V,
528 const scalar_t *r_v_to_s_in_V,
529 const scalar_t *w_v_in_V,
530 const scalar_t *v_v_in_V,
531 scalar_t *v_s_in_S) {
532 // Compute v_s_in_V = v_v_in_V + w_v_in_V.cross(r_v_to_s_in_V).
533 scalar_t v_s_in_V[3] = {0};
534 core::linalg::kernel::cross_3x1(w_v_in_V, r_v_to_s_in_V, v_s_in_V);
535 v_s_in_V[0] += v_v_in_V[0];
536 v_s_in_V[1] += v_v_in_V[1];
537 v_s_in_V[2] += v_v_in_V[2];
538
539 // Compute v_s_in_S = R_S_to_V * v_s_in_V.
540 core::linalg::kernel::matmul3x3_3x1(R_S_to_V, v_s_in_V, v_s_in_S);
541}
542
543template void PreComputeForDopplerICP(const float *R_S_to_V,
544 const float *r_v_to_s_in_V,
545 const float *w_v_in_V,
546 const float *v_v_in_V,
547 float *v_s_in_S);
548
549template void PreComputeForDopplerICP(const double *R_S_to_V,
550 const double *r_v_to_s_in_V,
551 const double *w_v_in_V,
552 const double *v_v_in_V,
553 double *v_s_in_S);
554
555template <typename scalar_t>
557 const int64_t workload_idx,
558 const scalar_t *source_points_ptr,
559 const scalar_t *source_dopplers_ptr,
560 const scalar_t *source_directions_ptr,
561 const scalar_t *target_points_ptr,
562 const scalar_t *target_normals_ptr,
563 const int64_t *correspondence_indices,
564 const scalar_t *R_S_to_V,
565 const scalar_t *r_v_to_s_in_V,
566 const scalar_t *v_s_in_S,
567 const bool reject_dynamic_outliers,
568 const scalar_t doppler_outlier_threshold,
569 const scalar_t &sqrt_lambda_geometric,
570 const scalar_t &sqrt_lambda_doppler,
571 const scalar_t &sqrt_lambda_doppler_by_dt,
572 scalar_t *J_G,
573 scalar_t *J_D,
574 scalar_t &r_G,
575 scalar_t &r_D) {
576 if (correspondence_indices[workload_idx] == -1) {
577 return false;
578 }
579
580 const int64_t target_idx = 3 * correspondence_indices[workload_idx];
581 const int64_t source_idx = 3 * workload_idx;
582
583 const scalar_t &doppler_in_S = source_dopplers_ptr[workload_idx];
584
585 const scalar_t ds_in_V[3] = {source_directions_ptr[source_idx],
586 source_directions_ptr[source_idx + 1],
587 source_directions_ptr[source_idx + 2]};
588
589 // Compute predicted Doppler velocity (in sensor frame).
590 scalar_t ds_in_S[3] = {0};
591 core::linalg::kernel::matmul3x3_3x1(R_S_to_V, ds_in_V, ds_in_S);
592 const scalar_t doppler_pred_in_S =
593 -core::linalg::kernel::dot_3x1(ds_in_S, v_s_in_S);
594
595 // Compute Doppler error.
596 const double doppler_error = doppler_in_S - doppler_pred_in_S;
597
598 // Dynamic point outlier rejection.
599 if (reject_dynamic_outliers &&
600 abs(doppler_error) > doppler_outlier_threshold) {
601 // Jacobian and residual are set to 0 by default.
602 return true;
603 }
604
605 // Compute Doppler residual and Jacobian.
606 scalar_t J_D_w[3] = {0};
607 core::linalg::kernel::cross_3x1(ds_in_V, r_v_to_s_in_V, J_D_w);
608 J_D[0] = sqrt_lambda_doppler_by_dt * J_D_w[0];
609 J_D[1] = sqrt_lambda_doppler_by_dt * J_D_w[1];
610 J_D[2] = sqrt_lambda_doppler_by_dt * J_D_w[2];
611 J_D[3] = sqrt_lambda_doppler_by_dt * -ds_in_V[0];
612 J_D[4] = sqrt_lambda_doppler_by_dt * -ds_in_V[1];
613 J_D[5] = sqrt_lambda_doppler_by_dt * -ds_in_V[2];
614 r_D = sqrt_lambda_doppler * doppler_error;
615
616 const scalar_t ps[3] = {source_points_ptr[source_idx],
617 source_points_ptr[source_idx + 1],
618 source_points_ptr[source_idx + 2]};
619
620 const scalar_t pt[3] = {target_points_ptr[target_idx],
621 target_points_ptr[target_idx + 1],
622 target_points_ptr[target_idx + 2]};
623
624 const scalar_t nt[3] = {target_normals_ptr[target_idx],
625 target_normals_ptr[target_idx + 1],
626 target_normals_ptr[target_idx + 2]};
627
628 // Compute geometric point-to-plane error.
629 const scalar_t p2p_error = (ps[0] - pt[0]) * nt[0] +
630 (ps[1] - pt[1]) * nt[1] +
631 (ps[2] - pt[2]) * nt[2];
632
633 // Compute geometric point-to-plane residual and Jacobian.
634 J_G[0] = sqrt_lambda_geometric * (-ps[2] * nt[1] + ps[1] * nt[2]);
635 J_G[1] = sqrt_lambda_geometric * (ps[2] * nt[0] - ps[0] * nt[2]);
636 J_G[2] = sqrt_lambda_geometric * (-ps[1] * nt[0] + ps[0] * nt[1]);
637 J_G[3] = sqrt_lambda_geometric * nt[0];
638 J_G[4] = sqrt_lambda_geometric * nt[1];
639 J_G[5] = sqrt_lambda_geometric * nt[2];
640 r_G = sqrt_lambda_geometric * p2p_error;
641
642 return true;
643}
644
645template bool GetJacobianDopplerICP(const int64_t workload_idx,
646 const float *source_points_ptr,
647 const float *source_dopplers_ptr,
648 const float *source_directions_ptr,
649 const float *target_points_ptr,
650 const float *target_normals_ptr,
651 const int64_t *correspondence_indices,
652 const float *R_S_to_V,
653 const float *r_v_to_s_in_V,
654 const float *v_s_in_S,
655 const bool reject_dynamic_outliers,
656 const float doppler_outlier_threshold,
657 const float &sqrt_lambda_geometric,
658 const float &sqrt_lambda_doppler,
659 const float &sqrt_lambda_doppler_by_dt,
660 float *J_G,
661 float *J_D,
662 float &r_G,
663 float &r_D);
664
665template bool GetJacobianDopplerICP(const int64_t workload_idx,
666 const double *source_points_ptr,
667 const double *source_dopplers_ptr,
668 const double *source_directions_ptr,
669 const double *target_points_ptr,
670 const double *target_normals_ptr,
671 const int64_t *correspondence_indices,
672 const double *R_S_to_V,
673 const double *r_v_to_s_in_V,
674 const double *v_s_in_S,
675 const bool reject_dynamic_outliers,
676 const double doppler_outlier_threshold,
677 const double &sqrt_lambda_geometric,
678 const double &sqrt_lambda_doppler,
679 const double &sqrt_lambda_doppler_by_dt,
680 double *J_G,
681 double *J_D,
682 double &r_G,
683 double &r_D);
684
685template <typename scalar_t>
687 int64_t workload_idx,
688 const scalar_t *target_points_ptr,
689 const int64_t *correspondence_indices,
690 scalar_t *jacobian_x,
691 scalar_t *jacobian_y,
692 scalar_t *jacobian_z) {
693 if (correspondence_indices[workload_idx] == -1) {
694 return false;
695 }
696
697 const int64_t target_idx = 3 * correspondence_indices[workload_idx];
698
699 jacobian_x[0] = jacobian_x[4] = jacobian_x[5] = 0.0;
700 jacobian_x[1] = target_points_ptr[target_idx + 2];
701 jacobian_x[2] = -target_points_ptr[target_idx + 1];
702 jacobian_x[3] = 1.0;
703
704 jacobian_y[1] = jacobian_y[3] = jacobian_y[5] = 0.0;
705 jacobian_y[0] = -target_points_ptr[target_idx + 2];
706 jacobian_y[2] = target_points_ptr[target_idx];
707 jacobian_y[4] = 1.0;
708
709 jacobian_z[2] = jacobian_z[3] = jacobian_z[4] = 0.0;
710 jacobian_z[0] = target_points_ptr[target_idx + 1];
711 jacobian_z[1] = -target_points_ptr[target_idx];
712 jacobian_z[5] = 1.0;
713
714 return true;
715}
716
717template bool GetInformationJacobians(int64_t workload_idx,
718 const float *target_points_ptr,
719 const int64_t *correspondence_indices,
720 float *jacobian_x,
721 float *jacobian_y,
722 float *jacobian_z);
723
724template bool GetInformationJacobians(int64_t workload_idx,
725 const double *target_points_ptr,
726 const int64_t *correspondence_indices,
727 double *jacobian_x,
728 double *jacobian_y,
729 double *jacobian_z);
730
731} // namespace kernel
732} // namespace pipelines
733} // namespace t
734} // namespace open3d
Common CUDA utilities.
#define OPEN3D_HOST_DEVICE
Definition CUDAUtils.h:43
double t
Definition SurfaceReconstructionPoisson.cpp:175
OPEN3D_HOST_DEVICE OPEN3D_FORCE_INLINE void cross_3x1(const scalar_t *A_3x1_input, const scalar_t *B_3x1_input, scalar_t *C_3x1_output)
Definition Matrix.h:63
OPEN3D_HOST_DEVICE OPEN3D_FORCE_INLINE scalar_t dot_3x1(const scalar_t *A_3x1_input, const scalar_t *B_3x1_input)
Definition Matrix.h:89
OPEN3D_HOST_DEVICE bool GetJacobianPointToPlane(int64_t workload_idx, const scalar_t *source_points_ptr, const scalar_t *target_points_ptr, const scalar_t *target_normals_ptr, const int64_t *correspondence_indices, scalar_t *J_ij, scalar_t &r)
Definition RegistrationImpl.h:252
void ComputeInformationMatrixCPU(const core::Tensor &target_points, const core::Tensor &correspondence_indices, core::Tensor &information_matrix, const core::Dtype &dtype, const core::Device &device)
Definition RegistrationCPU.cpp:703
OPEN3D_HOST_DEVICE bool GetJacobianDopplerICP(const int64_t workload_idx, const scalar_t *source_points_ptr, const scalar_t *source_dopplers_ptr, const scalar_t *source_directions_ptr, const scalar_t *target_points_ptr, const scalar_t *target_normals_ptr, const int64_t *correspondence_indices, const scalar_t *R_S_to_V, const scalar_t *r_v_to_s_in_V, const scalar_t *v_s_in_S, const bool reject_dynamic_outliers, const scalar_t doppler_outlier_threshold, const scalar_t &sqrt_lambda_geometric, const scalar_t &sqrt_lambda_doppler, const scalar_t &sqrt_lambda_doppler_by_dt, scalar_t *J_G, scalar_t *J_D, scalar_t &r_G, scalar_t &r_D)
Definition RegistrationImpl.h:556
void ComputeRtPointToPointCPU(const core::Tensor &source_points, const core::Tensor &target_points, const core::Tensor &corres, core::Tensor &R, core::Tensor &t, int &inlier_count, const core::Dtype &dtype, const core::Device &device)
Definition RegistrationCPU.cpp:619
void ComputePoseDopplerICPCPU(const core::Tensor &source_points, const core::Tensor &source_dopplers, const core::Tensor &source_directions, const core::Tensor &target_points, const core::Tensor &target_normals, const core::Tensor &correspondence_indices, core::Tensor &output_pose, float &residual, int &inlier_count, const core::Dtype &dtype, const core::Device &device, const core::Tensor &R_S_to_V, const core::Tensor &r_v_to_s_in_V, const core::Tensor &w_v_in_V, const core::Tensor &v_v_in_V, const double period, const bool reject_dynamic_outliers, const double doppler_outlier_threshold, const registration::RobustKernel &kernel_geometric, const registration::RobustKernel &kernel_doppler, const double lambda_doppler)
Definition RegistrationCPU.cpp:426
void ComputePoseColoredICPSYCL(const core::Tensor &source_points, const core::Tensor &source_colors, const core::Tensor &target_points, const core::Tensor &target_normals, const core::Tensor &target_colors, const core::Tensor &target_color_gradients, const core::Tensor &correspondence_indices, core::Tensor &pose, float &residual, int &inlier_count, const core::Dtype &dtype, const core::Device &device, const registration::RobustKernel &kernel, const double &lambda_geometric)
Definition RegistrationSYCL.cpp:184
void ComputePosePointToPlaneCPU(const core::Tensor &source_points, const core::Tensor &target_points, const core::Tensor &target_normals, const core::Tensor &correspondence_indices, core::Tensor &pose, float &residual, int &inlier_count, const core::Dtype &dtype, const core::Device &device, const registration::RobustKernel &kernel)
Definition RegistrationCPU.cpp:92
void ComputePoseSymmetricCPU(const core::Tensor &source_points, const core::Tensor &target_points, const core::Tensor &source_normals, const core::Tensor &target_normals, const core::Tensor &correspondence_indices, const core::Tensor &source_mean, const core::Tensor &target_mean, core::Tensor &pose, float &residual, int &inlier_count, const core::Dtype &dtype, const core::Device &device, const registration::RobustKernel &kernel)
Definition RegistrationCPU.cpp:182
void ComputeInformationMatrixSYCL(const core::Tensor &target_points, const core::Tensor &correspondence_indices, core::Tensor &information_matrix, const core::Dtype &dtype, const core::Device &device)
Definition RegistrationSYCL.cpp:406
OPEN3D_HOST_DEVICE bool GetJacobianSymmetric(int64_t workload_idx, const scalar_t *source_points_ptr, const scalar_t *target_points_ptr, const scalar_t *source_normals_ptr, const scalar_t *target_normals_ptr, const int64_t *correspondence_indices, const scalar_t *source_mean_ptr, const scalar_t *target_mean_ptr, scalar_t *J_ij, scalar_t &centered_residual, scalar_t &objective_residual)
Computes Jacobian and residuals for symmetric ICP.
Definition RegistrationImpl.h:324
void ComputePoseColoredICPCPU(const core::Tensor &source_points, const core::Tensor &source_colors, const core::Tensor &target_points, const core::Tensor &target_normals, const core::Tensor &target_colors, const core::Tensor &target_color_gradients, const core::Tensor &correspondence_indices, core::Tensor &pose, float &residual, int &inlier_count, const core::Dtype &dtype, const core::Device &device, const registration::RobustKernel &kernel, const double &lambda_geometric)
Definition RegistrationCPU.cpp:292
void ComputePosePointToPlaneSYCL(const core::Tensor &source_points, const core::Tensor &target_points, const core::Tensor &target_normals, const core::Tensor &correspondence_indices, core::Tensor &pose, float &residual, int &inlier_count, const core::Dtype &dtype, const core::Device &device, const registration::RobustKernel &kernel)
Definition RegistrationSYCL.cpp:31
OPEN3D_HOST_DEVICE bool GetJacobianColoredICP(const int64_t workload_idx, const scalar_t *source_points_ptr, const scalar_t *source_colors_ptr, const scalar_t *target_points_ptr, const scalar_t *target_normals_ptr, const scalar_t *target_colors_ptr, const scalar_t *target_color_gradients_ptr, const int64_t *correspondence_indices, const scalar_t &sqrt_lambda_geometric, const scalar_t &sqrt_lambda_photometric, scalar_t *J_G, scalar_t *J_I, scalar_t &r_G, scalar_t &r_I)
Definition RegistrationImpl.h:414
OPEN3D_HOST_DEVICE void PreComputeForDopplerICP(const scalar_t *R_S_to_V, const scalar_t *r_v_to_s_in_V, const scalar_t *w_v_in_V, const scalar_t *v_v_in_V, scalar_t *v_s_in_S)
Definition RegistrationImpl.h:526
void ComputePoseDopplerICPSYCL(const core::Tensor &source_points, const core::Tensor &source_dopplers, const core::Tensor &source_directions, const core::Tensor &target_points, const core::Tensor &target_normals, const core::Tensor &correspondence_indices, core::Tensor &output_pose, float &residual, int &inlier_count, const core::Dtype &dtype, const core::Device &device, const core::Tensor &R_S_to_V, const core::Tensor &r_v_to_s_in_V, const core::Tensor &w_v_in_V, const core::Tensor &v_v_in_V, const double period, const bool reject_dynamic_outliers, const double doppler_outlier_threshold, const registration::RobustKernel &kernel_geometric, const registration::RobustKernel &kernel_doppler, const double lambda_doppler)
Definition RegistrationSYCL.cpp:277
void ComputePoseSymmetricSYCL(const core::Tensor &source_points, const core::Tensor &target_points, const core::Tensor &source_normals, const core::Tensor &target_normals, const core::Tensor &correspondence_indices, const core::Tensor &source_mean, const core::Tensor &target_mean, core::Tensor &pose, float &residual, int &inlier_count, const core::Dtype &dtype, const core::Device &device, const registration::RobustKernel &kernel)
Definition RegistrationSYCL.cpp:100
OPEN3D_HOST_DEVICE bool GetInformationJacobians(int64_t workload_idx, const scalar_t *target_points_ptr, const int64_t *correspondence_indices, scalar_t *jacobian_x, scalar_t *jacobian_y, scalar_t *jacobian_z)
Definition RegistrationImpl.h:686
Definition PinholeCameraIntrinsic.cpp:16