iterative closest points
CEV ICP algorithm library
Loading...
Searching...
No Matches
test1.cpp
Go to the documentation of this file.
1/*
2 * @author Ethan Uppal
3 * @copyright Copyright (C) 2024 Ethan Uppal. All rights reserved.
4 */
5
6#include <cassert>
7#include <cstdlib>
8#include "../icp.h"
9#include <Eigen/Core>
10#include <Eigen/SVD>
11
12/* #name Test1 */
13/* #desc This is a WIP. */
14
15namespace icp {
16 struct Test1 final : public ICP {
17 double overlap_rate;
18 std::vector<icp::Vector> a_rot;
19
20 Test1(double overlap_rate): ICP(), overlap_rate(overlap_rate) {}
21 ~Test1() override {}
22
23 void setup() override {
24 if (a_rot.size() < a.size()) {
25 a_rot.resize(a.size());
26 }
27 }
28
29 void iterate() override {
30 size_t n = a.size();
31 const size_t m = b.size();
32
33 for (size_t i = 0; i < n; i++) {
34 a_rot[i] = transform.rotation * a[i];
35 }
36
37 /* #step Matching Step: see \ref vanilla_icp
38 for details. */
39 for (size_t i = 0; i < n; i++) {
40 matches[i].point = i;
41 matches[i].sq_dist = std::numeric_limits<double>::infinity();
42 for (size_t j = 0; j < m; j++) {
43 // Point-to-point matching
44 double dist_ij = (b[j] - a_rot[i]).squaredNorm();
45
46 if (dist_ij < matches[i].sq_dist) {
47 matches[i].sq_dist = dist_ij;
48 matches[i].pair = j;
49 }
50 }
51 }
52
53 /*
54 #step Trimming Step: see \ref trimmed_icp for details.
55 */
56 std::sort(matches.begin(), matches.end(),
57 [](const auto& a, const auto& b) {
58 return a.sq_dist < b.sq_dist;
59 });
60 n = (size_t)(overlap_rate * n);
61
62 /*
63 #step
64 Transformation Step
65
66 See [this paper](icp.pdf) for information. I copied over the
67 rotation optimization from \ref vanilla_icp, and it is a TODO to
68 see if that is mathematically correct or not.
69 */
70
71 transform.translation = Vector::Zero();
72 for (size_t i = 0; i < n; i++) {
73 transform.translation += b[matches[i].pair]
74 - a_rot[matches[i].point];
75 }
77
78 // no clue why this might still work
79 // TODO: mathematically see if you can justify it, otherwise scrap
80 // and find new method
81 Matrix N{};
82 for (size_t i = 0; i < n; i++) {
83 N += (a[matches[i].point] + transform.translation)
84 * b[matches[i].pair].transpose();
85 }
86 auto svd = N.jacobiSvd(Eigen::ComputeFullU | Eigen::ComputeFullV);
87 const Matrix U = svd.matrixU();
88 const Matrix V = svd.matrixV();
89 transform.rotation = V * U.transpose();
90 }
91 };
92
93 static bool static_initialization = []() {
94 assert(ICP::register_method("test1",
95 [](const ICP::Config& config) -> std::unique_ptr<ICP> {
96 /* #conf "overlap_rate" A `double` between 0 and 1 for the
97 * overlap rate. The default is 1. */
98 double overlap_rate = config.get<double>("overlap_rate", 1.0);
99 assert(overlap_rate >= 0 && overlap_rate <= 1);
100 return std::make_unique<Test1>(overlap_rate);
101 }));
102 return true;
103 }();
104}
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 ...
Definition icp.cpp:99
RBTransform transform
The current point cloud transformation that is being optimized.
Definition icp.h:57
ICP()
Definition icp.cpp:12
std::vector< Vector > a
The source point cloud relative to its centroid.
Definition icp.h:66
std::vector< Vector > b
The destination point cloud relative to its centroid.
Definition icp.h:69
std::vector< Match > matches
The pairing of each point in a to its closest in b.
Definition icp.h:79
Definition geo.cpp:9
Eigen::Matrix2d Matrix
Definition geo.h:16
Matrix rotation
Definition geo.h:21
Vector translation
Definition geo.h:20