如何从ceres求解器结果中检索异常值?

时间:2016-05-22 20:54:27

标签: c++ least-squares nonlinear-optimization ceres-solver

我尝试使用与Features2D + Homography to find a known object类似的方法比较图片,但用自编findHomography()函数替换findAffine()

我使用Ceres Solver来获得考虑异常值的最佳仿射矩阵。

    double translation[] = {0, 0};
    double angle = 0;
    double scaleFactor = 1;

    ceres::Problem problem;


    for (size_t i = 0; i < points1.size(); ++i) {
        problem.AddResidualBlock(
                  new ceres::AutoDiffCostFunction<AffineResidual, 1, 2, 1, 1>(
                          new AffineResidual(Eigen::Vector2d(points1[i].x, points1[i].y),
                                             Eigen::Vector2d(points2[i].x, points2[i].y))),
                          new ceres::HuberLoss(1.0),
                          translation,
                          &angle,
                          &scaleFactor);
    }

    ceres::Solver::Options options;
    options.linear_solver_type = ceres::DENSE_QR;
    options.minimizer_progress_to_stdout = true;

    ceres::Solver::Summary summary;
    Solve(options, &problem, &summary);

Ceres解算器提供LossFunction

  

损失函数减少了具有高残差的残差块的影响,通常是与异常值相对应的残差。

当然,我可以通过获得的矩阵从第一个图像转换关键点坐标,与第二个图像进行比较并获得偏差。但是ceres solver已经在工作期间完成了它。

我如何找回它?没有在文档中找到它。

1 个答案:

答案 0 :(得分:3)

我遇到了类似的问题。在查看Ceres库源(特别是ResidualBlock :: Evaluate()方法)之后,我得出结论,残差块没有明确的“异常值”状态。似乎损失函数仅影响块的结果成本值(这正是您引用的文档中的短语所描述的 - “损失函数减少了具有高残差的残余块的影响”)。所以答案是你不能从Ceres检索异常值,没有这样的功能。

解决方法可能是使用已解决的结果计算数据的残差,并对其应用损失函数。 LossFunction :: Evaluate()的评论可能有所帮助:

// For a residual vector with squared 2-norm 'sq_norm', this method
// is required to fill in the value and derivatives of the loss
// function (rho in this example):
//
//   out[0] = rho(sq_norm),
//   out[1] = rho'(sq_norm),
//   out[2] = rho''(sq_norm),
//
// Here the convention is that the contribution of a term to the
// cost function is given by 1/2 rho(s),  where
//
//   s = ||residuals||^2.
//
// Calling the method with a negative value of 's' is an error and
// the implementations are not required to handle that case.
//
// Most sane choices of rho() satisfy:
//
//   rho(0) = 0,
//   rho'(0) = 1,
//   rho'(s) < 1 in outlier region,
//   rho''(s) < 0 in outlier region,
//
// so that they mimic the least squares cost for small residuals.
virtual void Evaluate(double sq_norm, double out[3]) const = 0;