-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Expand file tree
/
Copy pathCorrespondenceChecker.cpp
More file actions
111 lines (100 loc) · 3.89 KB
/
CorrespondenceChecker.cpp
File metadata and controls
111 lines (100 loc) · 3.89 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
// ----------------------------------------------------------------------------
// - Open3D: www.open3d.org -
// ----------------------------------------------------------------------------
// Copyright (c) 2018-2024 www.open3d.org
// SPDX-License-Identifier: MIT
// ----------------------------------------------------------------------------
#include "open3d/pipelines/registration/CorrespondenceChecker.h"
#include <Eigen/Dense>
#include "open3d/geometry/PointCloud.h"
#include "open3d/utility/Logging.h"
namespace open3d {
namespace pipelines {
namespace registration {
bool CorrespondenceCheckerBasedOnEdgeLength::Check(
const geometry::PointCloud &source,
const geometry::PointCloud &target,
const CorrespondenceSet &corres,
const Eigen::Matrix4d & /*transformation*/) const {
for (size_t i = 0; i < corres.size(); i++) {
for (size_t j = i + 1; j < corres.size(); j++) {
// check edge ij
double dis_source = (source.points_[corres[i](0)] -
source.points_[corres[j](0)])
.norm();
double dis_target = (target.points_[corres[i](1)] -
target.points_[corres[j](1)])
.norm();
if (dis_source < dis_target * similarity_threshold_ ||
dis_target < dis_source * similarity_threshold_) {
return false;
}
}
}
return true;
}
bool CorrespondenceCheckerBasedOnDistance::Check(
const geometry::PointCloud &source,
const geometry::PointCloud &target,
const CorrespondenceSet &corres,
const Eigen::Matrix4d &transformation) const {
for (const auto &c : corres) {
const auto &pt = source.points_[c(0)];
Eigen::Vector3d pt_trans =
(transformation * Eigen::Vector4d(pt(0), pt(1), pt(2), 1.0))
.block<3, 1>(0, 0);
if ((target.points_[c(1)] - pt_trans).norm() > distance_threshold_) {
return false;
}
}
return true;
}
bool CorrespondenceCheckerBasedOnNormal::Check(
const geometry::PointCloud &source,
const geometry::PointCloud &target,
const CorrespondenceSet &corres,
const Eigen::Matrix4d &transformation) const {
if (!source.HasNormals() || !target.HasNormals()) {
utility::LogWarning(
"[CorrespondenceCheckerBasedOnNormal::Check] Pointcloud has no "
"normals.");
return true;
}
double cos_normal_angle_threshold = std::cos(normal_angle_threshold_);
for (const auto &c : corres) {
const auto &normal = source.normals_[c(0)];
Eigen::Vector3d normal_trans =
(transformation *
Eigen::Vector4d(normal(0), normal(1), normal(2), 0.0))
.block<3, 1>(0, 0);
if (target.normals_[c(1)].dot(normal_trans) <
cos_normal_angle_threshold) {
return false;
}
}
return true;
}
bool CorrespondenceCheckerBasedOnSourceRotation::Check(
const geometry::PointCloud &source,
const geometry::PointCloud &target,
const CorrespondenceSet &corres,
const Eigen::Matrix4d &transformation) const {
Eigen::Vector6d transform_6d =
open3d::utility::TransformMatrix4dToVector6d(transformation);
if (rotation_threshold_[0] >= 0.0 &&
std::abs(transform_6d[0]) > rotation_threshold_[0]) {
return false;
}
if (rotation_threshold_[1] >= 0.0 &&
std::abs(transform_6d[1]) > rotation_threshold_[1]) {
return false;
}
if (rotation_threshold_[2] >= 0.0 &&
std::abs(transform_6d[2]) > rotation_threshold_[2]) {
return false;
}
return true;
}
} // namespace registration
} // namespace pipelines
} // namespace open3d