18.Ceres官方教程-Modeling Non-linear Least Squares (6) Problem

18.Ceres官方教程-Modeling Non-linear Least Squares (6) Problem
Problem保持了非线性最小二乘问题的强化的边界。要创建最小二乘问题,可以使用Problem::AddResidualBlock()Problem::AddParameterBlock()
例如,下面这个Problem包含了三个参数块,维度分别为3,4,5。同时有两个残差块,维度分别是2和6。

double x1[] = { 1.0, 2.0, 3.0 };
double x2[] = { 1.0, 2.0, 3.0, 5.0 };
double x3[] = { 1.0, 2.0, 3.0, 6.0, 7.0 };

Problem problem;
problem.AddResidualBlock(new MyUnaryCostFunction(...), x1);
problem.AddResidualBlock(new MyBinaryCostFunction(...), x2, x3);

顾名思义,Problem::AddResidualBlock()向问题中添加了一个残差块。它添加了一个CostFunction,一个可选的LossFunction,并将CostFunction连接到一组参数块。
代价函数携带关于它所期望的参数块大小的信息。函数检查这些参数是否与parameter_blocks中列出的参数块的大小匹配。如果检测到不匹配,程序将中止。
Loss_function可以是nullptr,在这种情况下,该项的代价就是残差的平方范数。

用户可以使用Problem::AddParameterBlock()显式添加参数块。这将导致额外的正确性检查;然而,如果参数块不存在,Problem::AddResidualBlock()会隐式添加参数块,
因此不需要显式调用Problem::AddParameterBlock()。

AddParameterBlock()显式地向Problem添加了一个参数块。它还允许用户将LocalParameterization对象与参数块关联起来。具有相同参数的重复调用将被忽略。使用相同的双指针但大小不同的重复调用将导致未定义行为。

您可以使用Problem::SetParameterBlockConstant()将任何参数块设置为常量,并使用SetParameterBlockVariable()撤消此操作。

事实上,你可以设置任意数量的参数块为常量,Ceres足够聪明,能够知道你构建的问题的哪一部分取决于参数块,这些参数块可以自由更改,只需要花时间来解决它。
举个例子,如果你构造了一个有一百万个参数块和两百万个残差块的问题,然后把除了一个参数块之外的所有块都设置为常量,那么只有10个残差块依赖于这个非常量参数块。
如果你用一个参数块和10个残差块定义一个问题,那么Ceres在解决这个问题上所花费的计算工作量将是相同的。

Ownership

默认情况下,Problem拥有cost_function、loss_function和local_parameterization指针。这些对象在Problem的生命中仍然存在。
如果用户希望控制这些对象的销毁,那么他们可以通过在Problem::Options结构中设置相应的枚举来做到这一点。

请注意,即使Problem获得了cost_function和loss_function的所有权,它也不能阻止用户在另一个残差块中重用它们。
析构函数小心地对每个cost_function或loss_function指针只调用一次delete,不管有多少残差块引用它们。

18.Ceres官方教程-Modeling Non-linear Least Squares (6) Problem
TODO...

18.Ceres官方教程-Modeling Non-linear Least Squares (6) Problem
TODO...

18.Ceres官方教程-Modeling Non-linear Least Squares (6) Problem
TODO...

18.Ceres官方教程-Modeling Non-linear Least Squares (6) Problem
TODO...

18.Ceres官方教程-Modeling Non-linear Least Squares (6) Problem
TODO...

18.Ceres官方教程-Modeling Non-linear Least Squares (6) Problem

TODO...

18.Ceres官方教程-Modeling Non-linear Least Squares (6) Problem
TODO...

18.Ceres官方教程-Modeling Non-linear Least Squares (6) Problem
TODO...

18.Ceres官方教程-Modeling Non-linear Least Squares (6) Problem
在总代价函数中添加一个残差块。代价函数携带关于它所期望的参数块大小的信息。函数检查这些参数是否与parameter_blocks中列出的参数块的大小匹配。
如果检测到不匹配,程序将中止。Loss_function可以是nullptr,在这种情况下,该项的代价就是残差的平方范数。

形参块可以作为vector<double>或double指针一起传递。

用户可以选择使用AddParameterBlock显式添加参数块。这将导致额外的正确性检查;然而,如果参数块不存在,AddResidualBlock会隐式添加参数块,因此不需要显式调用AddParameterBlock。
Problem对象默认接受cost_function和loss_function指针的所有权。这些对象在Problem对象的生命周期中仍然存在。如果用户希望控制这些对象的销毁,那么他们可以通过在Options结构中设置相应的枚举来实现。

注意:即使Problem获得了cost_function和loss_function的所有权,它也不能阻止用户在另一个残差块中重用它们。析构函数小心地对每个cost_function或loss_function指针只调用一次delete,不管有多少残差块引用它们。

使用示例:

double x1[] = {1.0, 2.0, 3.0};
double x2[] = {1.0, 2.0, 5.0, 6.0};
double x3[] = {3.0, 6.0, 2.0, 5.0, 1.0};
vector<double*> v1;
v1.push_back(x1);
vector<double*> v2;
v2.push_back(x2);
v2.push_back(x1);

Problem problem;

problem.AddResidualBlock(new MyUnaryCostFunction(...), nullptr, x1);
problem.AddResidualBlock(new MyBinaryCostFunction(...), nullptr, x2, x1);
problem.AddResidualBlock(new MyUnaryCostFunction(...), nullptr, v1);
problem.AddResidualBlock(new MyBinaryCostFunction(...), nullptr, v2);

18.Ceres官方教程-Modeling Non-linear Least Squares (6) Problem
为问题添加一个大小适当的参数块。具有相同参数的重复调用将被忽略。使用相同的双指针但大小不同的重复调用将导致未定义行为。

18.Ceres官方教程-Modeling Non-linear Least Squares (6) Problem
向问题添加一个具有适当大小和参数化的参数块。具有相同参数的重复调用将被忽略。使用相同的双指针但大小不同的重复调用将导致未定义行为。

原文链接: https://www.cnblogs.com/vivian187/p/15393338.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍;

也有高质量的技术群,里面有嵌入式、搜广推等BAT大佬

    18.Ceres官方教程-Modeling Non-linear Least Squares (6) Problem

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/396766

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年4月7日 上午9:10
下一篇 2023年4月7日 上午9:10

相关推荐