#include <iostream>
using namespace std;
//#include <chrono>
#include <opencv2/core/core.hpp>
#include <ceres/ceres.h>
struct CURVE_FITTING_COST
{
CURVE_FITTING_COST(double x,double y): _x(x),_y(y){};
template <typename T>
bool operator () (const T* const abc,T*residual) const
{
residual[0]=T(_y)-ceres::exp(abc[0]*T(_x)*T(_x)+abc[1]*T(_x)+abc[2]);//计算残差
return true;
}
const double _x,_y;
};
int main(int argc, char **argv)
{
/*y=exp(ax^2+bx+c)+w w是高斯白噪声 目标是根据(x,y)数据拟合a,b,c参数*/
double a=1.0,b=2.0,c=1.0;
int N=100;//取100个点
double w_sigma=1;// w的sigma值
cv::RNG rng;//产生随机数
double abc[3]={0,0,0};//a,b,c估值
vector<double> x_data,y_data;
cout<<"产生数据中..."<<endl;
for(int i=0;i<N;i++){
double x=i/100.0;//注意类型
x_data.push_back(x);
y_data.push_back(exp(a*x*x+b*x+c)+rng.gaussian(w_sigma));
}
//构建最小二乘模型
ceres::Problem pro;
for(int i=0;i<N;i++){
pro.AddResidualBlock(new ceres::AutoDiffCostFunction<CURVE_FITTING_COST,1,3>(new CURVE_FITTING_COST(x_data[i],y_data[i]))
,nullptr//核函数
,abc);//待估计参数
}
//配置求解器
ceres::Solver::Options op;//这里面有很多配置项可以填
op.linear_solver_type=ceres::DENSE_QR;//增量方程如何求解
op.minimizer_progress_to_stdout =true;//输出到cout
ceres::Solver::Summary summary;
ceres::Solve(op,&pro,&summary);
//输出结果
cout<<summary.BriefReport()<<endl;
cout<<"估计的a,b,c=";
for( auto a:abc )cout<<a<<" ";
cout<<endl;
return 0;
}
ceres库最小二乘问题求解---参考SLAM十四讲6.3
最新推荐文章于 2022-09-25 16:58:42 发布