Ceres
来源:互联网 发布:dnf决战人工智能攻略 编辑:程序博客网 时间:2024/06/06 04:23
Hello World!
cost function
struct CostFunctor { template <typename T> bool operator()(const T* const x, T* residual) const { residual[0] = T(10.0) - x[0]; return true; }};
problem
// auto-differentiation to obtain the derivative (jacobian). CostFunction* cost_function = new AutoDiffCostFunction<CostFunctor, 1, 1>(new CostFunctor); problem.AddResidualBlock(cost_function, NULL, &x);
Numeric
cost function
struct NumericDiffCostFunctor { bool operator()(const double* const x, double* residual) const { residual[0] = 10.0 - x[0]; return true; }};
Problem
CostFunction* cost_function = new NumericDiffCostFunction<NumericDiffCostFunctor, ceres::CENTRAL, 1, 1>( new NumericDiffCostFunctor);problem.AddResidualBlock(cost_function, NULL, &x);
Powell’s Function
cost function
struct F4 { template <typename T> bool operator()(const T* const x1, const T* const x4, T* residual) const { residual[0] = T(sqrt(10.0)) * (x1[0] - x4[0]) * (x1[0] - x4[0]); return true; }};
用同样的方法构造F1、F2、F3的costfunction。
problem
problem.AddResidualBlock(new AutoDiffCostFunction<F1, 1, 1, 1>(new F1), NULL, &x1, &x2);problem.AddResidualBlock(new AutoDiffCostFunction<F2, 1, 1, 1>(new F2), NULL, &x3, &x4);problem.AddResidualBlock(new AutoDiffCostFunction<F3, 1, 1, 1>(new F3), NULL, &x2, &x3)problem.AddResidualBlock(new AutoDiffCostFunction<F4, 1, 1, 1>(new F4), NULL, &x1, &x4);
Curve Fitting(曲线拟合)
cost dunction
struct ExponentialResidual { ExponentialResidual(double x, double y) : x_(x), y_(y) {} template <typename T> bool operator()(const T* const m, const T* const c, T* residual) const { residual[0] = T(y_) - exp(m[0] * T(x_) + c[0]); return true; } private: // Observations for a sample. const double x_; const double y_;};
problem
Problem problem;for (int i = 0; i < kNumObservations; ++i) { CostFunction* cost_function = new AutoDiffCostFunction<ExponentialResidual, 1, 1, 1>( new ExponentialResidual(data[2 * i], data[2 * i + 1])); problem.AddResidualBlock(cost_function, NULL, &m, &c);}
拟合情况如下图
Robust Curve Fitting
假设在曲线拟合是我们得到的数据有一些不符合噪音异常值,那么我们使用上面的方法来拟合时就会发现拟合曲线将会偏离真实值。(注意在图像最上方的异常值)
我们可以使用lostfuncion
来解决这个问题。将代码
problem.AddResidualBlock(cost_function, NULL , &m, &c);
改为
problem.AddResidualBlock(cost_function, new CauchyLoss(0.5) , &m, &c);
Cauchyloss
是ceres求解器的一种损失函数。我们可以得到以下结果。
Bundle Adjustment
使用ceres主要就是为了解决BA问题,而BA问题通常是一个非线性优化问题。首先使用一个定义好的模块化函数来计算重投影,该函数的结构和取幂函数ExponentialResidual
类似,都有一个实例来观察每个image。
每一个BAL(Bundle Adjustment in Large)问题都需要三维点和有九个参数的相机模型,九个参数分别是三个旋转参数、三个平移参数、一个深度参数和两个畸变参数。
cost function
struct SnavelyReprojectionError { SnavelyReprojectionError(double observed_x, double observed_y) : observed_x(observed_x), observed_y(observed_y) {} template <typename T> bool operator()(const T* const camera, const T* const point, T* residuals) const { // camera[0,1,2] 是轴角参数。 T p[3]; ceres::AngleAxisRotatePoint(camera, point, p); // camera[3,4,5] 是平移参数。 p[0] += camera[3]; p[1] += camera[4]; p[2] += camera[5]; // Compute the center of distortion. The sign change comes from // the camera model that Noah Snavely's Bundler assumes, whereby // the camera coordinate system has a negative z axis. T xp = - p[0] / p[2]; T yp = - p[1] / p[2]; // Apply second and fourth order radial distortion. const T& l1 = camera[7]; const T& l2 = camera[8]; T r2 = xp*xp + yp*yp; T distortion = T(1.0) + r2 * (l1 + l2 * r2); // Compute final projected point position. //计算最终投影点位置。 const T& focal = camera[6]; T predicted_x = focal * distortion * xp; T predicted_y = focal * distortion * yp; // The error is the difference between the predicted and observed position. //误差是预测和观察到的位置的差值。 residuals[0] = predicted_x - T(observed_x); residuals[1] = predicted_y - T(observed_y); return true; } // Factory to hide the construction of the CostFunction object from // the client code. static ceres::CostFunction* Create(const double observed_x, const double observed_y) { return (new ceres::AutoDiffCostFunction<SnavelyReprojectionError, 2, 9, 3>( new SnavelyReprojectionError(observed_x, observed_y))); } double observed_x; double observed_y;};
problem
ceres::Problem problem;for (int i = 0; i < bal_problem.num_observations(); ++i) { ceres::CostFunction* cost_function = SnavelyReprojectionError::Create( bal_problem.observations()[2 * i + 0], bal_problem.observations()[2 * i + 1]); problem.AddResidualBlock(cost_function, NULL /* squared loss */, bal_problem.mutable_camera_for_observation(i), bal_problem.mutable_point_for_observation(i));}
阅读全文
0 0
- Ceres
- Ceres
- Ceres solver
- Ceres solver2
- Ceres优化
- Ceres(1)
- Ceres-Solver库入门
- Ceres solver tutorial
- Windows 配置 Ceres-solver
- VS2013 ceres-solver编译
- ceres-solver拟合椭球
- ceres solver 学习笔记
- ceres-solver使用
- ceres solver使用
- Ceres Solver for android
- Ceres Solver使用
- Ceres(5): Solver
- ceres学习网址
- 编码问题(1):文件编码与java编码的对应关系
- 确保物联网安全的关键技术盘点
- SIFT学习--构建尺度空间
- PyTorch学习总结(五)——torch.nn
- 蓝牙开发经验小结——自动配对
- Ceres
- BIGEMAP软件详细功能列表介绍
- 前端框架 更改列数后不能进行分页并且页面报错
- 编写一个应用程序,用户分别从两个文本框输入学术的姓名和分 数,程序按成绩排序将这些学生的姓名和分数显示在一个文本区中 。
- java8之数据流Stream的Map和flatMap的区别
- Linux下压缩和解压文件
- HTTP方法:get和post的区别
- MyEclipse下Maven的安装配置
- 问题 A: Hello World(JSU-ZJJ)