1. 程式人生 > >【環境配置】Ceres Solver使用

【環境配置】Ceres Solver使用

在之前的文章【環境配置】(四)opencv3中配置sfm模組已經說過如果配置ceres solver,這篇文章主要說下在使用ceres solver的時候遇到的問題。

1、使用ceres solver依賴於gflags,glog, Eigen3以及suitesparse,使用第一步首先要配置好相關的環境,include 和lib input

我的include配置如下:

E:\Opencv3\Ceres_Install\Ceres\include

E:\Opencv3\Ceres_Install\Eigen3\include\eigen3

E:\Opencv3\Ceres_Install\gflags\include

E:\Opencv3\Ceres_Install\glog\include

E:\Opencv3\Ceres_Install\suitesparse\include

lib配置如下:

包含路徑: 

E:\Opencv3\Ceres_Install\suitesparse\lib64\lapack_blas_windows

E:\Opencv3\Ceres_Install\Ceres\lib

E:\Opencv3\Ceres_Install\gflags\lib

E:\Opencv3\Ceres_Install\glog\lib

包含lib名稱:

ceres.lib
gflags_nothreads_static.lib
gflags_static.lib
glog.lib
libblas.lib
liblapack.lib

shlwapi.lib(解決錯誤2加入)

 

以上是release下面的配置,debug模式下面包含路徑已知,lib名稱更換為:

glogd.lib
ceres-debug.lib
gflags_static_debug.lib
gflags_nothreads_static_debug.lib
libblas.lib
liblapack.lib
shlwapi.lib(解決錯誤2加入)

配置中遇到的問題以及解決方法

1、出現錯誤

error LNK2019: unresolved external symbol "__declspec(dllimport) public: __cdecl google::base::CheckOpMessageBuilder::CheckOpMessageBuilder(char const *)" ([email protected]@[email protected]@[email protected]@Z) referenced in function "class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > * __cdecl google::MakeCheckOpString<int,int>(int const &,int const &,char const *)" ([email protected]@[email protected]@[email protected][email protected]@[email protected]@[email protected]@[email protected]@[email protected]@[email protected])

 原因在於報錯資訊是動態連結庫中的函式資訊有誤;

解決方法:在專案->屬性->c/c++->前處理器->前處理器定義中加入GOOGLE_GLOG_DLL_DECL=

參考:Ceres-Solver在VS2017下的配置

在這篇中還提到了與windows.h下定義的ERROR發生了衝突的問題,前處理器加上GLOG_NO_ABBREVIATED_SEVERITIES解決,我沒有遇到這個錯誤。

這個錯誤在於glog使用靜態連結發生的錯誤——

glog如何採用靜態連結的方式呢?答案是要看官方doc文件的說法:在自定義工程中新增“GOOGLE_GLOG_DLL_DECL=” 和 “GLOG_NO_ABBREVIATED_SEVERITIES” 這兩個巨集,第二個巨集主要是為了避免與windows.h衝突(下面會講到),第一個巨集才是使用靜態連結庫時必須的!在編譯時可以編譯兩個版本:Release 和 Debug 以供除錯時使用。

2、出現錯誤:

gflags_nothreads_static.lib(gflags.obj) : error LNK2019: unresolved external symbol __imp_PathMatchSpecA referenced in function "public: class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __cdecl google::`anonymous namespa

上面錯誤是連線gflangs沒有成功——直接#include <gflags/gflags.h>並連結上gflags.lib或gflags_nothreads.lib,應用程式可能並不能連結成功,出現上面的錯誤。解決辦法是在input上加上下面這個lib的宣告:

shlwapi.lib

參考:Google開源命令列引數解析庫gflags

 3、其他類似錯誤的一般處理方式

遇到unresolved external symbol "__declspec(dllimport) public這種錯誤,可能的原因有:

(1)沒有將相應的lib包含進去——檢查lib有沒有包含正確

(2)前處理器需要新增內容處理錯誤——這個錯誤的解決方式我自己找不到,不知道應該新增什麼,一般都是上網找BUILDING_DLL

(3)可能是因為Unicode搞的鬼,Property Page-General-Charater set修改為Not set

(4)關於多執行緒的問題,詳情參考VS2013編譯報錯——error LNK2001: 無法解析的外部符號 __imp_PathMatchSpecA E:\CaffeProgram\3train_mnist(p)\3train_mnist\gflags.lib(gflags.obj) 3train_mnist

錯誤詳情參考:VC6.0 error LNK2001: unresolved external symbol _main解決辦法

參考: 關於error LNK2001: unresolved external symbol "__declspec(dllimport) public

其他:ceres solver使用入門

 參考:一文助你Ceres 入門——Ceres Solver新手向全攻略