如何从 ceres 求解器结果中检索异常值?
How to retrieve outliers from ceres solver result?
我尝试使用类似于Features2D + Homography to find a known object的方法来比较图像,但是用自己编写的findAffine()
函数替换了findHomography()
。
我使用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:
Loss functions reduce the influence of residual blocks with high residuals, usually the ones corresponding to outliers.
当然,我可以通过获得的矩阵从第一张图像转换关键点坐标,与第二张图像进行比较并得到偏差。但是 ceres 求解器已经在工作期间在内部完成了。
我怎样才能找回它?在文档中没有找到它。
我遇到了类似的问题。在查看 Ceres 库资源(特别是 ResidualBlock::Evaluate() 方法)后,我得出结论,残差块没有明确的 "outlier" 状态。似乎损失函数只影响块的最终成本值(这正是您引用的文档中的短语描述的 - "Loss functions reduce the influence of residual blocks with high residuals")。所以答案是你无法从 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;
我尝试使用类似于Features2D + Homography to find a known object的方法来比较图像,但是用自己编写的findAffine()
函数替换了findHomography()
。
我使用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:
Loss functions reduce the influence of residual blocks with high residuals, usually the ones corresponding to outliers.
当然,我可以通过获得的矩阵从第一张图像转换关键点坐标,与第二张图像进行比较并得到偏差。但是 ceres 求解器已经在工作期间在内部完成了。
我怎样才能找回它?在文档中没有找到它。
我遇到了类似的问题。在查看 Ceres 库资源(特别是 ResidualBlock::Evaluate() 方法)后,我得出结论,残差块没有明确的 "outlier" 状态。似乎损失函数只影响块的最终成本值(这正是您引用的文档中的短语描述的 - "Loss functions reduce the influence of residual blocks with high residuals")。所以答案是你无法从 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;