win10+VS2017配置sophus

安装配置

去github(https://github.com/strasdat/Sophus)下载对应的zip。注意:视觉SLAM十四讲中提到最早Sophus是非模板类(只有双精度)的版本,后来的版本有了更多不同精度的选择,上面给出的链接是由strasdat维护的Sophus库,最新版本早已经是模板类版本。

书(2017年的)中使用的是非模板类版本a621ff

解压缩zip,使用cmake编译

一般情况下会报错,点击报错那一行最右侧的省略号,手动添加Eigen3的路径

在cmake后的文件夹中找到Sophus.sln,使用VS打开

在VS下调好对应的版本,32还是64,Debug还是Release(32和64没有比较,Debug和Release是一样的),右键ALL_BUILD-生成,再右键INSTALL-生成。然后看控制台输出文件的路径。去那里找到build后的Sophus文件夹

不知道怎么设置的,我的VS将build之后的文件弄到默认工程目录下面去而不是和sln同一目录。不过无所谓,去把它抓回来。

将build生成的Sophus文件夹下的include添加到包含目录:

项目-配置-C/C++-常规-附加包含目录-D:\xx\xx\xx\include

include目录下有一个sophus文件夹,内容如下:

这些hpp文件里同时完成了实现。

用certutil -hashfile命令计算一下hash值,写个批处理分别在Debug和Release生成的目录下跑一遍,其实Debug和Release生成出来都是一样的

 安装和使用过程中的一些问题

1.生成INSTALL时,报错MSB3073 命令setlocal ...balabala

参考(https://blog.csdn.net/u013001137/article/details/107732691

以管理员权限运行VS即可

2.“Eigen::TriangularViewImpl<_MatrixType,_Mode,Eigen::Dense>::_assignProduct:  无法将函数与现有的声明匹配

参考(https://blog.csdn.net/CUSTESC/article/details/104516521

在头文件中,同时include Eigen头文件和using namespace cv就会报该错误。

这里同时让自己意识到了平时编码的不规范,正规来说,using namespace应该放在cpp文件中。以往头文件我都是这么写的

#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

void test(Mat m,string str);

当将using namespace cv移动到cpp文件中后,上面头文件中的参数部分Mat和string就会报错,就需要改成

#include <opencv2/opencv.hpp>

void test(cv::Mat m,std::string str);

这也是为什么我们在调用库函数的时候能看到每个参数的命名空间

3.在将一个旋转矩阵转换成李代数时弹出了错误

RR的类型是Mat_<double>

Eigen::Matrix3d Rvec;

Rvec <<
	RR.at<double>(0, 0), RR.at<double>(0, 1), RR.at<double>(0, 2),
	RR.at<double>(1, 0), RR.at<double>(1, 1), RR.at<double>(1, 2),
	RR.at<double>(2, 0), RR.at<double>(2, 1), RR.at<double>(2, 2);

Sophus::SO3<double> SO3_R(R);

 提示我输入的矩阵R不是正交矩阵,还帮我输出了RR^T的结果。显然是精度的问题。

自己计算一下RR^T

只需降低精度,由double换成float即可

Eigen::Matrix3f Rvec;

Rvec <<
	(float)RR.at<double>(0, 0), (float)RR.at<double>(0, 1), (float)RR.at<double>(0, 2),
	(float)RR.at<double>(1, 0), (float)RR.at<double>(1, 1), (float)RR.at<double>(1, 2),
	(float)RR.at<double>(2, 0), (float)RR.at<double>(2, 1), (float)RR.at<double>(2, 2);

Sophus::SO3<float> SO3_R(Rvec);

4.Eigen和Opencv矩阵转换问题

像上面那样一位一位地将矩阵元素填入虽然能实现转换,但是也太麻烦了。就想着有没有简单的方法能够实现Eigen和Opencv的矩阵转换。

参考(https://humfrey.blog.csdn.net/article/details/107387479

有函数cv2eigen和eigen2cv来进行Eigen和opencv的矩阵类型转换

所需头文件

#include <Eigen/Core>
#include <Eigen/Dense>
#include <opencv2/core/eigen.hpp>
#include <opencv2/opencv.hpp>

例如上面3中旋转矩阵RR到R的转换,就可以从

Eigen::Matrix3f Rvec;
Rvec <<
	(float)RR.at<double>(0, 0), (float)RR.at<double>(0, 1), (float)RR.at<double>(0, 2),
	(float)RR.at<double>(1, 0), (float)RR.at<double>(1, 1), (float)RR.at<double>(1, 2),
	(float)RR.at<double>(2, 0), (float)RR.at<double>(2, 1), (float)RR.at<double>(2, 2);

替换成

Eigen::Matrix3f R;
cv::cv2eigen(RR, R);

想要转换回去

cv::eigen2cv(R, RR);

 sophus的一个李代数转换过程

Eigen::Matrix3f R;
Sophus::SO3<datatype> SO3_R(R);//旋转矩阵构造SO3
Eigen::Vector3f so3 = SO3_R.log();//对数映射,得到对应李代数
Sophus::SO3<float> SO3_R2 = Sophus::SO3f::exp(so3);//指数映射,李代数到旋转矩阵
Eigen::Matrix<float, 3, 3> m = SO3_R2.matrix();//Sophus的SO3到Eigen的矩阵
cv::eigen2cv(m, RR);

 

©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页