OpenCV::LMSolver 得到一个简单的例子 运行

OpenCV::LMSolver getting a simple example to run

问题:至少可以说,opencv.orgcv::LMSolver 的文档非常薄。在互联网上找到一些有用的示例也是不可能的。

APPROACH: 所以,我确实写了一些简单的代码:

#include <opencv2/calib3d.hpp>
#include <iostream>

using namespace cv;
using namespace std;

struct Easy : public LMSolver::Callback {
   Easy() = default;

   virtual bool compute(InputArray f_param, OutputArray f_error, OutputArray f_jacobian) const override
   { 
        Mat  param = f_param.getMat();

        if( f_error.empty() ) f_error.create(1, 1, CV_64F);             // dim(error) = 1
        Mat  error = f_error.getMat();                          

        vector<double> x{param.at<double>(0,0), param.at<double>(1,0)}; // dim(param) = 2
        double         error0 = calc(x);
        error.at<double>(0,0) = error0;

        if( ! f_jacobian.needed() ) return true; 
        else if( f_jacobian.empty() ) f_jacobian.create(1, 2, CV_64F); 
        Mat  jacobian = f_jacobian.getMat();

        double e = 1e-10; // estimate derivatives in epsilon environment       
        jacobian.at<double>(0, 0) = (calc({x[0] + e, x[1]    }) - error0) / e; // d/dx0 (error)
        jacobian.at<double>(0, 1) = (calc({x[0],     x[1] + e}) - error0) / e; // d/dx1 (error)
        return true;
   }

   double calc(const vector<double> x) const { return x[0]*x[0] + x[1]*x[1]; }
};

int main(int argc, char** argv) 
{
    Ptr<Easy>      callback   = makePtr<Easy>();
    Ptr<LMSolver>  solver     = LMSolver::create(callback, 100000, 1e-37);
    Mat            parameters = (Mat_<double>(2,1) << 5, 100);
    solver->run(parameters);
    cout << parameters << endl;
}

问题:

What does the return value of LMSolver::Callback::compute() report to the caller?

值得庆幸的是,opencv 是开源的,所以我们也许可以通过查看代码来解决这个问题。

查看源代码 on Github,我发现对 compute() 的所有调用看起来像:

if( !cb->compute(x, r, J) )
    return -1;

返回 false 只会导致求解器退出。所以回调的 compute() 的 return 值似乎只是 jacobian 的生成是否成功。

Currently, it finds the minimum at (-9e-07,4e-5). How can the precision be improved?

如果有的话,您至少应该将 run() 的 return 值与您的最大迭代次数进行比较,以确保它确实尽可能地收敛。