Windows PCL点云库不同版本的切换,以及不同版本计算结果不一致的阐述

因时代机遇,我首次使用的版本组合是VS2019+PCL1.11.1+cmake3.18.5;

因发展需要,当前最新的版本组合是VS2022+PCL1.13.1+cmake3.26.4;

一、首先,为啥要切换版本呢?

(1)不同版本的PCL库的API可能不同,导致代码编译就报错;

(2)不同版本的PCL库的计算结果可能不一致,导致结果的不可复现性;

二、那么,我们平时应该用哪个版本呢?

平时应该用的版本是业务代码使用的版本,比如我的业务代码基本是VS2019+PCL1.11.1编译运行的,那么即使换了新电脑,在验证代码结果时,也应该以这个版本组合为主;

而新的版本组合VS2022+PCL1.13.1,则可以等到业务代码环境都升级到该版本时再使用,目前研究一下版本切换,就是想机器有多个版本的情况下,我想用哪个版本就用哪个;

三、正题,切换版本之前的软件安装工作

安装VS2019、VS2022、cmake3.18.5、cmake3.26.4、PCL1.11.1、PCL1.13.1之后;

版本切换的工作主要是系统环境变量的修改:

以下以_ALL结尾的环境变量基本不起作用,只是我列举的枚举,以PCL_ROOT和PCL_ROOT_ALL为例,PCL_ROOT_ALL放置了所有PCL_ROOT值的枚举,在我需要用某个特定版本时,我就可以复制其中一个值给到PCL_ROOT;

第三张图时Path的值,当需要用到哪个版本时,应当将对应版本的路径值上移至其他版本之前;

注意!!! 

例子:在运行时,即使你编译时使用的是PCL1.13.1,但是运行时系统的环境改变成了PCL1.11.1,那么因为两个版本的库的名称都是一样的(库的名称并没有带版本),因此不会报没有DLL的错误而是直接成功运行,但是最终运行的结果是当前系统环境对应的PCL1.11.1版本的结果。

四、不同版本计算结果不一致的阐述:

VS2019(MSVC16)+PCL1.11.1+cmake3.18.5的组合VS2022(MSVC17)+PCL1.13.1+cmake3.26.4在运行某些函数时结果不一致,原因未知,需要查看源码是否改动或者Github询问函数是否改动,已经在Github问了,见GitHub - PointCloudLibrary/pcl: Point Cloud Library (PCL)icon-default.png?t=N658https://github.com/PointCloudLibrary/pcl/issues/5760,但是没有更明确的结论,好奇的大家可能试试下列代码:

#include <iostream>

#include <Eigen/Core>

#include <opencv2/opencv.hpp>

#include <pcl/common/angles.h>	
#include <pcl/common/impl/pca.hpp>
#include <pcl/common/common.h> // for getMinMax3D()
#include <pcl/common/eigen.h>
#include <pcl/common/centroid.h>
#include <pcl/common/geometry.h>
#include <pcl/point_types.h>
#include <pcl/point_cloud.h>
#include <pcl/io/ply_io.h>
#include <pcl/io/obj_io.h>
#include <pcl/segmentation/sac_segmentation.h>   //基于采样一致性分割的类的头文件

int main()
{
	using namespace std;
	using namespace cv;
	cout << "begin" << endl;

	string obj_path = R"(E:\luozc\code\cpp\ovi\sstree\spine_fwsy\build\save\cylinder\AARJ33D0003_20230627150639940_99\cloudRgbPtr.ply)";
	using T = pcl::PointXYZ;
	pcl::PointCloud<T>::Ptr ptcld(new pcl::PointCloud<T>);
	pcl::io::loadPLYFile(obj_path, *ptcld);

#if 1
    double dis = 4.0;
    Eigen::Vector4f coeff_plane;

    pcl::PointIndices::Ptr planeInd(new pcl::PointIndices);
    pcl::ModelCoefficients::Ptr coefficients(new pcl::ModelCoefficients);
    pcl::SACSegmentation<T> seg;
    // Optional
    seg.setOptimizeCoefficients(true);
    // Mandatory
    seg.setModelType(pcl::SACMODEL_PLANE);
    seg.setMethodType(pcl::SAC_RANSAC);//pcl::SAC_RANSAC//pcl::LMedS
    seg.setDistanceThreshold(dis);

    seg.setInputCloud(ptcld);
    seg.segment(*planeInd, *coefficients);
    coeff_plane = { coefficients->values[0],coefficients->values[1],coefficients->values[2],coefficients->values[3] };
    cout << coeff_plane << endl;
#endif

	system("pause");
	return 0;
}