Ubuntu16.04上配置安装ceres

这篇博客主要介绍如何配置ceres库并通过使用ceres库拟合一条曲线来介绍ceres库的简单使用

参考了以下博客:

https://blog.csdn.net/weixin_39373577/article/details/81285420

一、安装依赖项
sudo apt-get install liblapack-dev 
sudo apt-get install libsuitesparse-dev 
sudo apt-get install libcxsparse3.1.2 
sudo apt-get install libgflags-dev 
sudo apt-get install libgoogle-glog-dev libgtest-dev
做以下说明:
  • 在Ubuntu16.04上应该没有cxsparse3.1.2这个包,应该安装cxsparse3.1.4
  • 安装速度可能会非常的慢,这里来个小插曲,说一下如何修改软件源为中科大的源,速度非常快
  • 修改/etc/apt/sources.list中的内容为(修改前最好先把该文件复制一份):
deb http://mirrors.ustc.edu.cn/ubuntu/ xenial main restricted universe multiverse
deb http://mirrors.ustc.edu.cn/ubuntu/ xenial-security main restricted universe multiverse
deb http://mirrors.ustc.edu.cn/ubuntu/ xenial-updates main restricted universe multiverse
deb http://mirrors.ustc.edu.cn/ubuntu/ xenial-proposed main restricted universe multiverse
deb http://mirrors.ustc.edu.cn/ubuntu/ xenial-backports main restricted universe multiverse
deb-src http://mirrors.ustc.edu.cn/ubuntu/ xenial main restricted universe multiverse
deb-src http://mirrors.ustc.edu.cn/ubuntu/ xenial-security main restricted universe multiverse
deb-src http://mirrors.ustc.edu.cn/ubuntu/ xenial-updates main restricted universe multiverse
deb-src http://mirrors.ustc.edu.cn/ubuntu/ xenial-proposed main restricted universe multiverse
deb-src http://mirrors.ustc.edu.cn/ubuntu/ xenial-backports main restricted universe multiverse
  • 更新sudo apt-get update
二、编译ceres

下载地址:https://github.com/ceres-solver/ceres-solver

  • 解压,并cd到ceres根目录下
mkdir build
cd build
cmake ..
sudo make install
  • 安装完成后,ceres头文件目录为/usr/local/include/ceres、库文件为/usr/local/lib/libceres.a,可以自己检查一下
三、使用ceres拟合一条二次曲线

这里简单的介绍一下思路,下一篇博客会详细的介绍一下两种梯度下降方法。
假设有一条曲线满足如下方程: y = e x p ( a x 2 + b x + c ) + w y=exp(ax^2+bx+c)+w
其中, a , b , c a,b,c 为曲线的参数, w w 为高斯噪声。
如果我们有N对点(x, y),我们要根据这些点求出曲线的参数,那么问题可以转换为下面的优化问题: m i n a , b , c 1 2 i = 1 N y i e x p ( a x i 2 + b x i + c ) 2 min_{a,b,c}\frac{1}{2}\sum_{i=1}^{N}\begin{Vmatrix}y_i-exp(ax_i^2+bx_i+c)\end{Vmatrix}^2 在上式中,待估计的变量是 a , b , c a,b,c

程序:
#include <iostream>
#include <opencv2\core\core.hpp>
#include <ceres\ceres.h>
#include <chrono>

using namespace std;

//代价函数的计算模型
struct CURVE_FITTING_COST
{
	const double _x, _y;

	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(_y) + abc[2]);
		return 0;
	}
};

int main(int argc, char *argv[]) {
	double a = 1.0, b = 2.0, c = 1.0;
	int N = 100;
	double w_sigma = 1.0;
	cv::RNG rng;
	double abc[3] = { 0,0,0 };

	vector<double> x_data, y_data;

	cout << "generating data: " << 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));

		cout << x_data[i] << " " << y_data[i] << endl;
	}

	//构建最小二乘问题
	ceres::Problem problem;
	for (int i = 0; i < N; i++) {
		problem.AddResidualBlock(
			new ceres::AutoDiffCostFunction<CURVE_FITTING_COST, 1, 3>(
				new CURVE_FITTING_COST(x_data[i], y_data[i])
				),
			nullptr,
			abc
		);
	}

	//配置求解器
	ceres::Solver::Options options;
	options.linear_solver_type = ceres::DENSE_SCHUR;
	options.minimizer_progress_to_stdout = true;

	ceres::Solver::Summary summary;
	chrono::steady_clock::time_point t1 = chrono::steady_clock::now();
	ceres::Solve(options, &problem, &summary);
	chrono::steady_clock::time_point t2 = chrono::steady_clock::now();

	chrono::duration<double> time_used = chrono::duration_cast<chrono::duration<double>>(t2 - t1);
	cout << "solve time cost = " << time_used.count() << " seconds. " << endl;

	//输出结果
	cout << summary.BriefReport() << endl;
	cout << "estimated a, b, c = ";
	for (auto a : abc)
		cout << a << " ";
	cout << endl;

	return 0;
}

CMakeLists.txt的内容如下:

cmake_minimum_required( VERSION 2.8 )
project( ceres_curve_fitting )

set( CMAKE_BUILD_TYPE "Release" )
set( CMAKE_CXX_FLAGS "-std=c++11 -O3" )

# 寻找Ceres库并添加它的头文件
find_package( Ceres REQUIRED )
include_directories( ${CERES_INCLUDE_DIRS} )

# OpenCV
find_package( OpenCV REQUIRED )
include_directories( ${OpenCV_DIRS} )

add_executable( curve_fitting main.cpp )
# 与Ceres和OpenCV链接
target_link_libraries( curve_fitting ${CERES_LIBRARIES} ${OpenCV_LIBS} )

然后编译链接很简单,就不说了。运行结果如下:
曲线拟合结果
有兴趣的,可以自己把曲线画出来,形象的看一下拟合结果。

发布了47 篇原创文章 · 获赞 23 · 访问量 8万+

猜你喜欢

转载自blog.csdn.net/llfjcmx/article/details/88831384