Skip to content

Commit aab340f

Browse files
authored
Improve optimizeModelCoefficients for cone, cylinder, sphere models (#5790)
* Improve optimizeModelCoefficients for cone,cylinder,sphere models This has two effects: making the functions faster and reducing PCL's compile time. The function that is optimized is exactly the same as before. In my tests, optimizeModelCoefficients is now at least twice as fast, often even three times as fast as before. This is because the x, y, and z values are perfectly arranged for SSE and AVX instructions. The time needed to compile PCL is also reduced: instantiating Eigen::LevenbergMarquardt takes a rather long time, and previously this was done for each point type (sphere model) or even each point type-normal type combination (cone and cylinder model). Now, Eigen::LevenbergMarquardt is only instantiated once for all cone models, once for all cylinder models, and once for all sphere models. In my tests, this leads to a compile time reduction of roughly 1 minute (building the sample consensus library took 14m35s before and 13m31s now, one compile job, PCL_ONLY_CORE_POINT_TYPES=OFF). * Add more const
1 parent 969d5d3 commit aab340f

9 files changed

Lines changed: 190 additions & 142 deletions

File tree

sample_consensus/include/pcl/sample_consensus/impl/sac_model_cone.hpp

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@
3939
#ifndef PCL_SAMPLE_CONSENSUS_IMPL_SAC_MODEL_CONE_H_
4040
#define PCL_SAMPLE_CONSENSUS_IMPL_SAC_MODEL_CONE_H_
4141

42-
#include <unsupported/Eigen/NonLinearOptimization> // for LevenbergMarquardt
4342
#include <pcl/sample_consensus/sac_model_cone.h>
4443
#include <pcl/common/common.h> // for getAngle3D
4544
#include <pcl/common/concatenate.h>
@@ -344,14 +343,20 @@ pcl::SampleConsensusModelCone<PointT, PointNT>::optimizeModelCoefficients (
344343
return;
345344
}
346345

347-
OptimizationFunctor functor (this, inliers);
348-
Eigen::NumericalDiff<OptimizationFunctor > num_diff (functor);
349-
Eigen::LevenbergMarquardt<Eigen::NumericalDiff<OptimizationFunctor>, float> lm (num_diff);
350-
int info = lm.minimize (optimized_coefficients);
346+
Eigen::ArrayXf pts_x(inliers.size());
347+
Eigen::ArrayXf pts_y(inliers.size());
348+
Eigen::ArrayXf pts_z(inliers.size());
349+
std::size_t pos = 0;
350+
for(const auto& index : inliers) {
351+
pts_x[pos] = (*input_)[index].x;
352+
pts_y[pos] = (*input_)[index].y;
353+
pts_z[pos] = (*input_)[index].z;
354+
++pos;
355+
}
356+
pcl::internal::optimizeModelCoefficientsCone(optimized_coefficients, pts_x, pts_y, pts_z);
351357

352-
// Compute the L2 norm of the residuals
353-
PCL_DEBUG ("[pcl::SampleConsensusModelCone::optimizeModelCoefficients] LM solver finished with exit code %i, having a residual norm of %g. \nInitial solution: %g %g %g %g %g %g %g \nFinal solution: %g %g %g %g %g %g %g\n",
354-
info, lm.fvec.norm (), model_coefficients[0], model_coefficients[1], model_coefficients[2], model_coefficients[3],
358+
PCL_DEBUG ("[pcl::SampleConsensusModelCone::optimizeModelCoefficients] Initial solution: %g %g %g %g %g %g %g \nFinal solution: %g %g %g %g %g %g %g\n",
359+
model_coefficients[0], model_coefficients[1], model_coefficients[2], model_coefficients[3],
355360
model_coefficients[4], model_coefficients[5], model_coefficients[6], optimized_coefficients[0], optimized_coefficients[1], optimized_coefficients[2], optimized_coefficients[3], optimized_coefficients[4], optimized_coefficients[5], optimized_coefficients[6]);
356361

357362
Eigen::Vector3f line_dir (optimized_coefficients[3], optimized_coefficients[4], optimized_coefficients[5]);

sample_consensus/include/pcl/sample_consensus/impl/sac_model_cylinder.hpp

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@
4141
#ifndef PCL_SAMPLE_CONSENSUS_IMPL_SAC_MODEL_CYLINDER_H_
4242
#define PCL_SAMPLE_CONSENSUS_IMPL_SAC_MODEL_CYLINDER_H_
4343

44-
#include <unsupported/Eigen/NonLinearOptimization> // for LevenbergMarquardt
4544
#include <pcl/sample_consensus/sac_model_cylinder.h>
4645
#include <pcl/common/common.h> // for getAngle3D
4746
#include <pcl/common/concatenate.h>
@@ -299,14 +298,20 @@ pcl::SampleConsensusModelCylinder<PointT, PointNT>::optimizeModelCoefficients (
299298
return;
300299
}
301300

302-
OptimizationFunctor functor (this, inliers);
303-
Eigen::NumericalDiff<OptimizationFunctor > num_diff (functor);
304-
Eigen::LevenbergMarquardt<Eigen::NumericalDiff<OptimizationFunctor>, float> lm (num_diff);
305-
int info = lm.minimize (optimized_coefficients);
301+
Eigen::ArrayXf pts_x(inliers.size());
302+
Eigen::ArrayXf pts_y(inliers.size());
303+
Eigen::ArrayXf pts_z(inliers.size());
304+
std::size_t pos = 0;
305+
for(const auto& index : inliers) {
306+
pts_x[pos] = (*input_)[index].x;
307+
pts_y[pos] = (*input_)[index].y;
308+
pts_z[pos] = (*input_)[index].z;
309+
++pos;
310+
}
311+
pcl::internal::optimizeModelCoefficientsCylinder(optimized_coefficients, pts_x, pts_y, pts_z);
306312

307-
// Compute the L2 norm of the residuals
308-
PCL_DEBUG ("[pcl::SampleConsensusModelCylinder::optimizeModelCoefficients] LM solver finished with exit code %i, having a residual norm of %g. \nInitial solution: %g %g %g %g %g %g %g \nFinal solution: %g %g %g %g %g %g %g\n",
309-
info, lm.fvec.norm (), model_coefficients[0], model_coefficients[1], model_coefficients[2], model_coefficients[3],
313+
PCL_DEBUG ("[pcl::SampleConsensusModelCylinder::optimizeModelCoefficients] Initial solution: %g %g %g %g %g %g %g \nFinal solution: %g %g %g %g %g %g %g\n",
314+
model_coefficients[0], model_coefficients[1], model_coefficients[2], model_coefficients[3],
310315
model_coefficients[4], model_coefficients[5], model_coefficients[6], optimized_coefficients[0], optimized_coefficients[1], optimized_coefficients[2], optimized_coefficients[3], optimized_coefficients[4], optimized_coefficients[5], optimized_coefficients[6]);
311316

312317
Eigen::Vector3f line_dir (optimized_coefficients[3], optimized_coefficients[4], optimized_coefficients[5]);

sample_consensus/include/pcl/sample_consensus/impl/sac_model_sphere.hpp

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@
4141
#ifndef PCL_SAMPLE_CONSENSUS_IMPL_SAC_MODEL_SPHERE_H_
4242
#define PCL_SAMPLE_CONSENSUS_IMPL_SAC_MODEL_SPHERE_H_
4343

44-
#include <unsupported/Eigen/NonLinearOptimization> // for LevenbergMarquardt
4544
#include <pcl/sample_consensus/sac_model_sphere.h>
4645

4746
//////////////////////////////////////////////////////////////////////////
@@ -354,14 +353,20 @@ pcl::SampleConsensusModelSphere<PointT>::optimizeModelCoefficients (
354353
return;
355354
}
356355

357-
OptimizationFunctor functor (this, inliers);
358-
Eigen::NumericalDiff<OptimizationFunctor> num_diff (functor);
359-
Eigen::LevenbergMarquardt<Eigen::NumericalDiff<OptimizationFunctor>, float> lm (num_diff);
360-
int info = lm.minimize (optimized_coefficients);
356+
Eigen::ArrayXf pts_x(inliers.size());
357+
Eigen::ArrayXf pts_y(inliers.size());
358+
Eigen::ArrayXf pts_z(inliers.size());
359+
std::size_t pos = 0;
360+
for(const auto& index : inliers) {
361+
pts_x[pos] = (*input_)[index].x;
362+
pts_y[pos] = (*input_)[index].y;
363+
pts_z[pos] = (*input_)[index].z;
364+
++pos;
365+
}
366+
pcl::internal::optimizeModelCoefficientsSphere(optimized_coefficients, pts_x, pts_y, pts_z);
361367

362-
// Compute the L2 norm of the residuals
363-
PCL_DEBUG ("[pcl::SampleConsensusModelSphere::optimizeModelCoefficients] LM solver finished with exit code %i, having a residual norm of %g. \nInitial solution: %g %g %g %g \nFinal solution: %g %g %g %g\n",
364-
info, lm.fvec.norm (), model_coefficients[0], model_coefficients[1], model_coefficients[2], model_coefficients[3], optimized_coefficients[0], optimized_coefficients[1], optimized_coefficients[2], optimized_coefficients[3]);
368+
PCL_DEBUG ("[pcl::SampleConsensusModelSphere::optimizeModelCoefficients] Initial solution: %g %g %g %g \nFinal solution: %g %g %g %g\n",
369+
model_coefficients[0], model_coefficients[1], model_coefficients[2], model_coefficients[3], optimized_coefficients[0], optimized_coefficients[1], optimized_coefficients[2], optimized_coefficients[3]);
365370
}
366371

367372
//////////////////////////////////////////////////////////////////////////

sample_consensus/include/pcl/sample_consensus/sac_model_cone.h

Lines changed: 4 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@
4444

4545
namespace pcl
4646
{
47+
namespace internal {
48+
int optimizeModelCoefficientsCone (Eigen::VectorXf& coeff, const Eigen::ArrayXf& pts_x, const Eigen::ArrayXf& pts_y, const Eigen::ArrayXf& pts_z);
49+
} // namespace internal
50+
4751
/** \brief @b SampleConsensusModelCone defines a model for 3D cone segmentation.
4852
* The model coefficients are defined as:
4953
* <ul>
@@ -299,54 +303,6 @@ namespace pcl
299303
/** \brief The minimum and maximum allowed opening angles of valid cone model. */
300304
double min_angle_;
301305
double max_angle_;
302-
303-
/** \brief Functor for the optimization function */
304-
struct OptimizationFunctor : pcl::Functor<float>
305-
{
306-
/** Functor constructor
307-
* \param[in] indices the indices of data points to evaluate
308-
* \param[in] estimator pointer to the estimator object
309-
*/
310-
OptimizationFunctor (const pcl::SampleConsensusModelCone<PointT, PointNT> *model, const Indices& indices) :
311-
pcl::Functor<float> (indices.size ()), model_ (model), indices_ (indices) {}
312-
313-
/** Cost function to be minimized
314-
* \param[in] x variables array
315-
* \param[out] fvec resultant functions evaluations
316-
* \return 0
317-
*/
318-
int
319-
operator() (const Eigen::VectorXf &x, Eigen::VectorXf &fvec) const
320-
{
321-
Eigen::Vector4f apex (x[0], x[1], x[2], 0);
322-
Eigen::Vector4f axis_dir (x[3], x[4], x[5], 0);
323-
float opening_angle = x[6];
324-
325-
float apexdotdir = apex.dot (axis_dir);
326-
float dirdotdir = 1.0f / axis_dir.dot (axis_dir);
327-
328-
for (int i = 0; i < values (); ++i)
329-
{
330-
// dist = f - r
331-
Eigen::Vector4f pt = (*model_->input_)[indices_[i]].getVector4fMap();
332-
pt[3] = 0;
333-
334-
// Calculate the point's projection on the cone axis
335-
float k = (pt.dot (axis_dir) - apexdotdir) * dirdotdir;
336-
Eigen::Vector4f pt_proj = apex + k * axis_dir;
337-
338-
// Calculate the actual radius of the cone at the level of the projected point
339-
Eigen::Vector4f height = apex-pt_proj;
340-
float actual_cone_radius = tanf (opening_angle) * height.norm ();
341-
342-
fvec[i] = static_cast<float> (pcl::sqrPointToLineDistance (pt, apex, axis_dir) - actual_cone_radius * actual_cone_radius);
343-
}
344-
return (0);
345-
}
346-
347-
const pcl::SampleConsensusModelCone<PointT, PointNT> *model_;
348-
const Indices &indices_;
349-
};
350306
};
351307
}
352308

sample_consensus/include/pcl/sample_consensus/sac_model_cylinder.h

Lines changed: 4 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@
4646

4747
namespace pcl
4848
{
49+
namespace internal {
50+
int optimizeModelCoefficientsCylinder (Eigen::VectorXf& coeff, const Eigen::ArrayXf& pts_x, const Eigen::ArrayXf& pts_y, const Eigen::ArrayXf& pts_z);
51+
} // namespace internal
52+
4953
/** \brief @b SampleConsensusModelCylinder defines a model for 3D cylinder segmentation.
5054
* The model coefficients are defined as:
5155
* - \b point_on_axis.x : the X coordinate of a point located on the cylinder axis
@@ -295,42 +299,6 @@ namespace pcl
295299

296300
/** \brief The maximum allowed difference between the cylinder direction and the given axis. */
297301
double eps_angle_;
298-
299-
/** \brief Functor for the optimization function */
300-
struct OptimizationFunctor : pcl::Functor<float>
301-
{
302-
/** Functor constructor
303-
* \param[in] indices the indices of data points to evaluate
304-
* \param[in] estimator pointer to the estimator object
305-
*/
306-
OptimizationFunctor (const pcl::SampleConsensusModelCylinder<PointT, PointNT> *model, const Indices& indices) :
307-
pcl::Functor<float> (indices.size ()), model_ (model), indices_ (indices) {}
308-
309-
/** Cost function to be minimized
310-
* \param[in] x variables array
311-
* \param[out] fvec resultant functions evaluations
312-
* \return 0
313-
*/
314-
int
315-
operator() (const Eigen::VectorXf &x, Eigen::VectorXf &fvec) const
316-
{
317-
Eigen::Vector4f line_pt (x[0], x[1], x[2], 0);
318-
Eigen::Vector4f line_dir (x[3], x[4], x[5], 0);
319-
320-
for (int i = 0; i < values (); ++i)
321-
{
322-
// dist = f - r
323-
Eigen::Vector4f pt = (*model_->input_)[indices_[i]].getVector4fMap();
324-
pt[3] = 0;
325-
326-
fvec[i] = static_cast<float> (pcl::sqrPointToLineDistance (pt, line_pt, line_dir) - x[6]*x[6]);
327-
}
328-
return (0);
329-
}
330-
331-
const pcl::SampleConsensusModelCylinder<PointT, PointNT> *model_;
332-
const Indices &indices_;
333-
};
334302
};
335303
}
336304

sample_consensus/include/pcl/sample_consensus/sac_model_sphere.h

Lines changed: 4 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@
5252

5353
namespace pcl
5454
{
55+
namespace internal {
56+
int optimizeModelCoefficientsSphere (Eigen::VectorXf& coeff, const Eigen::ArrayXf& pts_x, const Eigen::ArrayXf& pts_y, const Eigen::ArrayXf& pts_z);
57+
} // namespace internal
58+
5559
/** \brief SampleConsensusModelSphere defines a model for 3D sphere segmentation.
5660
* The model coefficients are defined as:
5761
* - \b center.x : the X coordinate of the sphere's center
@@ -263,40 +267,6 @@ namespace pcl
263267
#endif
264268

265269
private:
266-
struct OptimizationFunctor : pcl::Functor<float>
267-
{
268-
/** Functor constructor
269-
* \param[in] indices the indices of data points to evaluate
270-
* \param[in] estimator pointer to the estimator object
271-
*/
272-
OptimizationFunctor (const pcl::SampleConsensusModelSphere<PointT> *model, const Indices& indices) :
273-
pcl::Functor<float> (indices.size ()), model_ (model), indices_ (indices) {}
274-
275-
/** Cost function to be minimized
276-
* \param[in] x the variables array
277-
* \param[out] fvec the resultant functions evaluations
278-
* \return 0
279-
*/
280-
int
281-
operator() (const Eigen::VectorXf &x, Eigen::VectorXf &fvec) const
282-
{
283-
Eigen::Vector4f cen_t;
284-
cen_t[3] = 0;
285-
for (int i = 0; i < values (); ++i)
286-
{
287-
// Compute the difference between the center of the sphere and the datapoint X_i
288-
cen_t.head<3>() = (*model_->input_)[indices_[i]].getVector3fMap() - x.head<3>();
289-
290-
// g = sqrt ((x-a)^2 + (y-b)^2 + (z-c)^2) - R
291-
fvec[i] = std::sqrt (cen_t.dot (cen_t)) - x[3];
292-
}
293-
return (0);
294-
}
295-
296-
const pcl::SampleConsensusModelSphere<PointT> *model_;
297-
const Indices &indices_;
298-
};
299-
300270
#ifdef __AVX__
301271
inline __m256 sqr_dist8 (const std::size_t i, const __m256 a_vec, const __m256 b_vec, const __m256 c_vec) const;
302272
#endif

sample_consensus/src/sac_model_cone.cpp

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,56 @@
3737
*/
3838

3939
#include <pcl/sample_consensus/impl/sac_model_cone.hpp>
40+
#include <unsupported/Eigen/NonLinearOptimization> // for LevenbergMarquardt
41+
42+
int pcl::internal::optimizeModelCoefficientsCone (Eigen::VectorXf& coeff, const Eigen::ArrayXf& pts_x, const Eigen::ArrayXf& pts_y, const Eigen::ArrayXf& pts_z)
43+
{
44+
if(pts_x.size() != pts_y.size() || pts_y.size() != pts_z.size()) {
45+
PCL_ERROR("[pcl::internal::optimizeModelCoefficientsCone] Sizes not equal!\n");
46+
return Eigen::LevenbergMarquardtSpace::ImproperInputParameters;
47+
}
48+
if(coeff.size() != 7) {
49+
PCL_ERROR("[pcl::internal::optimizeModelCoefficientsCone] Coefficients have wrong size\n");
50+
return Eigen::LevenbergMarquardtSpace::ImproperInputParameters;
51+
}
52+
struct ConeOptimizationFunctor : pcl::Functor<float>
53+
{
54+
ConeOptimizationFunctor (const Eigen::ArrayXf& x, const Eigen::ArrayXf& y, const Eigen::ArrayXf& z) :
55+
pcl::Functor<float>(x.size()), pts_x(x), pts_y(y), pts_z(z)
56+
{}
57+
58+
int
59+
operator() (const Eigen::VectorXf &x, Eigen::VectorXf &fvec) const
60+
{
61+
Eigen::Vector3f axis_dir(x[3], x[4], x[5]);
62+
axis_dir.normalize();
63+
const Eigen::ArrayXf axis_dir_x = Eigen::ArrayXf::Constant(pts_x.size(), axis_dir.x());
64+
const Eigen::ArrayXf axis_dir_y = Eigen::ArrayXf::Constant(pts_x.size(), axis_dir.y());
65+
const Eigen::ArrayXf axis_dir_z = Eigen::ArrayXf::Constant(pts_x.size(), axis_dir.z());
66+
const Eigen::ArrayXf bx = Eigen::ArrayXf::Constant(pts_x.size(), x[0]) - pts_x;
67+
const Eigen::ArrayXf by = Eigen::ArrayXf::Constant(pts_x.size(), x[1]) - pts_y;
68+
const Eigen::ArrayXf bz = Eigen::ArrayXf::Constant(pts_x.size(), x[2]) - pts_z;
69+
const Eigen::ArrayXf actual_cone_radius = std::tan(x[6]) *
70+
(bx*axis_dir_x+by*axis_dir_y+bz*axis_dir_z);
71+
// compute the squared distance of point b to the line (cross product), then subtract the actual cone radius (squared)
72+
fvec = ((axis_dir_y * bz - axis_dir_z * by).square()
73+
+(axis_dir_z * bx - axis_dir_x * bz).square()
74+
+(axis_dir_x * by - axis_dir_y * bx).square())
75+
-actual_cone_radius.square();
76+
return (0);
77+
}
78+
79+
const Eigen::ArrayXf& pts_x, pts_y, pts_z;
80+
};
81+
82+
ConeOptimizationFunctor functor (pts_x, pts_y, pts_z);
83+
Eigen::NumericalDiff<ConeOptimizationFunctor> num_diff (functor);
84+
Eigen::LevenbergMarquardt<Eigen::NumericalDiff<ConeOptimizationFunctor>, float> lm (num_diff);
85+
const int info = lm.minimize (coeff);
86+
PCL_DEBUG ("[pcl::internal::optimizeModelCoefficientsCone] LM solver finished with exit code %i, having a residual norm of %g.\n",
87+
info, lm.fvec.norm ());
88+
return info;
89+
}
4090

4191
#ifndef PCL_NO_PRECOMPILE
4292
#include <pcl/impl/instantiate.hpp>

sample_consensus/src/sac_model_cylinder.cpp

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,55 @@
3737
*/
3838

3939
#include <pcl/sample_consensus/impl/sac_model_cylinder.hpp>
40+
#include <unsupported/Eigen/NonLinearOptimization> // for LevenbergMarquardt
41+
42+
int pcl::internal::optimizeModelCoefficientsCylinder (Eigen::VectorXf& coeff, const Eigen::ArrayXf& pts_x, const Eigen::ArrayXf& pts_y, const Eigen::ArrayXf& pts_z)
43+
{
44+
if(pts_x.size() != pts_y.size() || pts_y.size() != pts_z.size()) {
45+
PCL_ERROR("[pcl::internal::optimizeModelCoefficientsCylinder] Sizes not equal!\n");
46+
return Eigen::LevenbergMarquardtSpace::ImproperInputParameters;
47+
}
48+
if(coeff.size() != 7) {
49+
PCL_ERROR("[pcl::internal::optimizeModelCoefficientsCylinder] Coefficients have wrong size\n");
50+
return Eigen::LevenbergMarquardtSpace::ImproperInputParameters;
51+
}
52+
struct CylinderOptimizationFunctor : pcl::Functor<float>
53+
{
54+
CylinderOptimizationFunctor (const Eigen::ArrayXf& x, const Eigen::ArrayXf& y, const Eigen::ArrayXf& z) :
55+
pcl::Functor<float>(x.size()), pts_x(x), pts_y(y), pts_z(z)
56+
{}
57+
58+
int
59+
operator() (const Eigen::VectorXf &x, Eigen::VectorXf &fvec) const
60+
{
61+
Eigen::Vector3f line_dir(x[3], x[4], x[5]);
62+
line_dir.normalize();
63+
const Eigen::ArrayXf line_dir_x = Eigen::ArrayXf::Constant(pts_x.size(), line_dir.x());
64+
const Eigen::ArrayXf line_dir_y = Eigen::ArrayXf::Constant(pts_x.size(), line_dir.y());
65+
const Eigen::ArrayXf line_dir_z = Eigen::ArrayXf::Constant(pts_x.size(), line_dir.z());
66+
const Eigen::ArrayXf bx = Eigen::ArrayXf::Constant(pts_x.size(), x[0]) - pts_x;
67+
const Eigen::ArrayXf by = Eigen::ArrayXf::Constant(pts_x.size(), x[1]) - pts_y;
68+
const Eigen::ArrayXf bz = Eigen::ArrayXf::Constant(pts_x.size(), x[2]) - pts_z;
69+
// compute the squared distance of point b to the line (cross product), then subtract the squared model radius
70+
fvec = ((line_dir_y * bz - line_dir_z * by).square()
71+
+(line_dir_z * bx - line_dir_x * bz).square()
72+
+(line_dir_x * by - line_dir_y * bx).square())
73+
-Eigen::ArrayXf::Constant(pts_x.size(), x[6]*x[6]);
74+
return (0);
75+
}
76+
77+
const Eigen::ArrayXf& pts_x, pts_y, pts_z;
78+
};
79+
80+
CylinderOptimizationFunctor functor (pts_x, pts_y, pts_z);
81+
Eigen::NumericalDiff<CylinderOptimizationFunctor> num_diff (functor);
82+
Eigen::LevenbergMarquardt<Eigen::NumericalDiff<CylinderOptimizationFunctor>, float> lm (num_diff);
83+
const int info = lm.minimize (coeff);
84+
coeff[6] = std::abs(coeff[6]);
85+
PCL_DEBUG ("[pcl::internal::optimizeModelCoefficientsCylinder] LM solver finished with exit code %i, having a residual norm of %g.\n",
86+
info, lm.fvec.norm ());
87+
return info;
88+
}
4089

4190
#ifndef PCL_NO_PRECOMPILE
4291
#include <pcl/impl/instantiate.hpp>

0 commit comments

Comments
 (0)