FitKnownRectangleRotationMaxPoints.h
Go to the documentation of this file.
1#pragma once
2
3#include <Eigen/Geometry>
4
5#include <pcl/common/transforms.h>
6#include <pcl/point_cloud.h>
7#include <pcl/point_types.h>
8
9namespace Eigen
10{
11 using Hyperplane3f = Hyperplane<float, 3>;
12}
13
14namespace visionx
15{
16
17 /**
18 * @brief Finds the rotation of a rectangle of known size at a given position
19 * that contains the most points from a point cloud.
20 */
22 {
23 public:
24 using PointT = pcl::PointXYZRGBA;
25
26
27 public:
29
30
31 // Input
32
33 /// Set the rectangle size.
34 void setRectangleSize(const Eigen::Vector2f& value);
35 Eigen::Vector2f getRectangleSize() const;
36
37 /// Set the number of solution steps, i.e. the resolution of the solution space.
38 void setNumSteps(const size_t& value);
39 size_t getNumSteps() const;
40
41
42 /**
43 * @brief Set the input cloud and the rectangle's position and normal.
44 * @param cloud The input cloud.
45 * @param normal The rectangle normal.
46 * @param center The rectangle center.
47 */
48 void setInputCloud(const pcl::PointCloud<PointT>& cloud,
49 Eigen::Vector3f normal,
50 Eigen::Vector3f center);
51
52
53 // Run
54
55 /**
56 * @brief Count the number of inliers per rotation step, and return
57 * the global pose corresponding to the rotation angle with the highest
58 * number of inliers.
59 *
60 * The best rotation angle can be retrieved via `getAngle()`.
61 * The number of inliers per step retrieved via `getInlierCounts()`.
62 *
63 * @return The global pose of the fitted rectangle.
64 */
65 Eigen::Matrix4f fit();
66 /// @see `setInputCloud()`, `fit()`
67 Eigen::Matrix4f
68 fit(const pcl::PointCloud<PointT>& cloud, Eigen::Vector3f normal, Eigen::Vector3f center);
69
70
71 /// Count the inliers for a given local rotation angle.
72 size_t countInliersOfAngle(float angle) const;
73 /// Get the inliers for a given local rotation angle.
74 pcl::PointIndicesPtr findInliersOfAngle(float angle) const;
75
76
77 // Results
78
79 /// Get the best local rotation angle.
80 float getBestAngle() const;
81
82 /// Get the best local rotation angle.
83 size_t
85 {
86 return inlierCounts.at(bestStep);
87 }
88
89 /// Get the inliers of the best local rotation angle.
90 pcl::PointIndicesPtr
91 getInliers() const
92 {
94 }
95
96 /// Get the inlier counts per step.
97 std::vector<size_t> getInlierCounts() const;
98
99 // Helpers
100
101 /// Get the local rotation angle of a solution step.
102 template <typename Int>
103 float
104 stepToAngle(Int step) const
105 {
106 return (step / float(numSteps)) * maxAngle;
107 }
108
109 /// Get the global pose corresponding to a local rotation angle.
110 Eigen::Matrix4f angleToPose(float angle);
111
112
113 private:
114 /// Initialize `aligned` and `alignedTransform`.
115 void initAlignedPointCloud(const pcl::PointCloud<PointT>& cloud,
116 Eigen::Vector3f normal,
117 Eigen::Vector3f center);
118 pcl::PointCloud<PointT>::ConstPtr getAlignedPointCloud() const;
119
120 /// Set `rotated` by rotating `aligned` by the given angle.
121 void setRotated(float angle) const;
122 /// Checks whether a rotated point is an inlier.
123 bool isInlier(const PointT& p) const;
124
125
126 public:
127 // Settings.
128
129 /// The rectangle size.
130 Eigen::Vector2f rectangleSize = Eigen::Vector2f::Ones();
131
132 /// The number of steps (i.e. resolution of solution space).
133 size_t numSteps = 180;
134 const float maxAngle = float(M_PI); // Need to cover 180 degrees.
135
136
137 // Runtime.
138
139 /// Transformed so center is at 0 and z = normal.
140 pcl::PointCloud<pcl::PointXYZRGBA>::Ptr aligned{new pcl::PointCloud<pcl::PointXYZRGBA>};
141 /// Transformation applied to get `aligned`.
142 Eigen::Matrix4f alignedTransform = Eigen::Matrix4f::Identity();
143
144 /// Buffer for point clouds rotated for inlier counting.
145 mutable pcl::PointCloud<pcl::PointXYZRGBA>::Ptr rotated{
146 new pcl::PointCloud<pcl::PointXYZRGBA>};
147
148
149 // Results
150
151 size_t bestStep = 0;
152 /// The best angle.
153 float bestAngle = 0;
154 /// The inlier counts per step.
155 std::vector<size_t> inlierCounts;
156 };
157
158} // namespace visionx
#define float
Definition 16_Level.h:22
#define M_PI
Definition MathTools.h:17
pcl::PointCloud< pcl::PointXYZRGBA >::Ptr aligned
Transformed so center is at 0 and z = normal.
std::vector< size_t > inlierCounts
The inlier counts per step.
void setInputCloud(const pcl::PointCloud< PointT > &cloud, Eigen::Vector3f normal, Eigen::Vector3f center)
Set the input cloud and the rectangle's position and normal.
Eigen::Matrix4f fit(const pcl::PointCloud< PointT > &cloud, Eigen::Vector3f normal, Eigen::Vector3f center)
std::vector< size_t > getInlierCounts() const
Get the inlier counts per step.
float getBestAngle() const
Get the best local rotation angle.
pcl::PointIndicesPtr findInliersOfAngle(float angle) const
Get the inliers for a given local rotation angle.
float stepToAngle(Int step) const
Get the local rotation angle of a solution step.
Eigen::Matrix4f alignedTransform
Transformation applied to get aligned.
size_t getNumInliers() const
Get the best local rotation angle.
void setNumSteps(const size_t &value)
Set the number of solution steps, i.e. the resolution of the solution space.
Eigen::Matrix4f angleToPose(float angle)
Get the global pose corresponding to a local rotation angle.
pcl::PointCloud< pcl::PointXYZRGBA >::Ptr rotated
Buffer for point clouds rotated for inlier counting.
size_t numSteps
The number of steps (i.e. resolution of solution space).
size_t countInliersOfAngle(float angle) const
Count the inliers for a given local rotation angle.
Eigen::Matrix4f fit()
Count the number of inliers per rotation step, and return the global pose corresponding to the rotati...
pcl::PointIndicesPtr getInliers() const
Get the inliers of the best local rotation angle.
void setRectangleSize(const Eigen::Vector2f &value)
Set the rectangle size.
Hyperplane< float, 3 > Hyperplane3f
Definition Elements.h:34
ArmarX headers.
double angle(const Point &a, const Point &b, const Point &c)
Definition point.hpp:109