iterative closest points
CEV ICP algorithm library
Loading...
Searching...
No Matches
trimmed.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 <Eigen/Core>
9#include <Eigen/SVD>
10#include <Eigen/Geometry>
11
12#include "icp/impl/trimmed.h"
13
14/* #name Trimmed */
15/* #register trimmed */
16
17/* #desc Trimmed ICP is identical to \ref vanilla_icp with the addition of an
18overlap rate parameter, which specifies the percentage of points between the two
19point sets that have correspondences. When the overlap rate is `1`, the algorithm
20reduces to vanilla. */
21
22namespace icp {
23
24 Trimmed::Trimmed(double overlap_rate): ICP(), overlap_rate(overlap_rate) {}
25
26 /* #conf "overlap_rate" A `double` between `0.0` and `1.0` for
27 * the overlap rate. The default is `1.0`. */
28 Trimmed::Trimmed(const Config& config)
29 : ICP(), overlap_rate(config.get<double>("overlap_rate", 0.9)) {}
30
32
34 a_current.resize(a.size());
35 b_cm = get_centroid(b);
36
37 compute_matches();
38 }
39
41 const size_t n = a.size();
42
43 for (size_t i = 0; i < n; i++) {
44 a_current[i] = transform.apply_to(a[i]);
45 }
46
47 /* #step Matching Step: see \ref vanilla_icp for details. */
48 compute_matches();
49
50 /*
51 #step
52 Trimming Step
53
54 Matches are considered in increasing order of distance.
55
56 Sources:
57 https://ieeexplore.ieee.org/abstract/document/1047997
58 */
59 std::sort(matches.begin(), matches.end(),
60 [](const auto& a, const auto& b) { return a.cost < b.cost; });
61 size_t new_n = static_cast<size_t>(overlap_rate * n);
62 new_n = std::max<size_t>(new_n, 1); // TODO: bad for scans with 0 points
63
64 // yeah, i know this is inefficient. we'll get back to it later.
65 std::vector<icp::Vector> trimmed_current(new_n);
66 std::vector<icp::Vector> trimmed_b(new_n);
67 for (size_t i = 0; i < new_n; i++) {
68 trimmed_current[i] = a_current[matches[i].point];
69 trimmed_b[i] = b[matches[i].pair];
70 }
71
72 icp::Vector trimmed_cm = get_centroid(trimmed_current);
73 icp::Vector trimmed_b_cm = get_centroid(trimmed_b);
74
75 /* #step SVD: see \ref vanilla_icp for details. */
76 Matrix N = Matrix::Zero();
77 for (size_t i = 0; i < new_n; i++) {
78 N += (trimmed_current[i] - trimmed_cm) * (trimmed_b[i] - trimmed_b_cm).transpose();
79 }
80
81 auto svd = N.jacobiSvd(Eigen::ComputeFullU | Eigen::ComputeFullV);
82 Matrix U = svd.matrixU();
83 Matrix V = svd.matrixV();
84 Matrix R = V * U.transpose();
85
86 /* #step Reflection Handling: see \ref vanilla_icp for details. */
87 if (R.determinant() < 0) {
88 V = V * Eigen::DiagonalMatrix<double, 2>(1, -1);
89 R = V * U.transpose();
90 }
91
93
94 /* #step Transformation Step: see \ref vanilla_icp for details. */
95 transform.translation += trimmed_b_cm - R * trimmed_cm;
96 }
97
98 void Trimmed::compute_matches() {
99 const size_t n = a.size();
100 const size_t m = b.size();
101
102 for (size_t i = 0; i < n; i++) {
103 matches[i].point = i;
104 matches[i].cost = std::numeric_limits<double>::infinity();
105 for (size_t j = 0; j < m; j++) {
106 // Point-to-point matching
107 double dist_ij = (b[j] - a_current[i]).squaredNorm();
108
109 if (dist_ij < matches[i].cost) {
110 matches[i].cost = dist_ij;
111 matches[i].pair = j;
112 }
113 }
114 }
115 }
116}
Configuration for ICP instances.
Definition icp.h:80
Interface for iterative closest points.
Definition icp.h:48
RBTransform transform
The current point cloud transformation that is being optimized.
Definition icp.h:58
std::vector< Vector > a
The source point cloud.
Definition icp.h:61
std::vector< Vector > b
The destination point cloud.
Definition icp.h:64
std::vector< Match > matches
The pairing of each point in a to its closest in b.
Definition icp.h:67
void setup() override
Per-method setup code.
Definition trimmed.cpp:33
Trimmed(double overlap_rate)
Definition trimmed.cpp:24
void iterate() override
Perform one iteration of ICP for the point clouds a and b provided with ICP::begin.
Definition trimmed.cpp:40
Definition driver.h:7
Eigen::Vector2d Vector
Definition geo.h:15
Eigen::Matrix2d Matrix
Definition geo.h:16
Vector get_centroid(const std::vector< Vector > &points)
Definition geo.cpp:10
Matrix rotation
Definition geo.h:21
Vector apply_to(Vector v) const
Definition geo.h:31
Vector translation
Definition geo.h:20