Win10+vcpkg+g2o+vs2019配置

Win10+vcpkg+g2o+vs2019配置

参考:
Windows+Visual Studio下生成g2o库教程(结合Cholmod库)

2021.7.13更新:可用.\vcpkg.exe integrate install将下载的库集成到vs的全局环境,这样就不用进行第二步的环境配置了。

**

1. 利用vcpkg下载安装g2o(必须使用最新版本的vcpkg)

**

我的vcpkg版本为2020.11,下载地址:https://github.com/microsoft/vcpkg/releases

直接下载.zip安装包,解压,双击bootstrap-vcpkg.bat,运行结束后出现vcpkg.exe,即可使用。
运行(win+R)->输入cmd,出现
命令行
切换到有vcpkg.exe的目录下
输入命令:vcpkg install g2o:x64-windows

或者打开PowerShell
转换到有vcpkg.exe的目录下
输入命令:\vcpkg.exe install g2o:x64-windows

安装g2o

在安装suitesparse时,可能会出现如下错误

Error : Building package suitesparse:x64-vindows failed vith:BUILD_FAILED

Error : Building package suitesparse:x64-vindows failed vith:BUILD_FAILED
这时,可先用vcpkg安装suitesparse

./vcpkg.exe install suitesparse:x64-windows

安装suitesparse
然后再重复:.\vcpkg.exe install g2o:x64-windows,即可成功。

最后的vcpkg目录如下图所示:
vcpkg目录

**

2. g2o配置

**
参考:【SLAM】SLAM环境配置 Win10+VS2019+OpenCV+PCL+g2o+Vcpkg

利用参考教程的测试代码进行测试。

/**
* BA Example
* Author: Xiang Gao
* Date: 2016.3
* Email: gaoxiang12@mails.tsinghua.edu.cn
*
* 在这个程序中,我们读取两张图像,进行特征匹配。然后根据匹配得到的特征,计算相机运动以及特征点的位置。这是一个典型的Bundle Adjustment,我们用g2o进行优化。
*/
 
// for std
#include <iostream>
// for opencv 
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/features2d/features2d.hpp>
#include <boost/concept_check.hpp>
// for g2o
#include <g2o/core/sparse_optimizer.h>
#include <g2o/core/block_solver.h>
#include <g2o/core/robust_kernel.h>
#include <g2o/core/robust_kernel_impl.h>
#include <g2o/core/optimization_algorithm_levenberg.h>
#include <g2o/solvers/cholmod/linear_solver_cholmod.h>
#include <g2o/types/slam3d/se3quat.h>
#include <g2o/types/sba/types_six_dof_expmap.h>
 
 
using namespace std;
using namespace cv;
 
// 寻找两个图像中的对应点,像素坐标系
// 输入:img1, img2 两张图像
// 输出:points1, points2, 两组对应的2D点
int     findCorrespondingPoints(const cv::Mat& img1, const cv::Mat& img2, vector<cv::Point2f>& points1, vector<cv::Point2f>& points2);
 
// 相机内参
double cx = 325.5;
double cy = 253.5;
double fx = 518.0;
double fy = 519.0;
 
int main()
{
 
	
 
	// 读取图像
	cv::Mat img1 = cv::imread("near.jpg",-1);
	cv::Mat img2 = cv::imread("far.jpg",-1);
 
	// 找到对应点
	vector<cv::Point2f> pts1, pts2;
	if (findCorrespondingPoints(img1, img2, pts1, pts2) == false)
	{
		cout << "匹配点不够!" << endl;
		return 0;
	}
	cout << "找到了" << pts1.size() << "组对应特征点。" << endl;
	// 构造g2o中的图
	// 先构造求解器
	g2o::SparseOptimizer    optimizer;
	// 使用Cholmod中的线性方程求解器
	g2o::BlockSolver_6_3::LinearSolverType* linearSolver = new  g2o::LinearSolverCholmod<g2o::BlockSolver_6_3::PoseMatrixType>();
	// 6*3 的参数
	g2o::BlockSolver_6_3* block_solver = new g2o::BlockSolver_6_3(linearSolver);
	// L-M 下降 
	g2o::OptimizationAlgorithmLevenberg* algorithm = new g2o::OptimizationAlgorithmLevenberg(block_solver);
 
	optimizer.setAlgorithm(algorithm);
	optimizer.setVerbose(false);
 
	// 添加节点
	// 两个位姿节点
	for (int i = 0; i<2; i++)
	{
		g2o::VertexSE3Expmap* v = new g2o::VertexSE3Expmap();
		v->setId(i);
		if (i == 0)
			v->setFixed(true); // 第一个点固定为零
		// 预设值为单位Pose,因为我们不知道任何信息
		v->setEstimate(g2o::SE3Quat());
		optimizer.addVertex(v);
	}
	// 很多个特征点的节点
	// 以第一帧为准
	for (size_t i = 0; i<pts1.size(); i++)
	{
		g2o::VertexSBAPointXYZ* v = new g2o::VertexSBAPointXYZ();
		v->setId(2 + i);
		// 由于深度不知道,只能把深度设置为1了
		double z = 1;
		double x = (pts1[i].x - cx) * z / fx;
		double y = (pts1[i].y - cy) * z / fy;
		v->setMarginalized(true);
		v->setEstimate(Eigen::Vector3d(x, y, z));
		optimizer.addVertex(v);
	}
 
	// 准备相机参数
	g2o::CameraParameters* camera = new g2o::CameraParameters(fx, Eigen::Vector2d(cx, cy), 0);
	camera->setId(0);
	optimizer.addParameter(camera);
 
	// 准备边
	// 第一帧
	vector<g2o::EdgeProjectXYZ2UV*> edges;
	for (size_t i = 0; i<pts1.size(); i++)
	{
		g2o::EdgeProjectXYZ2UV*  edge = new g2o::EdgeProjectXYZ2UV();
		edge->setVertex(0, dynamic_cast<g2o::VertexSBAPointXYZ*>   (optimizer.vertex(i + 2)));
		edge->setVertex(1, dynamic_cast<g2o::VertexSE3Expmap*>     (optimizer.vertex(0)));
		edge->setMeasurement(Eigen::Vector2d(pts1[i].x, pts1[i].y));
		edge->setInformation(Eigen::Matrix2d::Identity());
		edge->setParameterId(0, 0);
		// 核函数
		edge->setRobustKernel(new g2o::RobustKernelHuber());
		optimizer.addEdge(edge);
		edges.push_back(edge);
	}
	// 第二帧
	for (size_t i = 0; i<pts2.size(); i++)
	{
		g2o::EdgeProjectXYZ2UV*  edge = new g2o::EdgeProjectXYZ2UV();
		edge->setVertex(0, dynamic_cast<g2o::VertexSBAPointXYZ*>   (optimizer.vertex(i + 2)));
		edge->setVertex(1, dynamic_cast<g2o::VertexSE3Expmap*>     (optimizer.vertex(1)));
		edge->setMeasurement(Eigen::Vector2d(pts2[i].x, pts2[i].y));
		edge->setInformation(Eigen::Matrix2d::Identity());
		edge->setParameterId(0, 0);
		// 核函数
		edge->setRobustKernel(new g2o::RobustKernelHuber());
		optimizer.addEdge(edge);
		edges.push_back(edge);
	}
 
	cout << "开始优化" << endl;
	optimizer.setVerbose(true);
	optimizer.initializeOptimization();
	optimizer.optimize(10);
	cout << "优化完毕" << endl;
 
	//我们比较关心两帧之间的变换矩阵
	g2o::VertexSE3Expmap* v = dynamic_cast<g2o::VertexSE3Expmap*>(optimizer.vertex(1));
	Eigen::Isometry3d pose = v->estimate();
	cout << "Pose=" << endl << pose.matrix() << endl;
 
	// 以及所有特征点的位置
	for (size_t i = 0; i<pts1.size(); i++)
	{
		g2o::VertexSBAPointXYZ* v = dynamic_cast<g2o::VertexSBAPointXYZ*> (optimizer.vertex(i + 2));
		cout << "vertex id " << i + 2 << ", pos = ";
		Eigen::Vector3d pos = v->estimate();
		cout << pos(0) << "," << pos(1) << "," << pos(2) << endl;
	}
 
	// 估计inlier的个数
	int inliers = 0;
	for (vector<g2o::EdgeProjectXYZ2UV*>::iterator e = edges.begin();e!=edges.end();++e)
	{
        (*e)->computeError();
		// chi2 就是 error*\Omega*error, 如果这个数很大,说明此边的值与其他边很不相符
		if ((*e)->chi2() > 1)
		{
			cout << "error = " << (*e)->chi2() << endl;
		}
		else
		{
			inliers++;
		}
	}
 
	cout << "inliers in total points: " << inliers << "/" << pts1.size() + pts2.size() << endl;
	optimizer.save("ba.g2o");
	std::system("pause");
	return 0;
}
 
 
int     findCorrespondingPoints(const cv::Mat& img1, const cv::Mat& img2, vector<cv::Point2f>& points1, vector<cv::Point2f>& points2)
{
	cv::ORB orb;
	vector<cv::KeyPoint> kp1, kp2;
	cv::Mat desp1, desp2;
	orb(img1, cv::Mat(), kp1, desp1);
	orb(img2, cv::Mat(), kp2, desp2);
	cout << "分别找到了" << kp1.size() << "和" << kp2.size() << "个特征点" << endl;
 
	cv::Ptr<cv::DescriptorMatcher>  matcher = cv::DescriptorMatcher::create("BruteForce-Hamming");
 
	double knn_match_ratio = 0.8;
	vector< vector<cv::DMatch> > matches_knn;
	matcher->knnMatch(desp1, desp2, matches_knn, 2);
	vector< cv::DMatch > matches;
	for (size_t i = 0; i<matches_knn.size(); i++)
	{
		if (matches_knn[i][0].distance < knn_match_ratio * matches_knn[i][1].distance)
			matches.push_back(matches_knn[i][0]);
	}
 
	if (matches.size() <= 20) //匹配点太少
		return false;
 
	for (vector< cv::DMatch >::iterator m = matches.begin();m!=matches.end();++m)
	{
		points1.push_back(kp1[(*m).queryIdx].pt);
		points2.push_back(kp2[(*m).trainIdx].pt);
	}
 
	return true;
}

(1)配置opencv和boost库

网上都有教程,这里不详细解说。我配置的是opencv340 配置opencv库
配置opencv库

以及之前安装pcl时的boost1.64

配置boost库
(2)配置suitesparse和g2o:
配置suitesparse和g2o
在linker->input处添加如下lib
g2o的lib文件
suitesparse的lib文件

g2o_core.lib
g2o_csparse_extension.lib
g2o_ext_freeglut_minimal.lib
g2o_opengl_helper.lib
g2o_solver_cholmod.lib
g2o_solver_csparse.lib
g2o_solver_dense.lib
g2o_solver_eigen.lib
g2o_solver_pcg.lib
g2o_solver_slam2d_linear.lib
g2o_solver_structure_only.lib
g2o_stuff.lib
g2o_types_data.lib
g2o_types_icp.lib
g2o_types_sba.lib
g2o_types_sclam2d.lib
g2o_types_sim3.lib
g2o_types_slam2d.lib
g2o_types_slam2d_addons.lib
g2o_types_slam3d.lib
g2o_types_slam3d_addons.lib

libamd.lib
libbtf.lib
libcamd.lib
libccolamd.lib
libcholmod.lib
libcolamd.lib
libcxsparse.lib
libklu.lib
libldl.lib
libspqr.lib
libumfpack.lib
metis.lib
suitesparseconfig.lib
libblas.lib

**

3. 测试代码改错部分

**

(1)cannot open source file “cholmod.h”
在这里插入图片描述
解决方案:将#include <cholmod.h>改为#include “suitesparse/cholmod.h”

(2)如果你配置的是opencv3及以上的版本,会出现如下错误:object of abstract class type "cv::ORB" is not allowed:
在这里插入图片描述

解决方案:https://www.cnblogs.com/renzmin/articles/12196094.html

在这里插入图片描述
在这里插入图片描述

(3)g2o可能会出现如下错误:no instance of constructor 'g2oRBlockSolver =BlockSolver [with Traits=g2o=BlockSoverTraits 6, 3 ]" matches the argument listno instance of constructor g2o:OptimizationAlgorithmLevenberg:OptimizationAlgorithmLevenberg"matches the argument list

在这里插入图片描述
解决方案如下:

在这里插入图片描述

(4)运行之后若出现:由于找不到xxxx.dll,无法继续执行代码时,在电脑里寻找这个dll文件,复制到C:\Windows\System32路径下

在这里插入图片描述

至此,代码运行成功。
在这里插入图片描述

评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值