Ceres-solver简介及Windows 配置

Windows 下 配置 Ceres-solver (Visual Studio)

本文介绍内容: 在windows Visual Studio 上配置 Ceres-solver

  • Ceres-solver简介
  • 本文重点
  • 安装必备及下载
  • 安装步骤
  • 测试与使用
  • 参考资源

Ceres-solver简介

Ceres Solver是由Google开发的非线性最小二乘问题求解工具包, 
被用于Google产品多年,强大、快速、稳定并受到持续的开发支持。 
更多特性参见官网Features介绍栏 [Ceres官网 ]

安装Ceres前,最好对优化问题,优化过程,非线性最小二乘优化问题有大概了解。 
可参见Ceres官网或最优化算法相关的书(推荐一本用过的 Numerical Optimization)

本文重点

Ceres官网给出了 Linux Windows Android 等系统的安装配置教程但由于种种原因, 
Ceres在windows(Visual Studio)下的安装不能很好的加入Suitesparse(可看做一个扩展包)。 
本文重点是在官网教程基础上,尝试加入Suitesparse。不需要Suitesparse的按官网步骤即可。

配置必备及下载

如想在VS环境下使用,也建议对VS的 静态链接、动态dll,debug、release,32、64等配置有所了解。 
配置不当,可能无法生成或使用,不同的配置,生成的ceres库也不同。

日期及环境

日期2015年5月: 
环境:64位 win8.1 联想y430p VisualStudio(简称VS) 2013

配置工具cmake

windows VS下Ceres的安装可用别人以cmake工具生成的Ceres.sln工程文件 
这比较简单,但失去了配置的灵活性,无法扩展,甚至可能因为环境、版本等的不同而失效。 
所以配置Ceres最好的方法是使用cmake工具生成自己的Ceres.sln。 
CMake是一个跨平台的安装(编译)工具,可以用简单的语句来描述所有平台的安装(编译过程)。 
对cmake的学习是一劳永逸的,许多优秀的算法包库都可以而且也推荐用cmake编译生成。

ceres的组成

ceres必备工具包、库:eigen glog (gflags)

ceres还可安装这些可选的工具,来为其提速或满足特殊需求: 
BLAS,LAPACK,SuiteSparse,CXsparse(SuiteSparse又需要LAPACK,LAPACK貌似又需要BLAS)

上述所有工具皆可单独配置使用 
其中BLAS LAPACK Eigen SuiteSparse 是一系列数学算法库,侧重针对线性代数、矩阵计算。 
SuiteSparse针对稀疏矩阵计算,目前很难在windows下配置, 
本文重点即在于尝试将其包含进ceres中。 
CXsparse是SuiteSparse的一个简化版本,不需BLAS和LAPACK。 
Gflags是一个开源的处理命令行参数的库,使用c++开发,具备python接口,可以替代getopt。 
Glog是一个C++语言的应用级日志记录框架,提供了C++风格的流操作和各种助手宏。

这里写图片描述

下载地址

必备: 
cmake 
ceres源文件 
eigen 
glog 
gflags 
最新的gflags可能没有sln文件,附一旧版

可选: 
BLAS LAPACK 
LAPACK对windows 
SuiteSparse-github-windows: 含sln文件的SuiteSparse版本 
SuiteSparse官网,源代码,建议使用上面github的 
CXsparse

总之,编译ceres-solver必须配置eigen、gflags和glog三个库,在此基础上 
用cmake编译生成ceres.sln工程文件,再由ceres.sln生成C++可调用的ceres.lib。 
最终在c++项目里,通过配置好ceres的头文件,调用ceres.lib来”使用”ceres。


安装步骤 (含suitesparse:

前期准备

  • 建立一个目录,如D:\mathlib\ceres
  • 将下载并解压后的eigen,glog,gflags,ceres,suitesparse,CXsparse …等文件放到该\ceres目录下
  • 安装cmake,我这里下载的cmake是cmake-3.2.2-win32-x86版本,绿色,解压后可直接使用。 
    cmake文件可放到\ceres下,也可放到别处。考虑以后make别的库的时候使用,我这里放到别处, 
    如D:\tools\cmake-3.2.2-win32-x86
  • eigen不需生成后面直接用
  • 用sln文件生成glog,gflags: 
    用VS分别打开glog和gflags的sln工程文件,点生成(菜单栏或右键项目文件)。 
    对不同的配置:32/64位,debug/release,dll/static 可生成共八个不同版本,这里以32,release,dll为例。
  • 生成suitesparse(需用cmake): 
    这里下载suitesparse包,按照它给出的教程配置好suitesparse,过程与上面类似,大致如下: 
    用cmake生成sln,再用sln生成lib,最后测试一下好使不。 
    不想测试的可略过这个括号( 使用它这里的example-projects测试suitesparse时需要输入矩阵,这个 
    可参见我在其github下的issue:suitesparse testing-read a sparse matrix,how?
  • 其实最终要的就是glog,gflags,suitesparse生成的include和lib 
    include包含头文件,即对各功能的声明,而功能的定义、实体,封装在静态库lib,或配合dll使用的lib里。 
    所以把这些include和lib汇到一起放到一个大文件夹下可能比较方便,但为使结构清晰, 
    方便分别调用,这里暂时仍置于各自文件夹下。

初步配置cmake

  • 以上准备工作做完,材料就准备好了,这时开始用cmake像make suitesparse那样来make ceres的sln
  • 打开…\cmake-3.2.2-win32-x86\bin 的 cmake-gui.exe
  • 点browse sourse:源文件位置在哪,当然就是下载的ceres文件,我这里是1.10.0, 
    如D:\mathlib\ceres\ceres-solver-1.10.0
  • 点browse build:生成的sln放到哪,我选择放在\ceres下,新建一个ceres_build 如果还有32,64 debug 
    release的考虑,那么再分别建四个文件夹32debug、32release、64debug、64release 
    用以输出不同的版本。如果不需要这么多,就建一个,选择32release为例, 
    最终结果如D:\mathlib\ceres\ceres_build\32release
  • 点configue按键进行配置,这时肯定会配置不成功,一些选项会变红, 这时需要对每一项进行配置,直到配置成功。
  • 首先最简单的 对EIGEN_INCLUDE_DIR项,配置好eigen的位置,这里是D:/mathlib/ceres/eigen。 
    注意cmake中路径的\与windows的/不同 这时eigen就配置好了,然后点一下configre进行后续配置。
配置suitesparse

如果不配置suitesparse ,跳过这一步,但这是本文的重点,也只是试验,目前没有别的好办法。

原理: 
注意,这里seres的这些配置项,来自于源文件中的CMakeLists.txt 
即 按我的路径 D:\mathlib\ceres\ceres-solver-1.10.0\CMakeLists.txt 
cmake通过这个CMakeListslists配合D:\mathlib\ceres\ceres-solver-1.10.0\cmake下的各个.cmake和.in文件 
来对ceres进行配置,查找ceres需要的各个组件并定义如何生成ceres。 
而要想配置suitesparse,按目前版本的CMakeLists,必须先配置好blas和lapack才可以配置suitesparse, 
查找blas和lapack需要通过find_package命令结合findblas.cmake和findlapack.cmake来配置,这很麻烦。 
以至于我选择绕开它或者说屏蔽它,当然有能力的可以找到或自己写findblas.cmake,findlapack.cmake。 
我这里通过修改CMakeListslists和findsuitesparse.cmake,屏蔽对blas和lapack的搜索, 
从而直接配置suitesparse,最后在使用ceres的时候,再链接上所需的blas和lapack的lib和dll。 
修改部分如下: 
对CMakeLists.txt,用VS打开,通过搜索找到以下内容:

<code class="language-cmake hljs  has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">OPTION</span>(CUSTOM_BLAS
       <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Use handcoded BLAS routines (usually faster) instead of Eigen."</span>
       <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">OFF</span>)  <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"># ON改为OFF</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">OPTION</span>(LAPACK <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Enable use of LAPACK."</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">OFF</span>)     <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"># ON改为OFF</span>
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"># SuiteSparse.</span>
...
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#将 IF (SUITESPARSE AND NOT LAPACK) 一直到 ENDIF (SUITESPARSE AND NOT LAPACK) </span>
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"># 的内容全部用#注释掉</span>
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#IF (SUITESPARSE AND NOT LAPACK)</span>
  <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"># If user has disabled LAPACK, but left SUITESPARSE ON, turn it OFF,</span>
  <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"># LAPACK controls whether Ceres will be linked, directly or indirectly</span>
  <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"># via SuiteSparse to LAPACK.</span>
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#  MESSAGE("-- Disabling SuiteSparse as use of LAPACK has been disabled, "</span>
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#    "turn ON LAPACK to enable (optional) building with SuiteSparse.")</span>
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#  UPDATE_CACHE_VARIABLE(SUITESPARSE OFF)</span>
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#ENDIF (SUITESPARSE AND NOT LAPACK)</span>
</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li></ul>

(可选)将IF (LAPACK)到ENDIF (LAPACK)的内容也注释掉,虽然前面改为OFF后,这部分其实就没用了 
这里为保险起见也注释掉了。

对FindSuiteSparse.cmake(这个文件在ceres-solver-1.10.0\cmake文件夹下), 
VS打开,类似上面,搜索BLAS,LAPACK,注释掉# BLAS. 和 # LAPACK.对应部分的内容, 
(可选)同样保险起见,搜索并注释掉 ${BLAS_LIBRARIES}) , 
如果注释了这里记得把最后面的右括号放到下一行,不然括号也会被注释掉导致cmake不能正常工作。 
修改完保存一下,再点configure,当然这些改动也可在打开cmake-gui.exe前就弄好。 
这些步骤无非就是把对lapack和blas的搜索通过注释屏蔽掉,从而直接安装suitesparse。 
(注:也可以通过自己写一个findsuitesparse.cmake来提前将blas和lapack配置进来 
上面的suitesparse-metis-for-windows其实就有一个,但是我修改半天没能成功于是放弃。)

继续配置cmake

继续进行各项配置,将grouped和advanced打上勾,可以看到这些选项被编组,还多出一些选项。 
对GLOG GFLAGS分别将之前编译生成的include和lib对应好,如图 
 
对AMD CAMD CCOLAMD CHOLAMD COLAMD CXSPARSEE SUITESPARSE SUITESPARSEQR 
这些都是suitesparse的组成部分,设置类似,都是: 
将对应的include路径和lib文件设置好,如图以camd和ccolamd为例,其余设置类似。 
 
对于ungrouped Entries,BUILD,CMAKE 项,如图, 
 
 
 
勾上 GFLAGS SUITESPARSE OPENMP SCHUR_SPECIALIZATIONS 
建议不勾 BUILDING_TESTING. 会省去很多麻烦。可以用example来test 
CMAKE_BUILD_TYPE如果是release就写Release,如果是debug就写Debug。 
如果想把ceres build成一个dll,可以勾上BUILD_SHARED_LIBS

如果更懂cmake,可以通过设置环境变量,自动让cmake找到上面设置的include和lib 
每次configure时检查一下suitesparse,glog,gflags是否勾上 
(因为每次configure可能会由于找不到相应部件而自动取消掉一些项的勾选)

最终configure完,会显示configure done 然后点击generate,这样ceres.sln项目工程就生成了。


生成ceres

最后,在之前设置的输出目录ceres_build/32release下用VS打开生成的ceres.sln文件 
这里写图片描述

可以看到有很多解决方案,除了ceres其他都是例子,通过一些配置后,就可以生成最终结果了。 
可以先生成ceres,再生成其他的例子,也可以直接生成所有(菜单栏-生成-生成解决方案). 
这里选择先生成ceres,注意在生成ceres时,为防止gflog与windows对 GDI调用时对error设置的冲突, 
可以用预处理器解决,参见官网说明,方法是:在右键ceres 属性-配置属性-C/C++ -预处理器(Preprocessor)-预处理器定义处, 
加上GLOG_NO_ABBREVIATED_SEVERITIES,注意不要把原来这里有的定义弄没了。 
这里写图片描述


测试与使用

生成完ceres后,配置并生成其他例子,用以测试: 
如对bundle_adjuster,右键-属性-链接器-输入-附加依赖项 
这里加入生成suitesarse时附带的libblas.lib和liblapack.lib,建议使用绝对路径,如 
D:\mathlib\ceres\suitesparse\lapack_windows\x32\libblas.lib; 
D:\mathlib\ceres\suitesparse\lapack_windows\x32\liblapack.lib;其他例子配置相同,加上这两个lib。 
生成好后还有重要的一步,就是把之前的所有dll文件(分别来自suitesparse的lapack_windows、glag、glog文件下) 
放到要运行的例子.exe所在的文件夹(这里是在…\32release\bin\release)下,全部dll文件如图: 
这里写图片描述 
运行这些例子,如helloworld.exe,powell.exe 对例子的介绍见官网

注意要想看结果通常要在cmd下运行,参考步骤如下(这里build文件名略有不同,对应好即可)

<code class="language-cmd hljs r has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">d:  
cd D:\mathlib\ceres\ceres_build\32release\bin\Release 
helloworld
powell
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span>  </code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li></ul>

这里写图片描述 
最终会看到convergence,收敛,证明成功了。 
由于都是dense的没有sparse的例子,suitesparse的调用需进一步验证。

在自己的项目中使用ceres,类似上面只需把头文件加进来,把ceres.lib即需要的dll设置好 
当然要怎么构造problem还需进一步学习ceres,参见官网对API的使用的介绍。


说明,本文只为ceres配置学习进行交流,不用于其他目的,除小部分参考博客和官网内容,其他均为原创。 
对于所参考的内容,如原作者不同意使用,请告知,将及时去掉,在此表示感谢。


参考

附一些资源以供参考,学习:

ceres基本配置(不含suitesparse) 
http://www.csdn123.com/html/blogs/20131113/95976.htm 
http://www.grandmaster.nu/blog/?page_id=628 
github上的ceres.sln: 
https://github.com/tbennun/ceres-windows

cmake简介: 
http://www.cnblogs.com/coderfenghc/archive/2013/01/20/2846621.html 
http://www.cmake.org/ 官网

eigen及配置简介: 
http://blog.csdn.net/abcjennifer/article/details/7781936

glog简介: 
http://blog.csdn.net/netlinux/article/details/6700549 
http://www.cnblogs.com/foreveryl/archive/2011/10/14/2212265.html 
gflags简介: 
http://blog.chinaunix.net/uid-20196318-id-3440642.html 
http://blog.csdn.net/lezardfu/article/details/23753741

静态和动态链接: 
http://blog.csdn.net/jewes/article/details/8765745 
http://www.cnblogs.com/kex1n/archive/2011/09/06/2168435.html

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值