如何在Mac下安装Ceres库并在Cmake中配置

如何在Mac下安装多线程版Ceres库并通过cmake配置调用

  • 前言
    • 什么是Ceres
    • 如何通过homebrew安装Ceres库(无多线程)
    • 如何通过cmake安装Ceres库(TBB版多线程加速)
    • 如何在cmake中配置Ceres第三方库

前言

上次写博客还是高中时候,那时候会在qq空间写些随想,这么多年过去了,如今再开始写博客还有些小激动哈哈。头一次写技术博客,也不知道会不会有人来看,全当记录自己走过的一些坑,如果恰好能够帮助到一些有需要的人也是极好的。

最近由于项目需求,需要使用第三方Ceres库来求解一些定义的约束问题。头一次接触Ceres库,期间着实踩了很多坑。本文接下来将逐步阐释如何在Mac下安装,以及如何在Cmake配置文件中配置Ceres库。最后会展示出一个调用Ceres的完整Demo。
后续我会写一篇如何在Android平台下编译Ceres库的教程,网上关于Android平台下Ceres库配置真的很少,官网也是简单提了一下没有很详细的说明。

什么是Ceres

想一个很简单的问题,我们定义一个函数y = wx + b,同时有很多组数据(x=1, y=2) (x=2, y=4)等等,我们希望求解w b来使得函数可以很好地拟合这组数据,如何来求解呢。Ceres就可以用来帮助我们求解这样一个问题,我们只需要定义好输入数据和待求量以及损失函数,Ceres就可以帮我求解了。
当然Ceres的用处远不止于次,可以用来迭代求解一些很复杂带有边界约束的非线性问题。Ceres库于2014年被谷歌开源,目前在计算机视觉领域(slam等)有着很广泛的应用。
官方网站在这里,里面有很详细的用法描述。如果碰到问题也可以在github社区参与讨论。

如何通过homebrew安装Ceres库(无多线程)

那么如何安装Ceres库为我们所用,其实官网已经说得很明确了,这里只是照搬一下过程。
用mac的小伙伴都知道mac有一个神器–HomeBrew,有了它在mac下一键安装各种(opencv等)不再是问题!没有homebrew的小伙伴直接在百度搜homebrew安装即可。
同样,对于我们的主角Ceres也是如此,用homebrew可以一键搞定。只需要打开终端,输入brew install ceres-solver即可。Mac会自动帮我们安装好Ceres以及它所依赖的第三方库(glog、eigen、suite-sparse)。
如果不确定自己是否已经完全安装了Ceres依赖的第三方库,可以依次在终端输入
brew install glog
brew install eigen
brew install suite-sparse
正常所有依赖库都应该显示如下的提示,这表明依赖库已经安装了,如果没有下面提示则会自动安装。

Warning: suite-sparse 5.3.0_1 is already installed and up-to-date
To reinstall 5.3.0_1, run `brew reinstall suite-sparse`

等待这些四个库都安装完成后,在mac/usr/local/Cellar目录下,会生成这几个库文件夹。大功告成

如何通过cmake安装Ceres库(TBB版多线程加速)

通过上一节安装教程后,我们已经可以调用Ceres库了,不过不能多线程加速。如果想要多线程加速的话,这里我们不能通过homebrew来一键安装,需要自己手动通过cmake来开启多线程选项并编译源码。
1.首先我们需要在Ceres官方github上下载Ceres的源码包并解压到某一路径下。以下是我解压的示例,正常除了ceres-bin这个文件夹是我自己创建的以外,其他文件夹应该都是有的。
如何在Mac下安装Ceres库并在Cmake中配置_第1张图片
2.通过homebrew安装第三方依赖的库。
brew install glog
brew install eigen
brew install suite-sparse
由于需要多线程,所以还需要安装额外的第三方多线程库。官方给出了3种加速方式:TBB OPENMPCXX11_THREADS。这里只讲如何安装附带TBB的Ceres库。
同样需要通过brew来安装TBB
brew install TBB
3.准备工作都已做好,接下来就需要通过cmake来编译了。
首先在编译之前,我们需要修改CMakeLists.txt,这是因为CMakeLists.txt中把多线程的选项默认关了…
打开CMakeLists.txt,找到115行 122行,原来红框的部分都是OFF的,把这两个地方现在都换成ON。
如何在Mac下安装Ceres库并在Cmake中配置_第2张图片
4.打开终端,并切换目录到ceres源码的根目录下。
然后依次运行
mkdir ceres-bin
cd ceres-bin
如上面CMakeLists.txt所示,我们需要再编译中把CXX11设置成ONOPENMP CXX11_THREADS都设成OFF,只有这样TBB才会默认开启。
cmake -DCXX11=ON -DOPENMP=OFF -DCXX11_THREADS=OFF ..
make -j3
make install
大功告成!这波操作后ceres就会安装到mac系统当中,与上一节homebrew的效果是一样的,只不过多了多线程TBB的支持。

如何在cmake中配置Ceres第三方库

安装完Ceres库后,接下来我们展示如何通过调用Ceres。
首先我们建立一个testCeres.cpp,并贴上一段谷歌ceres给的官方调用示例。顺便说一下,谷歌提供了大量的调用示例,各种case讲的还是挺详细的。
下面代码来自于示例网站中的helloworld.cc,主要干的事情就是采用双线程迭代求x,使得0.5 (10-x)^2的损失loss最小,划重点平方,不是10-x,ceres内部是有平方运算的,千万不要定义错了。

#include "ceres/ceres.h"
#include "glog/logging.h"

using ceres::AutoDiffCostFunction;
using ceres::CostFunction;
using ceres::Problem;
using ceres::Solver;
using ceres::Solve;

// A templated cost functor that implements the residual r = 10 -
// x. The method operator() is templated so that we can then use an
// automatic differentiation wrapper around it to generate its
// derivatives.
struct CostFunctor {
  template <typename T> bool operator()(const T* const x, T* residual) const {
    residual[0] = 10.0 - x[0];
    return true;
  }
};

int main(int argc, char** argv) {
  google::InitGoogleLogging(argv[0]);

  // The variable to solve for with its initial value. It will be
  // mutated in place by the solver.
  double x = 0.5;
  const double initial_x = x;

  // Build the problem.
  Problem problem;

  // Set up the only cost function (also known as residual). This uses
  // auto-differentiation to obtain the derivative (jacobian).
  CostFunction* cost_function =
      new AutoDiffCostFunction<CostFunctor, 1, 1>(new CostFunctor);
  problem.AddResidualBlock(cost_function, NULL, &x);

  // Run the solver!
  Solver::Options options;
  options.num_threads = 2;
  options.minimizer_progress_to_stdout = true;
  Solver::Summary summary;
  Solve(options, &problem, &summary);

  std::cout << summary.BriefReport() << "\n";
  std::cout << "x : " << initial_x
            << " -> " << x << "\n";
  return 0;
}

如果通过cmake来执行的话是编不过的,这是因为没有引入Ceres的库路径和头文件路径以及它所依赖的第三方库相关信息。所以接下来我会贴上如何在CMakeLists.txt中写入有关ceres的所有配置。
同样,ceres官网上已经做了很明确的说明,对于本博客讲述不清楚的地方可以参考官网Installation的Using Ceres with Cmake部分。

cmake_minimum_required(VERSION 3.10)

set(LIBRARY_NAME TESTCeres)
project(${LIBRARY_NAME})

set(CMAKE_CXX_STANDARD 11)

# ceres module
FIND_PACKAGE(ceres REQUIRED)
# Eigen module
INCLUDE_DIRECTORIES(${EIGEN_INCLUDE_DIR})

# 搜集testCeres.cpp源码文件
file(GLOB SRC your/path/to/testCeres.cpp)
set(SOURCE_FILES ${SRC})

add_executable(${LIBRARY_NAME} ${SOURCE_FILES})

target_link_libraries(${LIBRARY_NAME}
                      ceres
                      )

很简洁的CMakeLists.txt配置,利用FIND_PACKAGE找到ceres的依赖包,再INCLUDE_DIRECTORIES包含下EIGEN的系统路径就可以了。这些都归功于homebrew,它直接把这些包的路径帮我们捋顺好了。
安装好Ceres库以及相应的第三方库,编写好cmakelists配置文件后,就可以运行看效果啦。

在CMakeLists.txt 同目录下输入如下命令
mkdir cmake_build
cd cmake_build
cmake ..
make
./TESTCeres

最终如果看到如下的log说明Ceres配置成功并可以开心地使用啦。

Scanning dependencies of target TESTCeres
[ 50%] Building CXX object CMakeFiles/TESTCeres.dir/Users/subowen/Project/MTWideAngleUnDistortion/test/testCeres.cpp.o
[100%] Linking CXX executable TESTCeres
[100%] Built target TESTCeres
iter      cost      cost_change  |gradient|   |step|    tr_ratio  tr_radius  ls_iter  iter_time  total_time
   0  4.512500e+01    0.00e+00    9.50e+00   0.00e+00   0.00e+00  1.00e+04        0    6.51e-05    3.26e-04
   1  4.511598e-07    4.51e+01    9.50e-04   9.50e+00   1.00e+00  3.00e+04        1    1.07e-03    1.45e-03
   2  5.012552e-16    4.51e-07    3.17e-08   9.50e-04   1.00e+00  9.00e+04        1    2.48e-05    1.49e-03
Ceres Solver Report: Iterations: 3, Initial cost: 4.512500e+01, Final cost: 5.012552e-16, Termination: CONVERGENCE
x : 0.5 -> 10

你可能感兴趣的:(Ceres相关)