39 const size_t N = in_correspondences.size();
44 Eigen::Matrix<double,7,1> th;
47 th[2] =
params.ransac_threshold_lin;
50 th[5] =
params.ransac_threshold_ang;
51 th[6] =
params.ransac_threshold_scale;
56 double min_err = std::numeric_limits<double>::max();
60 const size_t n =
params.ransac_minSetSize;
62 const size_t max_it =
params.ransac_nmaxSimulations;
64 ASSERTMSG_(d>=
n,
"Minimum number of points to be considered a good set is < Minimum number of points to fit the model")
69 for(
size_t iterations = 0; iterations < max_it; iterations++ )
80 mbInliers.reserve(
n );
81 for(
size_t i = 0; mbInliers.size()<
n && i<N; i++ )
83 const size_t idx = mbSet[i];
86 if (
params.user_individual_compat_callback)
89 pm.
idx_this = in_correspondences[ idx ].this_idx;
90 pm.
idx_other = in_correspondences[ idx ].other_idx;
91 if (! (*
params.user_individual_compat_callback)(pm,
params.user_individual_compat_callback_userdata))
95 mbInliers.push_back( in_correspondences[ idx ] );
96 cSet.push_back( idx );
103 std::cerr <<
"[tfest::se3_l2_robust] Iter " << iterations <<
": It was not possible to find the min no of (compatible) matching pairs.\n";
109 if (!
res) { std::cerr <<
"[tfest::se3_l2_robust] tfest::se3_l2() returned false for tentative subset during RANSAC iteration!\n";
continue; }
114 mbOut_vec[0] = mbOut.
x();
115 mbOut_vec[1] = mbOut.
y();
116 mbOut_vec[2] = mbOut.z();
118 mbOut_vec[3] = mbOut.
yaw();
119 mbOut_vec[4] = mbOut.
pitch();
120 mbOut_vec[5] = mbOut.
roll();
122 mbOut_vec[6] =
scale;
125 for(
size_t k =
n; k < N; k++ )
127 const size_t idx = mbSet[k];
130 if (
params.user_individual_compat_callback)
133 pm.
idx_this = in_correspondences[ idx ].this_idx;
134 pm.
idx_other = in_correspondences[ idx ].other_idx;
135 if (! (*
params.user_individual_compat_callback)(pm,
params.user_individual_compat_callback_userdata))
141 mbInliers.push_back( in_correspondences[ idx ] );
143 mbInliers.erase( mbInliers.end()-1 );
145 if (!
res) { std::cerr <<
"[tfest::se3_l2_robust] tfest::se3_l2() returned false for tentative subset during RANSAC iteration!\n";
continue; }
150 if( fabs( mbOut_vec[0] - csOut.
x() ) < th[0] && fabs( mbOut_vec[1] - csOut.
y() ) < th[1] &&
151 fabs( mbOut_vec[2] - csOut.z() ) < th[2] && fabs( mbOut_vec[3] - csOut.
yaw() ) < th[3] &&
152 fabs( mbOut_vec[4] - csOut.
pitch() ) < th[4] && fabs( mbOut_vec[5] - csOut.
roll() ) < th[5] &&
153 fabs( mbOut_vec[6] -
scale ) < th[6] )
156 cSet.push_back( idx );
165 if( cSet.size() >= d )
169 cSetInliers.resize( cSet.size() );
170 for(
unsigned int m = 0; m < cSet.size(); m++ )
171 cSetInliers[m] = in_correspondences[ cSet[m] ];
176 ASSERTMSG_(
res,
"tfest::se3_l2() returned false for tentative subset during RANSAC iteration!")
180 const double err = std::sqrt(
square( mbOut_vec[0] - cIOut.
x() ) +
square( mbOut_vec[1] - cIOut.
y() ) +
square( mbOut_vec[2] - cIOut.z() ) +
185 if( err < min_err && cSet.size() >= max_size )
188 max_size = cSet.size();
203 std::cerr <<
"[se3_l2_robust] maximum size is == 0!\n";
Column vector, like Eigen::MatrixX*, but automatically initialized to zeros since construction.
A class used to store a 3D pose (a 3D translation + a rotation in 3D).
double pitch() const
Get the PITCH angle (in radians)
double roll() const
Get the ROLL angle (in radians)
double yaw() const
Get the YAW angle (in radians)
A class used to store a 3D pose as a translation (x,y,z) and a quaternion (qr,qx,qy,...
double x() const
Common members of all points & poses classes.
void permuteVector(const VEC &in_vector, VEC &out_result)
Returns a random permutation of a vector: all the elements of the input vector are in the output but ...
GLenum GLenum GLenum GLenum GLenum scale
GLenum const GLfloat * params
void linspace(T first, T last, size_t count, VECTOR &out_vector)
Generates an equidistant sequence of numbers given the first one, the last one and the desired number...
int round(const T value)
Returns the closer integer (int) to x.
std::vector< int32_t > vector_int
bool TFEST_IMPEXP se3_l2(const mrpt::utils::TMatchingPairList &in_correspondences, mrpt::poses::CPose3DQuat &out_transform, double &out_scale, bool forceScaleToUnity=false)
Least-squares (L2 norm) solution to finding the optimal SE(3) transform between two reference frames ...
bool TFEST_IMPEXP se3_l2_robust(const mrpt::utils::TMatchingPairList &in_correspondences, const TSE3RobustParams &in_params, TSE3RobustResult &out_results)
Least-squares (L2 norm) solution to finding the optimal SE(3) transform between two reference frames ...
#define ASSERTMSG_(f, __ERROR_MSG)
This base provides a set of functions for maths stuff.
T square(const T x)
Inline function for the square of a number.
Classes for 2D/3D geometry representation, both of single values and probability density distribution...
A namespace of pseudo-random numbers genrators of diferent distributions.
BASE_IMPEXP CRandomGenerator randomGenerator
A static instance of a CRandomGenerator class, for use in single-thread applications.
Functions for estimating the optimal transformation between two frames of references given measuremen...
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values,...
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
For each individual-compatibility (IC) test, the indices of the candidate match between elements in b...
Parameters for se3_l2_robust().
Output placeholder for se3_l2_robust()
mrpt::vector_int inliers_idx
Indexes within the in_correspondences list which corresponds with inliers.
mrpt::poses::CPose3DQuat transformation
The best transformation found.
double scale
The estimated scale of the rigid transformation (should be very close to 1.0)