【记录】PCL 1.11.1+VS2019+Super4PCS复现的相关配置操作流程

课题研究需要super4pcs算法复现,网上找了一轮发现大部分是基于Ubuntu系统的复现,csdn上一位博主做了在vs2019上复现super4pcs的工作:

点云全局配准复现——Super4pcs实现_小修勾的博客-CSDN博客

写的很详细,但是最后一些地方讲的不是很清楚,这里我也是花了一些功夫才最终成功,这里主要根据是上面这篇博客,写一篇文章记录下来,对这个复现工作做一个补充整合。

1.需要:

(1)VS2019(别的版本没有用过)

(2)PCL1.11.1

(3)cmake 3.24

关于如何安装配置vs2019以及PCL1.11.1,网站上有很多详细教程在此不再赘述。

cmake安装可参考以下这位博主的文章:

Windows下Cmake安装步骤详解(图文)_L_Li_L的博客-CSDN博客_windows安装cmake

2.super4pcs复现

(1)相关原代码:

super4pcs原有的github目前已经不再维护了,原作者将super4pcs的内容与PCL等库做了结合,命名为OpenGR,github地址如下:

GitHub - STORM-IRIT/OpenGR: OpenGR: A C++ library for 3D Global Registration

(2)主要流程

①下载源码

首先在上面的github地址中下载源码的zip文件,解压

【记录】PCL 1.11.1+VS2019+Super4PCS复现的相关配置操作流程_第1张图片

 解压后的文件夹如下所示

【记录】PCL 1.11.1+VS2019+Super4PCS复现的相关配置操作流程_第2张图片

 其中3rdparty里的happly和stb是空的,需要在刚才的github上另外下载下来解压到对应文件夹中

 在此处下载happly和stb的zip文件并解压到对应文件夹中:

【记录】PCL 1.11.1+VS2019+Super4PCS复现的相关配置操作流程_第3张图片

 解压完后如下两图所示

happly:

【记录】PCL 1.11.1+VS2019+Super4PCS复现的相关配置操作流程_第4张图片

stb:

【记录】PCL 1.11.1+VS2019+Super4PCS复现的相关配置操作流程_第5张图片

②Cmake 

接下来是cmake的步骤,先在OpenGR文件夹下的install文件夹下新建两个文件夹,分别命名为build和install

【记录】PCL 1.11.1+VS2019+Super4PCS复现的相关配置操作流程_第6张图片

然后运行cmake,将红圈处的两个路径设置为刚刚安装好的OpenGR的位置以及OpenGR中build文件的位置,记得勾选下方的Grouped

【记录】PCL 1.11.1+VS2019+Super4PCS复现的相关配置操作流程_第7张图片

 然后点击下方的Generate,会跳出如下界面,按图中方式填写,然后Finish

【记录】PCL 1.11.1+VS2019+Super4PCS复现的相关配置操作流程_第8张图片

 此时再点击configure,等待进度满后出现如下界面,

【记录】PCL 1.11.1+VS2019+Super4PCS复现的相关配置操作流程_第9张图片

此时勾选Advanced,界面变为

【记录】PCL 1.11.1+VS2019+Super4PCS复现的相关配置操作流程_第10张图片

 将Ungrouped Entries中的EIFGEN3——INCLUDE DIR项的内容改为自己PCL库中eigen库的位置(其实就是和上面那行的内容一样,可以直接复制)

【记录】PCL 1.11.1+VS2019+Super4PCS复现的相关配置操作流程_第11张图片

 然后取消勾选Advanced,再将CMAKE下的CMAKE_INSTALL_PREFIX项中的内容改为刚才创建的install文件夹的路径

 【记录】PCL 1.11.1+VS2019+Super4PCS复现的相关配置操作流程_第12张图片

 最后点击generate,至此cmake步骤完成。

③生成

双击运行刚刚创建的build文件夹下的 OpenGR.sln项目文件

【记录】PCL 1.11.1+VS2019+Super4PCS复现的相关配置操作流程_第13张图片

修改上面的模式为Release,x64模式

接下来分别右击ALL_ BUILD和INSTALL,点击里面的生成

【记录】PCL 1.11.1+VS2019+Super4PCS复现的相关配置操作流程_第14张图片

完成后,install文件夹下就会生成以下几个文件

 【记录】PCL 1.11.1+VS2019+Super4PCS复现的相关配置操作流程_第15张图片

 ④配置文件

首先新建VS2019的空项目,选择与PCL库安装时相符的模式(debug64或release64),打开视图——其他窗口——属性管理器,在对应的模式下右击添加PCL库的属性表(安装PCL库时已经提前保存好,不清楚可以去看相关教程),这里之前我碰到了一个疑问,当时安装PCL库时用的是Debug版本,而原博主使用的时Release版本,我本身也是个小白,因此担心会遇到问题,实际操作后没有遇到问题成功实现了算法,所以这两种版本应该都可以。

添加PCL库的属性表后,新建一个属性表命名为super4PCS

【记录】PCL 1.11.1+VS2019+Super4PCS复现的相关配置操作流程_第16张图片

 双击这个属性表进行配置

在VC ++目录中,点击包含目录——编辑,在其中添加之前创建的install文件夹下的include文件的路径

【记录】PCL 1.11.1+VS2019+Super4PCS复现的相关配置操作流程_第17张图片

【记录】PCL 1.11.1+VS2019+Super4PCS复现的相关配置操作流程_第18张图片

同样的, 点击库目录——编辑,在其中添加install文件夹下lib文件的路径

【记录】PCL 1.11.1+VS2019+Super4PCS复现的相关配置操作流程_第19张图片

【记录】PCL 1.11.1+VS2019+Super4PCS复现的相关配置操作流程_第20张图片

然后点击确定,最后将新建的这个super4PCS属性表保存到合适的位置,以后每次运行super4pcs算法需要添加这个属性表,因此要记住保存到了哪里。

接下来,在此电脑——属性——高级系统设置——环境变量——系统变量中,双击Path

 【记录】PCL 1.11.1+VS2019+Super4PCS复现的相关配置操作流程_第21张图片

【记录】PCL 1.11.1+VS2019+Super4PCS复现的相关配置操作流程_第22张图片

【记录】PCL 1.11.1+VS2019+Super4PCS复现的相关配置操作流程_第23张图片

 在其中添加install文件夹下bin文件的路径

【记录】PCL 1.11.1+VS2019+Super4PCS复现的相关配置操作流程_第24张图片

 到此配置工作就完成了。

⑤测试

在之前新建的空项目中测试的代码(如果要重新新建项目,记得要添加PCL属性表和之前创建保存好的super4PCS属性表),其实与PCL库下实现的4PCS的代码基本一样,不过需要先添加以下三个头文件:

#include 
#include 
#include 

 我的具体测试代码如下:

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 


using namespace std;
typedef pcl::PointXYZ PointT;
typedef pcl::PointCloud PointCloud;

void visualize_pcd(PointCloud::Ptr pcd_src, PointCloud::Ptr pcd_tgt, PointCloud::Ptr pcd_final)
{
	pcl::visualization::PCLVisualizer viewer1("registration Viewer1");
	pcl::visualization::PCLVisualizer viewer2("registration Viewer2");
	//原始点云绿色
	pcl::visualization::PointCloudColorHandlerCustom src_h(pcd_src, 0, 255, 0);
	//目标点云红色
	pcl::visualization::PointCloudColorHandlerCustom tgt_h(pcd_tgt, 255, 0, 0);
	//匹配好的点云绿色
	pcl::visualization::PointCloudColorHandlerCustom final_h(pcd_final, 0, 255, 0);
	viewer1.addCoordinateSystem(5.0);
	viewer2.addCoordinateSystem(5.0);
	viewer1.setBackgroundColor(0, 0, 0);
	viewer2.setBackgroundColor(0, 0, 0);
	viewer1.addPointCloud(pcd_src, src_h, "source cloud");
	viewer1.addPointCloud(pcd_tgt, tgt_h, "target cloud");
	viewer2.addPointCloud(pcd_final, final_h, "result cloud");
	viewer2.addPointCloud(pcd_tgt, tgt_h, "target cloud");
	while (!viewer1.wasStopped())
	{
		viewer1.spinOnce(100);
		boost::this_thread::sleep(boost::posix_time::microseconds(100000));
	}

}

int main(int argc, char** argv)
{
	//加载点云文件
	PointCloud::Ptr cloud_source(new PointCloud);
	PointCloud::Ptr cloud_target0(new PointCloud);
	PointCloud::Ptr cloud_target(new PointCloud);
	//std::string filename = "point_source/hippo1-1224_s100.pcd";//
	std::string filename = "100bun045-100.pcd";//
	if (pcl::io::loadPCDFile(filename, *cloud_source) == -1)//*打开点云文件

	{
		PCL_ERROR("Couldn't read file source\n");
		return(-1);
	}

	std::string filename2 = "100bun045-100.pcd";//
	if (pcl::io::loadPCDFile(filename2, *cloud_target0) == -1)//*打开点云文件

	{
		PCL_ERROR("Couldn't read file source\n");
		return(-1);
	}

	Eigen::Matrix4f tras0 = Eigen::Matrix4f::Identity();
	// 定义旋转矩阵,绕y轴
	float theta = M_PI / 4;		// 旋转弧度 45°
	tras0(0, 0) = cos(theta);
	tras0(0, 2) = sin(theta);
	tras0(2, 0) = -sin(theta);
	tras0(2, 2) = cos(theta);
	// 定义在x轴上的平移
	tras0(0, 3) = 2.5;
	//定义在y轴上的平移
	tras0(1, 3) = 0;
	//定义在z轴上的平移
	tras0(2, 3) = 5;
	cout << "tars0matrix:" << endl << tras0 << endl;
	pcl::transformPointCloud(*cloud_target0, *cloud_target, tras0);
	//四点法配准
	PointCloud::Ptr pcs(new PointCloud);

	pcl::Super4PCSsfpcs;
	sfpcs.setInputSource(cloud_source);
	sfpcs.setInputTarget(cloud_target);
	sfpcs.setOverlap(0.5);
	sfpcs.setDelta(0.08);//增量
	sfpcs.setMaxTimeSeconds(500);//最大计算时间
	//sfpcs.setSampleSize(paraD);//采样点

	Eigen::Matrix4f tras;
	clock_t start = clock();
	sfpcs.align(*pcs);
	clock_t end = clock();
	cout << "time:" << (double)(end - start) / (double)CLOCKS_PER_SEC << endl;
	cout << "score:" << sfpcs.getFitnessScore() << endl;
	tras = sfpcs.getFinalTransformation();
	cout << "matrix:" << endl << tras << endl << endl << endl;
	

	//for (int i = 0; i < 20; i++)//for循环20次用于查看多次实验下的不同结果
	//{
	//	clock_t start = clock();
	//	fpcs.align(*pcs);
	//	clock_t end = clock();
	//	cout << "time:" << (double)(end - start) / (double)CLOCKS_PER_SEC << endl;
	//	cout << "score:" << fpcs.getFitnessScore() << endl;
	//	tras = fpcs.getFinalTransformation();
	//	cout << "matrix:" << endl << tras << endl << endl << endl;
	//}


	PointCloud::Ptr cloud_end(new PointCloud);
	pcl::transformPointCloud(*cloud_source, *cloud_end, tras);

	visualize_pcd(cloud_source, cloud_target, cloud_end);
	return (0);

}

 所用的点云数据类型为pcd

若出现如下报错:error C1128:字节数超过对象文件格式main.cpp限制:请使用/bigobj进行编译

可参考这篇博客里的办法:

error C1128:字节数超过对象文件格式main.cpp限制:请使用/bigobj进行编译_熊L的博客-CSDN博客_字节数超过对象文件格式限制

 配准结果:

【记录】PCL 1.11.1+VS2019+Super4PCS复现的相关配置操作流程_第25张图片

配准前:

 【记录】PCL 1.11.1+VS2019+Super4PCS复现的相关配置操作流程_第26张图片

 配准后:

【记录】PCL 1.11.1+VS2019+Super4PCS复现的相关配置操作流程_第27张图片

你可能感兴趣的:(c++)