lm算法原理介绍,opencv图像处理算法

1 .高斯zzdhf方法

残差函数f(x )是非线性函数,根据其一次wsdbbz近似为:

这里的j是残差函数f的雅可比矩阵,是引入了损失函数的:

如果将其一阶导设为0,则得到:

这就是论文中常见的正规公式。

2.LM

LM改进了高斯zzdhf方法,在求解过程中引入了衰减因子。

2.1衰减因子的作用:

2.2阻尼系数初始值的选择:

一个简单的策略是:

2.3衰减因子更新策略

3 .核心代码说明

3.1矩阵的构造

void problem :3360 make hessian (

TicToc t_h;

//直接构造大h矩阵

ulong size=ordering_generic_;

最大xh (matxx 3360: zero (size,size );

vecxb(vecx:3360zero(size );

//TODO: accelate、accelate和accelate

//#ifdef USE_OPENMP

//#pragma omp parallel for

//#endif

//对每个残差进行扫描,计算他们的雅可比,得到最后的H=J^T * J

for (自动边缘3360边缘_ ) }

edge.second-ComputeResidual (;

edge.second-ComputeJacobians (;

autojacobians=edge.second-jacobians (;

autoverticies=edge.second-vertici es (;

assert (jacobians.size (==vertici es.size ) );

for(size_tI=0; i verticies.size (; I ) {

auto v_i=verticies[i];

if(v_I-isfixed ) ) continue; //Hessian不需要添加该信息。 也就是说杰克比为0

auto jacobian_i=jacobians[i];

ulong index_i=v_i-OrderingId (;

ulong dim_i=v_i-LocalDimension (;

matxxjtw=Jacobian _ I.transpose (* edge.second-information );

for(size_tj=I; j verticies.size (; j ) {

auto v_j=verticies[j];

if(v_j-isfixed ) ) continue;

auto jacobian_j=jacobians[j];

ulong index_j=v_j-OrderingId (;

ulong dim_j=v_j-LocalDimension (;

assert(v_j-orderingid )!=-1;

MatXX hessian=JtW * jacobian_j;

//所有信息矩阵重叠

h.block(index_I,index_j,dim_i,dim_j ).noalias )=hessian;

if(j!=i ) {

//对称的下三角

h.block(index_j、index_i、dim_j、dim_i ).noalias )=hessian.transpose );

}

}

b.segment(index_I,dim_i ).noalias )-=JtW * edge.second-Residual );

}

}

Hessian_=H;

b_=b;

t_hessian_cost_ =t_h.toc (;

delta _ x _=vecx :3360 zero (size ); //initial delta_x=0_n;

}

3.2在构建的h矩阵中加入衰减因子

void problem : addlambdatohessianlm (

ulong size=Hessian_.cols (;

asert (hessian _.rows (==hessian _.cols ) ) ‘ Hessian is not square ‘ );

for(ulongI=0; i size; I ) {

Hessian_(i,I )=currentLambda_;

}

}

3.3求解后,验证该步骤的解是否合适,代码对应衰减因子的更新策略

bool problem :3360 isgoodstepinlm () {

双比例=0;

sale=delta _ x _.transpose (* (current lambda _ * delta _ x _ b _ ) );

scale =1e-3; //make sure it’s non-zero : )

//recomputeresidualsafterupdatestate

//统计所有残差

double tempChi=0.0;

for (自动边缘3360边缘_ ) }

edge.second-ComputeResidual (;

tempChi =edge.second-Chi2(;

}

doublerho=(currentchi_-tempchi )/scale;

射频识别(if )//最后步骤,误差下降

{

doublealpha=1.-pow((2*rho-1 ),3 );

阿尔法=STD:3360min (阿尔法,2./3. );

doublescalefactor=(STD :3360 max ) )1./3 .alpha );

currentLambda_ *=scaleFactor;

ni_=2;

currentChi_=tempChi;

返回真;

} else {

currentLambda_ *=ni_;

ni_ *=2;

返回假;

}

}

Published by

风君子

独自遨游何稽首 揭天掀地慰生平

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注