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