11#include <Eigen/Geometry>
21 struct Trimmed final :
public ICP {
23 std::vector<icp::Vector> a_current;
26 Trimmed(
double overlap_rate):
ICP(), overlap_rate(overlap_rate) {}
27 ~Trimmed()
override {}
29 void setup()
override {
30 if (a_current.size() <
a.size()) {
31 a_current.resize(
a.size());
37 void iterate()
override {
38 const size_t n =
a.size();
39 const size_t m =
b.size();
41 for (
size_t i = 0; i < n; i++) {
46 for (
size_t i = 0; i < n; i++) {
48 matches[i].sq_dist = std::numeric_limits<double>::infinity();
49 for (
size_t j = 0; j < m; j++) {
51 double dist_ij = (
b[j] - a_current[i]).squaredNorm();
53 if (dist_ij <
matches[i].sq_dist) {
70 [](
const auto&
a,
const auto&
b) { return a.sq_dist < b.sq_dist; });
71 size_t new_n = (size_t)(overlap_rate * n);
74 std::vector<icp::Vector> trimmed_current(new_n);
75 std::vector<icp::Vector> trimmed_b(new_n);
76 for (
size_t i = 0; i < new_n; i++) {
77 trimmed_current[i] = a_current[
matches[i].point];
85 for (
size_t i = 0; i < new_n; i++) {
86 N += (trimmed_current[i] - trimmed_cm) * (trimmed_b[i] - trimmed_b_cm).transpose();
89 auto svd = N.jacobiSvd(Eigen::ComputeFullU | Eigen::ComputeFullV);
92 Matrix R = V * U.transpose();
112 if (R.determinant() < 0) {
114 std::cout <<
"Reflection" << std::endl;
115 std::cout <<
"Matrix V: " << V << std::endl;
116 std::cout <<
"Matrix U: " << U << std::endl;
117 std::cout <<
"Sing vals: " << svd.singularValues() << std::endl;
119 V = V * Eigen::DiagonalMatrix<double, 2>(1, -1);
120 R = V * U.transpose();
130 static bool static_initialization = []() {
132 [](
const ICP::Config& config) -> std::unique_ptr<ICP> {
135 double overlap_rate = config.get<
double>(
"overlap_rate", 1.0);
136 assert(overlap_rate >= 0 && overlap_rate <= 1);
137 return std::make_unique<Trimmed>(overlap_rate);
static bool register_method(std::string name, std::function< std::unique_ptr< ICP >(const Config &)> constructor)
Registers a new ICP method that can be created with constructor, returning false if name has already ...
RBTransform transform
The current point cloud transformation that is being optimized.
std::vector< Vector > a
The source point cloud relative to its centroid.
std::vector< Vector > b
The destination point cloud relative to its centroid.
std::vector< Match > matches
The pairing of each point in a to its closest in b.
Vector get_centroid(const std::vector< Vector > &points)