1. 程式人生 > >ceres求解BA第10章

ceres求解BA第10章

erb 其中 優化 reset 排序。 就會 func onerror i+1

1.前言
g2o是根據邊來保存每一個代價函數,它是在邊類中構造誤差函數,構造邊的時候,會設置頂點、測量值、協方差矩陣等。而在ceres中,用problem類型來構造最終的目標函數。先是使用AddResidualBlock來添加代價函數,代價函數和核函數等構造成目標函數。
在ceres中,代價函數就是誤差項,目標函數是由很多誤差項的範數的平方再各自乘以核函數除以2得到的。
2.定義代價函數類型,定義其create成員來使用ceres當中的AutoDiff特性
所謂的定義代價函數類型是定義了一個SnavelyReprojectionError.h文件,它的構造函數中用的成員變量是observed_x,observed_y,會把傳入的值賦值給observed_x,observed_y,這兩個值是測量值,在重載運算符()中,只有輸入camera,point,residuals,那麽camera,point就會計算出預測值,和測量值相減,就可以得到誤差項。
而ceres::AutoDiffCostFunction的參數就是這個SnavelyProjectionError類和2,9,3,輸入值就是SnavelyProjectionError類。
3.ceresBundle.cpp 添加代價函數
定義point_block_size和camera_block_size,這裏是3和9
定義points和cameras指針,返回值分別是parameters_+cmear_block_size()*num_cameras_;和parameters_
定義觀測值常量指針observations,返回值是2*num_observations_的列。observations數據不能更改。沒有給出觀測值的具體值啊,這個是要讀取的。
根據觀測值數量做一個for循環,定義代價函數指針cost_function.它的值形式就是SnavelyProjectionError.h的create函數,輸入變量是observations[2*i+0],observations[2*i+1].
定義損失函數指針為loss_function,這裏的損失函數類似於魯棒核函數,也是用來怕不好的數據點影響叠代效果的。它的值為如果params.robustify是健壯的,就用HuberLoss(1.0)函數,這裏的delta定位1.0.如果不健壯就為NULL.
定義數據指針camera,point為cameras+9*camera_index()[i]和points+3*point_index()[i];
point_index為num_observations_長度的列,camera_index同樣。

然後往問題裏添加代價函數就可以了。是這麽添加的
problem->AddResidualBlock(cost_function,loss_function,camera,point)
只有放入代價函數,損失函數,放入camera,point這個SnavelyProjectionError.h就可以用到這兩個值得到代價函數的形式。看problem.h可以看到,在problem類中,添加目標函數的變量都是指針形式,分別是代價函數,損失函數,x0和x1.
ResidualBlockId AddResidualBlock(CostFunction* cost_function,
LossFunction* loss_function,
double* x0, double* x1);
4.ceresBundle.cpp 用ParameterBlockOrdering來管理Schur的消元順序
定義SetOrdering函數來做。在函數裏分別定義
num_points,points_block_size,指針points,points值為parameters_ + camera_block_size() * num_cameras_; 跟之前一樣。
還有num_cameras,camera_block_size,指針cameras.
如果參數的ordering值為"automatic",那麽跳出函數,否則
定義ParameterBlockOrdering指針 ordering.
用ordering的AddElementToGroup對變量進行編號從而定義消元順序。這裏設置點雲變量為0,相機變量為1.
先做points的循環
ordering->AddElementToGroup(points+point_block_size*i,0);
然後把ordering放到ceres的求解器options中
options->linear_solver_ordering.reset(ordering)
5.ceresBundle.cpp 設置優化策略
ceres設置優化策略等直接對Solver::Options的類型成員進行賦值就可以了,很方便。
這裏設了一個setSolverOptionsFromFlags函數,變量有bal_problem用來提供各種參數值的,params用來判斷的,options選擇優化策略的。
來看options的幾個參數值。
max_num_iterations:最大叠代次數
minimizer_progress_to_stdout:要不要輸出到cout,如果輸出,填true;
num_threads:用於計算的線程數目,可以加速雅克比矩陣的計算。
trust_region_strategy_type:下降策略的選取
linear_solver_type:增量方程如何求解,例如ceres::DENSE_QR.
設置好options之後,把它放入之前的SetOrdering函數,對schur消元進行排序。
6求解的設置
也還是options的參數
gradient_tolerance=1e-16;梯度
function_tolerance=1e-16:兩次叠代之間目標函數之差的閾值。
定義統計信息summary,然後一次把options,&problem,&summary放入求解 函數solve就可以了。其中options是設置求解策略和閾值等的,problem是用來設置目標函數是怎麽求得,summary是求解之後的統計信息。

 

ceres求解BA第10章