TEASER-plusplus: [QUESTION] the program is running so slow!!!!
I have read the docs and papers but I still don’t know why the program is running so slow
This is my changed code, the S,T point cloud is processed by myself, the size is 10240
`
// An example showing TEASER++ registration with the Stanford bunny model
#include <chrono>
#include <iostream>
#include <random>
#include <Eigen/Core>
#include <teaser/ply_io.h> #include <teaser/registration.h>
// Macro constants for generating noise and outliers #define NOISE_BOUND 0.05 #define N_OUTLIERS 1700 #define OUTLIER_TRANSLATION_LB 5 #define OUTLIER_TRANSLATION_UB 10
inline double getAngularError(Eigen::Matrix3d R_exp, Eigen::Matrix3d R_est) { return std::abs(std::acos(fmin(fmax(((R_exp.transpose() * R_est).trace() - 1) / 2, -1.0), 1.0))); }
void addNoiseAndOutliers(Eigen::Matrix<double, 3, Eigen::Dynamic>& tgt) { // Add uniform noise Eigen::Matrix<double, 3, Eigen::Dynamic> noise = Eigen::Matrix<double, 3, Eigen::Dynamic>::Random(3, tgt.cols()) * NOISE_BOUND; NOISE_BOUND / 2; tgt = tgt + noise;
// Add outliers std::random_device rd; std::mt19937 gen(rd()); std::uniform_int_distribution<> dis2(0, tgt.cols() - 1); // pos of outliers std::uniform_int_distribution<> dis3(OUTLIER_TRANSLATION_LB, OUTLIER_TRANSLATION_UB); // random translation std::vector<bool> expected_outlier_mask(tgt.cols(), false); for (int i = 0; i < N_OUTLIERS; ++i) { int c_outlier_idx = dis2(gen); assert(c_outlier_idx < expected_outlier_mask.size()); expected_outlier_mask[c_outlier_idx] = true; tgt.col(c_outlier_idx).array() += dis3(gen); // random translation } }
int main() { // Load the .ply file teaser::PLYReader reader; teaser::PointCloud src_cloud; auto status = reader.read(“./example_data/left_face_10240.ply”, src_cloud); int N = src_cloud.size();
// Convert the point cloud to Eigen Eigen::Matrix<double, 3, Eigen::Dynamic> src(3, N); for (size_t i = 0; i < N; ++i) { src.col(i) << src_cloud[i].x, src_cloud[i].y, src_cloud[i].z; }
// Homogeneous coordinates Eigen::Matrix<double, 4, Eigen::Dynamic> src_h; src_h.resize(4, src.cols()); src_h.topRows(3) = src; src_h.bottomRows(1) = Eigen::Matrix<double, 1, Eigen::Dynamic>::Ones(N);
// Apply an arbitrary SE(3) transformation Eigen::Matrix4d T; // clang-format off T << 9.96926560e-01, 6.68735757e-02, -4.06664421e-02, -1.15576939e-01, -6.61289946e-02, 9.97617877e-01, 1.94008687e-02, -3.87705398e-02, 4.18675510e-02, -1.66517807e-02, 9.98977765e-01, 1.14874890e-01, 0, 0, 0, 1; // clang-format on
// Apply transformation /*Eigen::Matrix<double, 4, Eigen::Dynamic> tgt_h = T * src_h; Eigen::Matrix<double, 3, Eigen::Dynamic> tgt = tgt_h.topRows(3);
// Add some noise & outliers addNoiseAndOutliers(tgt);*/
//add code by dsy //teaser::PLYReader reader; teaser::PointCloud tgt_cloud; auto status1 = reader.read(“./example_data/right_face_10240.ply”, tgt_cloud); int M = tgt_cloud.size(); Eigen::Matrix<double, 3, Eigen::Dynamic> tgt(3, M); for (size_t i = 0; i < M; ++i) { tgt.col(i) << tgt_cloud[i].x, tgt_cloud[i].y, tgt_cloud[i].z; }
Eigen::Matrix<double, 4, Eigen::Dynamic> tgt_h; tgt_h.resize(4, tgt.cols()); tgt_h.topRows(3) = tgt; tgt_h.bottomRows(1) = Eigen::Matrix<double, 1, Eigen::Dynamic>::Ones(N);
tgt_h = T * tgt_h; tgt = tgt_h.topRows(3); std::cout << “Run TEASER++ registration” << std::endl; // Run TEASER++ registration // Prepare solver parameters teaser::RobustRegistrationSolver::Params params; params.noise_bound = NOISE_BOUND; params.cbar2 = 1; params.estimate_scaling = false; params.rotation_max_iterations = 100; params.rotation_gnc_factor = 1.4; params.rotation_estimation_algorithm = teaser::RobustRegistrationSolver::ROTATION_ESTIMATION_ALGORITHM::GNC_TLS; params.rotation_cost_threshold = 0.005;
// Solve with TEASER++ std::cout << “Solve with TEASER++” << std::endl; teaser::RobustRegistrationSolver solver(params); std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now(); solver.solve(src, tgt); std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
auto solution = solver.getSolution();
// Compare results std::cout << “=====================================” << std::endl; std::cout << " TEASER++ Results " << std::endl; std::cout << “=====================================” << std::endl; std::cout << "Expected rotation: " << std::endl; std::cout << T.topLeftCorner(3, 3) << std::endl; std::cout << "Estimated rotation: " << std::endl; std::cout << solution.rotation << std::endl; std::cout << "Error (deg): " << getAngularError(T.topLeftCorner(3, 3), solution.rotation) << std::endl; std::cout << std::endl; std::cout << "Expected translation: " << std::endl; std::cout << T.topRightCorner(3, 1) << std::endl; std::cout << "Estimated translation: " << std::endl; std::cout << solution.translation << std::endl; std::cout << "Error (m): " << (T.topRightCorner(3, 1) - solution.translation).norm() << std::endl; std::cout << std::endl; std::cout << "Number of correspondences: " << N << std::endl; std::cout << "Number of outliers: " << N_OUTLIERS << std::endl; std::cout << "Time taken (s): " << std::chrono::duration_caststd::chrono::microseconds(end - begin).count() / 1000000.0 << std::endl; }
`
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Comments: 18 (9 by maintainers)
The larger the bound, TEASER++ will behave more similar to a solution obtained with SVD, as the GNC will essentially terminate at the first iteration. You can also try to estimate the ground truth outlier ratio here, by essentially calculating how many correspondences are close enough after ground truth rotation and translation, and see whether TEASER++ is selecting the correct inliers. If TEASER++ is selecting the correct inliers, but the result is still bad, then there might be some hidden bugs in the solver. If on the other hand TEASER is selecting the incorrect inliers (even after tuning the thresholds), then that means your data is somehow violating our assumptions about either isotropic noise, or the point cloud is not from rigid objects.
There’s some issue with the included FPFH estimator. I recommend using Open3D’s FPFH features and use the python binding.