Windows10安装PCL1.14.0及点云配准

一、下载visual studio2022

下载网址:Visual Studio: 面向软件开发人员和 Teams 的 IDE 和代码编辑器 (microsoft.com)

安装的时候选择"使用C++的桌面开发“,同时可以修改文件路径,可以放在D盘。修改文件路径的时候,共享组件、工具和SDK的路径无法修改,可能是因为你之前有安装过Visual studio。可以通过以下操作解决:

1.首先WIN+R,输入regedit回车

2.按照这个顺序展开目录

HKEY_LOCAL_MACHINE
SOFTWARE
Microsoft
VisualStudio
Setup

3.右键删除SharedInstallationPath  CachePath,就可以修改共享组件、工具和SDK的路径了

二、安装PCL1.14.0

都是以我自己的安装路径为例

1.下载

官网下载:Releases · PointCloudLibrary/pcl · GitHub

只要下载PCL-1.14.0-AllInOne-msvc2022-win64.exe和pcl-1.14.0-pdb-msvc2022-win64.zip两个文件即可。

如果下载太慢,我这里已经下载好了:

链接:https://pan.baidu.com/s/177DvR5gOcVL7iPm4xI7s_w 
提取码:wstc 

2.安装

点击PCL-1.14.0-AllInOne-msvc2022-win64.exe进行安装

下一步

我接受

选择Add PCL to the system Path for all users,下一步

可以选择修改路径,我自己的路径是C:\Compiler\PCL\PCL 1.14.0,你可以选择自己的路径,不过一定要记得,因为之后配置环境变量要用到,然后下一步

没必要创建快捷方式,下一步,然后点击安装;在安装过程中,会出现提醒你变量名太长,没办法写入环境变量,这个时候你直接确定就行,等安装完成之后,自己配置环境变量。安装完成之后会出现这三个应用

把OpenNi2.2 SDK for Windows 64-bit给卸载掉,因为它有默认安装路径,即使我们修改文件安装路径,它还是安装在默认路径;卸载完之后,打开C:\Compiler\PCL\PCL 1.14.0\3rdParty\OpenNI2文件夹,发现里面有一个OpenNI-Windows-x64-2.2.msi,这是安装PCL-1.14.0-AllInOne-msvc2022-win64.exe的时候附带的,点击安装,可以帮你再次安装OpenNi2.2 SDK for Windows 64-bit,而且可以修改成自己的路径,我的路径是C:\Compiler\PCL\PCL 1.14.0\3rdParty\OpenNI2

安装完成之后就会包含这些内容

接着把pcl-1.14.0-pdb-msvc2022-win64.zip解压

把里面的所有pdb文件都复制到C:\Compiler\PCL\PCL 1.14.0\bin里面

3.配置环境变量

此电脑右键属性

点击高级系统设置

点击环境变量

确保这四个都存在,这是安装PCL-1.14.0-AllInOne-msvc2022-win64.exe的时候自动生成的,接着点击Path开始配置环境变量

C:\Compiler\PCL\PCL 1.14.0\bin
C:\Compiler\PCL\PCL 1.14.0\3rdParty\VTK\bin
C:\Compiler\PCL\PCL 1.14.0\3rdParty\OpenNI2\Tools
C:\Compiler\PCL\PCL 1.14.0\3rdParty\OpenNI2\Redist
C:\Compiler\PCL\PCL 1.14.0\3rdParty\Boost\lib
C:\Compiler\PCL\PCL 1.14.0\3rdParty\Qhull\bin
C:\Compiler\PCL\PCL 1.14.0\3rdParty\FLANN\bin

把这几个路径添加进环境变量即可。

三、创建项目

打开visual studio2022

创建新项目

选择空项目,下一步

可以修改项目名称,和位置;创建项目

右键点击源文件,添加新项,随便取个名字,点击添加(注意:我已经添加过文件了,如果是新创建的文件,源文件里面是啥也没有的)

右键点击解决方案下方的pointCloud(这个是项目名称),点击属性,就会出现这个属性页,点击VC++目录

C:\Compiler\PCL\PCL 1.14.0\3rdParty\Boost\include\boost-1_84
C:\Compiler\PCL\PCL 1.14.0\3rdParty\Eigen3\include\eigen3
C:\Compiler\PCL\PCL 1.14.0\3rdParty\FLANN\include
C:\Compiler\PCL\PCL 1.14.0\3rdParty\Qhull\include
C:\Compiler\PCL\PCL 1.14.0\3rdParty\VTK\include\vtk-9.3
C:\Compiler\PCL\PCL 1.14.0\3rdParty\OpenNI2\Include
C:\Compiler\PCL\PCL 1.14.0\include\pcl-1.14

把这些路径加入到包含目录里

C:\Compiler\PCL\PCL 1.14.0\3rdParty\FLANN\lib
C:\Compiler\PCL\PCL 1.14.0\3rdParty\Boost\lib
C:\Compiler\PCL\PCL 1.14.0\lib
C:\Compiler\PCL\PCL 1.14.0\3rdParty\VTK\lib
C:\Compiler\PCL\PCL 1.14.0\3rdParty\Qhull\lib
C:\Compiler\PCL\PCL 1.14.0\3rdParty\OpenNI2\Lib

这些路径放到库目录里

然后点击C/C++的所有选项,把SDL检查改成否

再点击C/C++的代码生成,修改启用增强指令集为高级适量扩展(X86/X64)(/arch:AVX)

BOOST_USE_WINDOWS_H
NOMINMAX
_CRT_SECURE_NO_DEPRECATE

在C/C++的预处理器里面的预处理定义增加这三行

可以用代码获取附加项文件名

#include <iostream>
#include <fstream>
#include <string>
#include <filesystem>
namespace fs = std::filesystem;bool ends_with(const std::string& value, const std::string& ending)
{if (ending.size() > value.size()) return false;return std::equal(ending.rbegin(), ending.rend(), value.rbegin());
}int main() {std::string path1 = "C:\\Compiler\\PCL\\PCL 1.14.0\\3rdParty\\VTK\\lib\\";  // 你需要替换为你的具体路径std::string path2 = "C:\\Compiler\\PCL\\PCL 1.14.0\\lib\\";  // 你需要替换为你的具体路径std::ofstream ofs_glib1("gLibFiles1.txt");std::ofstream ofs_other1("otherFiles1.txt");std::ofstream ofs_glib2("gLibFiles2.txt");std::ofstream ofs_other2("otherFiles2.txt");if (!ofs_glib1 || !ofs_other1) {std::cerr << "无法打开输出文件.\n";return 1;}if (!ofs_glib2 || !ofs_other2) {std::cerr << "无法打开输出文件.\n";return 1;}for (auto& p : fs::directory_iterator(path1)) {if (p.is_regular_file()) {std::string filename = p.path().filename().string();if (ends_with(filename, "-gd.lib") || ends_with(filename, "d.lib")) {  // 检查文件名是否以 "-gd.lib" 或 "d.lib" 结尾ofs_glib1 << filename << '\n';}else {ofs_other1 << filename << '\n';}}}for (auto& p : fs::directory_iterator(path2)) {if (p.is_regular_file()) {std::string filename = p.path().filename().string();if (ends_with(filename, "-gd.lib") || ends_with(filename, "d.lib")) {  // 检查文件名是否以 "-gd.lib" 或 "d.lib" 结尾ofs_glib2 << filename << '\n';}else {ofs_other2 << filename << '\n';}}}return 0;
}//C:\\Compiler\\PCL\\PCL 1.14.0\\3rdParty\\VTK\\lib\\

一共可以得到四个txt文件

上面两个保存的是Debug版本的附加项 ,把这两个文件的内容整合到一起:

pcl_commond.lib
pcl_featuresd.lib
pcl_filtersd.lib
pcl_iod.lib
pcl_io_plyd.lib
pcl_kdtreed.lib
pcl_keypointsd.lib
pcl_mld.lib
pcl_octreed.lib
pcl_outofcored.lib
pcl_peopled.lib
pcl_recognitiond.lib
pcl_registrationd.lib
pcl_sample_consensusd.lib
pcl_searchd.lib
pcl_segmentationd.lib
pcl_stereod.lib
pcl_surfaced.lib
pcl_trackingd.lib
pcl_visualizationd.lib
vtkcgns-9.3-gd.lib
vtkChartsCore-9.3-gd.lib
vtkCommonColor-9.3-gd.lib
vtkCommonComputationalGeometry-9.3-gd.lib
vtkCommonCore-9.3-gd.lib
vtkCommonDataModel-9.3-gd.lib
vtkCommonExecutionModel-9.3-gd.lib
vtkCommonMath-9.3-gd.lib
vtkCommonMisc-9.3-gd.lib
vtkCommonSystem-9.3-gd.lib
vtkCommonTransforms-9.3-gd.lib
vtkDICOMParser-9.3-gd.lib
vtkDomainsChemistry-9.3-gd.lib
vtkDomainsChemistryOpenGL2-9.3-gd.lib
vtkdoubleconversion-9.3-gd.lib
vtkexodusII-9.3-gd.lib
vtkexpat-9.3-gd.lib
vtkFiltersAMR-9.3-gd.lib
vtkFiltersCore-9.3-gd.lib
vtkFiltersExtraction-9.3-gd.lib
vtkFiltersFlowPaths-9.3-gd.lib
vtkFiltersGeneral-9.3-gd.lib
vtkFiltersGeneric-9.3-gd.lib
vtkFiltersGeometry-9.3-gd.lib
vtkFiltersHybrid-9.3-gd.lib
vtkFiltersHyperTree-9.3-gd.lib
vtkFiltersImaging-9.3-gd.lib
vtkFiltersModeling-9.3-gd.lib
vtkFiltersParallel-9.3-gd.lib
vtkFiltersParallelImaging-9.3-gd.lib
vtkFiltersPoints-9.3-gd.lib
vtkFiltersProgrammable-9.3-gd.lib
vtkFiltersSelection-9.3-gd.lib
vtkFiltersSMP-9.3-gd.lib
vtkFiltersSources-9.3-gd.lib
vtkFiltersStatistics-9.3-gd.lib
vtkFiltersTexture-9.3-gd.lib
vtkFiltersTopology-9.3-gd.lib
vtkFiltersVerdict-9.3-gd.lib
vtkfmt-9.3-gd.lib
vtkfreetype-9.3-gd.lib
vtkGeovisCore-9.3-gd.lib
vtkgl2ps-9.3-gd.lib
vtkglew-9.3-gd.lib
vtkhdf5-9.3-gd.lib
vtkhdf5_hl-9.3-gd.lib
vtkImagingColor-9.3-gd.lib
vtkImagingCore-9.3-gd.lib
vtkImagingFourier-9.3-gd.lib
vtkImagingGeneral-9.3-gd.lib
vtkImagingHybrid-9.3-gd.lib
vtkImagingMath-9.3-gd.lib
vtkImagingMorphological-9.3-gd.lib
vtkImagingSources-9.3-gd.lib
vtkImagingStatistics-9.3-gd.lib
vtkImagingStencil-9.3-gd.lib
vtkInfovisCore-9.3-gd.lib
vtkInfovisLayout-9.3-gd.lib
vtkInteractionImage-9.3-gd.lib
vtkInteractionStyle-9.3-gd.lib
vtkInteractionWidgets-9.3-gd.lib
vtkIOAMR-9.3-gd.lib
vtkIOAsynchronous-9.3-gd.lib
vtkIOCesium3DTiles-9.3-gd.lib
vtkIOCGNSReader-9.3-gd.lib
vtkIOChemistry-9.3-gd.lib
vtkIOCityGML-9.3-gd.lib
vtkIOCONVERGECFD-9.3-gd.lib
vtkIOCore-9.3-gd.lib
vtkIOEnSight-9.3-gd.lib
vtkIOExodus-9.3-gd.lib
vtkIOExport-9.3-gd.lib
vtkIOExportGL2PS-9.3-gd.lib
vtkIOExportPDF-9.3-gd.lib
vtkIOGeometry-9.3-gd.lib
vtkIOHDF-9.3-gd.lib
vtkIOImage-9.3-gd.lib
vtkIOImport-9.3-gd.lib
vtkIOInfovis-9.3-gd.lib
vtkIOIOSS-9.3-gd.lib
vtkIOLegacy-9.3-gd.lib
vtkIOLSDyna-9.3-gd.lib
vtkIOMINC-9.3-gd.lib
vtkIOMotionFX-9.3-gd.lib
vtkIOMovie-9.3-gd.lib
vtkIONetCDF-9.3-gd.lib
vtkIOOggTheora-9.3-gd.lib
vtkIOParallel-9.3-gd.lib
vtkIOParallelXML-9.3-gd.lib
vtkIOPLY-9.3-gd.lib
vtkIOSegY-9.3-gd.lib
vtkIOSQL-9.3-gd.lib
vtkioss-9.3-gd.lib
vtkIOTecplotTable-9.3-gd.lib
vtkIOVeraOut-9.3-gd.lib
vtkIOVideo-9.3-gd.lib
vtkIOXML-9.3-gd.lib
vtkIOXMLParser-9.3-gd.lib
vtkjpeg-9.3-gd.lib
vtkjsoncpp-9.3-gd.lib
vtkkissfft-9.3-gd.lib
vtklibharu-9.3-gd.lib
vtklibproj-9.3-gd.lib
vtklibxml2-9.3-gd.lib
vtkloguru-9.3-gd.lib
vtklz4-9.3-gd.lib
vtklzma-9.3-gd.lib
vtkmetaio-9.3-gd.lib
vtknetcdf-9.3-gd.lib
vtkogg-9.3-gd.lib
vtkParallelCore-9.3-gd.lib
vtkParallelDIY-9.3-gd.lib
vtkpng-9.3-gd.lib
vtkpugixml-9.3-gd.lib
vtkRenderingAnnotation-9.3-gd.lib
vtkRenderingContext2D-9.3-gd.lib
vtkRenderingContextOpenGL2-9.3-gd.lib
vtkRenderingCore-9.3-gd.lib
vtkRenderingFreeType-9.3-gd.lib
vtkRenderingGL2PSOpenGL2-9.3-gd.lib
vtkRenderingHyperTreeGrid-9.3-gd.lib
vtkRenderingImage-9.3-gd.lib
vtkRenderingLabel-9.3-gd.lib
vtkRenderingLICOpenGL2-9.3-gd.lib
vtkRenderingLOD-9.3-gd.lib
vtkRenderingOpenGL2-9.3-gd.lib
vtkRenderingSceneGraph-9.3-gd.lib
vtkRenderingUI-9.3-gd.lib
vtkRenderingVolume-9.3-gd.lib
vtkRenderingVolumeOpenGL2-9.3-gd.lib
vtkRenderingVtkJS-9.3-gd.lib
vtksqlite-9.3-gd.lib
vtksys-9.3-gd.lib
vtkTestingRendering-9.3-gd.lib
vtktheora-9.3-gd.lib
vtktiff-9.3-gd.lib
vtkverdict-9.3-gd.lib
vtkViewsContext2D-9.3-gd.lib
vtkViewsCore-9.3-gd.lib
vtkViewsInfovis-9.3-gd.lib
vtkWrappingTools-9.3-gd.lib
vtkzlib-9.3-gd.lib

下面两个保存的是Release版本的附加项,把这两个文件的内容整合到一起:

pcl_common.lib
pcl_features.lib
pcl_filters.lib
pcl_io.lib
pcl_io_ply.lib
pcl_kdtree.lib
pcl_keypoints.lib
pcl_ml.lib
pcl_octree.lib
pcl_outofcore.lib
pcl_people.lib
pcl_recognition.lib
pcl_registration.lib
pcl_sample_consensus.lib
pcl_search.lib
pcl_segmentation.lib
pcl_stereo.lib
pcl_surface.lib
pcl_tracking.lib
pcl_visualization.lib
vtkcgns-9.3.lib
vtkChartsCore-9.3.lib
vtkCommonColor-9.3.lib
vtkCommonComputationalGeometry-9.3.lib
vtkCommonCore-9.3.lib
vtkCommonDataModel-9.3.lib
vtkCommonExecutionModel-9.3.lib
vtkCommonMath-9.3.lib
vtkCommonMisc-9.3.lib
vtkCommonSystem-9.3.lib
vtkCommonTransforms-9.3.lib
vtkDICOMParser-9.3.lib
vtkDomainsChemistry-9.3.lib
vtkDomainsChemistryOpenGL2-9.3.lib
vtkdoubleconversion-9.3.lib
vtkexodusII-9.3.lib
vtkexpat-9.3.lib
vtkFiltersAMR-9.3.lib
vtkFiltersCellGrid-9.3.lib
vtkFiltersCore-9.3.lib
vtkFiltersExtraction-9.3.lib
vtkFiltersFlowPaths-9.3.lib
vtkFiltersGeneral-9.3.lib
vtkFiltersGeneric-9.3.lib
vtkFiltersGeometry-9.3.lib
vtkFiltersGeometryPreview-9.3.lib
vtkFiltersHybrid-9.3.lib
vtkFiltersHyperTree-9.3.lib
vtkFiltersImaging-9.3.lib
vtkFiltersModeling-9.3.lib
vtkFiltersParallel-9.3.lib
vtkFiltersParallelImaging-9.3.lib
vtkFiltersPoints-9.3.lib
vtkFiltersProgrammable-9.3.lib
vtkFiltersReduction-9.3.lib
vtkFiltersSelection-9.3.lib
vtkFiltersSMP-9.3.lib
vtkFiltersSources-9.3.lib
vtkFiltersStatistics-9.3.lib
vtkFiltersTensor-9.3.lib
vtkFiltersTexture-9.3.lib
vtkFiltersTopology-9.3.lib
vtkFiltersVerdict-9.3.lib
vtkfmt-9.3.lib
vtkfreetype-9.3.lib
vtkGeovisCore-9.3.lib
vtkgl2ps-9.3.lib
vtkglew-9.3.lib
vtkhdf5-9.3.lib
vtkhdf5_hl-9.3.lib
vtkImagingColor-9.3.lib
vtkImagingCore-9.3.lib
vtkImagingFourier-9.3.lib
vtkImagingGeneral-9.3.lib
vtkImagingHybrid-9.3.lib
vtkImagingMath-9.3.lib
vtkImagingMorphological-9.3.lib
vtkImagingSources-9.3.lib
vtkImagingStatistics-9.3.lib
vtkImagingStencil-9.3.lib
vtkInfovisCore-9.3.lib
vtkInfovisLayout-9.3.lib
vtkInteractionImage-9.3.lib
vtkInteractionStyle-9.3.lib
vtkInteractionWidgets-9.3.lib
vtkIOAMR-9.3.lib
vtkIOAsynchronous-9.3.lib
vtkIOCellGrid-9.3.lib
vtkIOCesium3DTiles-9.3.lib
vtkIOCGNSReader-9.3.lib
vtkIOChemistry-9.3.lib
vtkIOCityGML-9.3.lib
vtkIOCONVERGECFD-9.3.lib
vtkIOCore-9.3.lib
vtkIOEnSight-9.3.lib
vtkIOExodus-9.3.lib
vtkIOExport-9.3.lib
vtkIOExportGL2PS-9.3.lib
vtkIOExportPDF-9.3.lib
vtkIOFLUENTCFF-9.3.lib
vtkIOGeometry-9.3.lib
vtkIOHDF-9.3.lib
vtkIOImage-9.3.lib
vtkIOImport-9.3.lib
vtkIOInfovis-9.3.lib
vtkIOIOSS-9.3.lib
vtkIOLegacy-9.3.lib
vtkIOLSDyna-9.3.lib
vtkIOMINC-9.3.lib
vtkIOMotionFX-9.3.lib
vtkIOMovie-9.3.lib
vtkIONetCDF-9.3.lib
vtkIOOggTheora-9.3.lib
vtkIOParallel-9.3.lib
vtkIOParallelXML-9.3.lib
vtkIOPLY-9.3.lib
vtkIOSegY-9.3.lib
vtkIOSQL-9.3.lib
vtkioss-9.3.lib
vtkIOTecplotTable-9.3.lib
vtkIOVeraOut-9.3.lib
vtkIOVideo-9.3.lib
vtkIOXML-9.3.lib
vtkIOXMLParser-9.3.lib
vtkjpeg-9.3.lib
vtkjsoncpp-9.3.lib
vtkkissfft-9.3.lib
vtklibharu-9.3.lib
vtklibproj-9.3.lib
vtklibxml2-9.3.lib
vtkloguru-9.3.lib
vtklz4-9.3.lib
vtklzma-9.3.lib
vtkmetaio-9.3.lib
vtknetcdf-9.3.lib
vtkogg-9.3.lib
vtkParallelCore-9.3.lib
vtkParallelDIY-9.3.lib
vtkpng-9.3.lib
vtkpugixml-9.3.lib
vtkRenderingAnnotation-9.3.lib
vtkRenderingCellGrid-9.3.lib
vtkRenderingContext2D-9.3.lib
vtkRenderingContextOpenGL2-9.3.lib
vtkRenderingCore-9.3.lib
vtkRenderingFreeType-9.3.lib
vtkRenderingGL2PSOpenGL2-9.3.lib
vtkRenderingHyperTreeGrid-9.3.lib
vtkRenderingImage-9.3.lib
vtkRenderingLabel-9.3.lib
vtkRenderingLICOpenGL2-9.3.lib
vtkRenderingLOD-9.3.lib
vtkRenderingOpenGL2-9.3.lib
vtkRenderingSceneGraph-9.3.lib
vtkRenderingUI-9.3.lib
vtkRenderingVolume-9.3.lib
vtkRenderingVolumeOpenGL2-9.3.lib
vtkRenderingVtkJS-9.3.lib
vtksqlite-9.3.lib
vtksys-9.3.lib
vtkTestingRendering-9.3.lib
vtktheora-9.3.lib
vtktiff-9.3.lib
vtkverdict-9.3.lib
vtkViewsContext2D-9.3.lib
vtkViewsCore-9.3.lib
vtkViewsInfovis-9.3.lib
vtkWrappingTools-9.3.lib
vtkzlib-9.3.lib

选择哪个版本看你需求,在链接器的输入的附加依赖项里增加相应版本的附加项,配置完成,电脑重启,即可生效

四、确认是否安装成功

#include <iostream>
#include <vector>
#include <ctime>
#include <pcl/point_cloud.h>
#include <pcl/octree/octree.h>
#include <boost/thread/thread.hpp>
#include <pcl/visualization/pcl_visualizer.h>
using namespace std;
int
main(int argc, char** argv)
{srand((unsigned int)time(NULL));pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);// 创建点云数据cloud->width = 1000;cloud->height = 1;cloud->points.resize(cloud->width * cloud->height);for (size_t i = 0; i < cloud->points.size(); ++i){cloud->points[i].x = 1024.0f * rand() / (RAND_MAX + 1.0f);cloud->points[i].y = 1024.0f * rand() / (RAND_MAX + 1.0f);cloud->points[i].z = 1024.0f * rand() / (RAND_MAX + 1.0f);}pcl::octree::OctreePointCloudSearch<pcl::PointXYZ> octree(0.1);octree.setInputCloud(cloud);octree.addPointsFromInputCloud();pcl::PointXYZ searchPoint;searchPoint.x = 1024.0f * rand() / (RAND_MAX + 1.0f);searchPoint.y = 1024.0f * rand() / (RAND_MAX + 1.0f);searchPoint.z = 1024.0f * rand() / (RAND_MAX + 1.0f);//半径内近邻搜索vector<int>pointIdxRadiusSearch;vector<float>pointRadiusSquaredDistance;float radius = 256.0f * rand() / (RAND_MAX + 1.0f);cout << "Neighbors within radius search at (" << searchPoint.x<< " " << searchPoint.y<< " " << searchPoint.z<< ") with radius=" << radius << endl;if (octree.radiusSearch(searchPoint, radius, pointIdxRadiusSearch, pointRadiusSquaredDistance) > 0){for (size_t i = 0; i < pointIdxRadiusSearch.size(); ++i)cout << "    " << cloud->points[pointIdxRadiusSearch[i]].x<< " " << cloud->points[pointIdxRadiusSearch[i]].y<< " " << cloud->points[pointIdxRadiusSearch[i]].z<< " (squared distance: " << pointRadiusSquaredDistance[i] << ")" << endl;}// 初始化点云可视化对象boost::shared_ptr<pcl::visualization::PCLVisualizer>viewer(new pcl::visualization::PCLVisualizer("v1"));viewer->setBackgroundColor(0, 0, 0);  //设置背景颜色为黑色// 对点云着色可视化 (red).pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ>target_color(cloud, 255, 0, 0);viewer->addPointCloud<pcl::PointXYZ>(cloud, target_color, "target cloud");viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "target cloud");// 等待直到可视化窗口关闭while (!viewer->wasStopped()){viewer->spinOnce(100);boost::this_thread::sleep(boost::posix_time::microseconds(1000));}return (0);
}

这份代码运行之后出现红色点云:

五、点云配准

#include <pcl/point_types.h>
#include <pcl/point_cloud.h>
#include <pcl/features/fpfh_omp.h>
#include <pcl/io/ply_io.h>//pcd输入输出头文件
#include <pcl/registration/icp.h>//点云icp算法头文件
#include <pcl/registration/ndt.h>//点云NDT算法头文件
#include <pcl/registration/ia_ransac.h>//点云ransac迭代对齐算法(SAC-IA)算法头文件
#include <pcl/registration/gicp.h>//点云GICP算法的头文件
#include <pcl/visualization/pcl_visualizer.h>//点云可视化头文件
#include <time.h>
#include <boost/thread.hpp>
#include <pcl/features/normal_3d_omp.h>
typedef pcl::PointXYZ PointT; //重定义pcl::PointXYZ为PointT
typedef pcl::PointCloud<PointT> PointCloud; //重定义pcl::PointCloud<PointT>为PointCloud
//点云配准类型
typedef pcl::IterativeClosestPoint<pcl::PointXYZ, pcl::PointXYZ> ICP;
typedef pcl::NormalDistributionsTransform<pcl::PointXYZ, pcl::PointXYZ> NDT;
typedef pcl::SampleConsensusInitialAlignment<pcl::PointXYZ, pcl::PointXYZ, pcl::FPFHSignature33> SAC_IA;
typedef pcl::GeneralizedIterativeClosestPoint<pcl::PointXYZ, pcl::PointXYZ> GICP;
//FPFH特征
typedef pcl::FPFHEstimationOMP<pcl::PointXYZ, pcl::Normal, pcl::FPFHSignature33> FPFHEstimation;
typedef pcl::PointCloud<pcl::FPFHSignature33> FPFH;
//法线估计
typedef pcl::NormalEstimationOMP<pcl::PointXYZ, pcl::Normal> NormalEstimation;
typedef pcl::PointCloud<pcl::Normal> Normal;
typedef pcl::search::KdTree<pcl::PointXYZ> KdTreeT;//点云可视化
void visualize_pcd(PointCloud::Ptr pcd_src,PointCloud::Ptr pcd_tgt,PointCloud::Ptr pcd_final)
{pcl::visualization::PCLVisualizer viewer("registration Viewer");// 设置背景viewer.setBackgroundColor(1, 1, 1);// 添加坐标轴到可视化对象,参数指定轴的大小(长度),这里设置为1.0单位长度viewer.addCoordinateSystem(0.5);// 设置相机位置和方向viewer.initCameraParameters();pcl::visualization::PointCloudColorHandlerCustom<PointT> src_h(pcd_src, 0, 255, 0);pcl::visualization::PointCloudColorHandlerCustom<PointT> tgt_h(pcd_tgt, 255, 0, 0);pcl::visualization::PointCloudColorHandlerCustom<PointT> final_h(pcd_final, 0, 0, 255);//viewer.addPointCloud(pcd_src, src_h, "source cloud");    //source绿色viewer.addPointCloud(pcd_tgt, tgt_h, "tgt cloud");     //target红色viewer.addPointCloud (pcd_final, final_h, "final cloud");  //final蓝色while (!viewer.wasStopped()){viewer.spinOnce(100);boost::this_thread::sleep(boost::posix_time::microseconds(1000));}
}void printinfo(Eigen::Matrix4f icp_trans, Eigen::Matrix3f rotation, Eigen::Vector3f translation, Eigen::Vector3f euler_angles_deg,Eigen::Quaternionf quaternion)
{cout.setf(ios::fixed);cout.precision(5);cout << endl << "Transformation matrix:" << endl << icp_trans << endl;//输出变换矩阵cout << endl << "Rotation matrix:" << endl << rotation << endl;cout << endl << "Translation vector:" << endl << translation << endl;cout << endl << "Euler Angle:" << endl;cout << endl << "roll(x):" << euler_angles_deg[2] << endl;cout << endl << "pitch(y):" << euler_angles_deg[1] << endl;cout << endl << "yaw(z):" << euler_angles_deg[0] << endl;// 输出四元数,由于欧拉角时常出现万向节,所以可以使用四元数来表示旋转,这样更精确cout << endl <<"Rotation quaternion: " << endl<< "w = " << quaternion.w() << endl<< ", x = " << quaternion.x() << endl<< ", y = " << quaternion.y() << endl<< ", z = " << quaternion.z() << endl;
}void downsampling(PointCloud::Ptr cloud_src_o, PointCloud::Ptr cloud_tgt_o,pcl::VoxelGrid<pcl::PointXYZ>::Ptr voxel_grid)
{float leaf = 0.005f;voxel_grid->setLeafSize(leaf, leaf, leaf); // 示例叶子大小voxel_grid->setInputCloud(cloud_src_o);voxel_grid->filter(*cloud_src_o);voxel_grid->setInputCloud(cloud_tgt_o);voxel_grid->filter(*cloud_tgt_o);
}
void normalestimation(NormalEstimation ne, Normal::Ptr src_normals, Normal::Ptr tgt_normals, KdTreeT::Ptr tree, PointCloud::Ptr cloud_src_o, PointCloud::Ptr cloud_tgt_o)
{创建一个NormalEstimationOMP对象,进行法线计算;ne.setSearchMethod(tree);ne.setKSearch(20);ne.setInputCloud(cloud_src_o);ne.compute(*src_normals);ne.setInputCloud(cloud_tgt_o);ne.compute(*tgt_normals);cout << "原点云法线计算完成" << endl <<*src_normals << endl;cout << "目标点云法线计算完成" << endl << *tgt_normals << endl;
}void fpfh_features(FPFHEstimation fpfh, FPFH::Ptr src_fpfhs,FPFH::Ptr tgt_fpfhs, PointCloud::Ptr cloud_src_o, PointCloud::Ptr cloud_tgt_o, KdTreeT::Ptr tree, Normal::Ptr src_normals, Normal::Ptr tgt_normals)
{fpfh.setSearchMethod(tree);fpfh.setRadiusSearch(0.05); // Use a radius search instead of a KdTree searchfpfh.setInputCloud(cloud_src_o);fpfh.setInputNormals(src_normals);fpfh.compute(*src_fpfhs);fpfh.setInputCloud(cloud_tgt_o);fpfh.setInputNormals(tgt_normals);fpfh.compute(*tgt_fpfhs);cout << "原点云特征计算完成" << *src_fpfhs << endl; cout << "目标点云特征计算完成" << *tgt_fpfhs << endl;
}GICP& gicp_registration(GICP& gicp, PointCloud& final_cloud,PointCloud::Ptr cloud_src_o, PointCloud::Ptr cloud_tgt_o)
{gicp.setInputSource(cloud_src_o);gicp.setInputTarget(cloud_tgt_o);// 配准时最大迭代次数gicp.setMaximumIterations(50);// 两次变化矩阵之间的差异小于这个阈值时,就认为已经收敛,停止迭代gicp.setTransformationEpsilon(1e-6);// 对应点之间的最大距离gicp.setMaxCorrespondenceDistance(0.05);// 采用随机采样一致性方法进行配准gicp.setRANSACOutlierRejectionThreshold(1.5);// 最小内点比例。在RANSAC配准方法中,当内点的比例小于此值时,认为配准失败。gicp.setRANSACIterations(20);// 执行配准,并将结果存储在Final中gicp.align(final_cloud);return gicp;}
SAC_IA& sacia_registration(SAC_IA & sac_ia, PointCloud& final_cloud,PointCloud::Ptr cloud_src_o, PointCloud::Ptr cloud_tgt_o,FPFH::Ptr & src_fpfhs, FPFH::Ptr& tgt_fpfhs)
{sac_ia.setInputSource(cloud_src_o);sac_ia.setSourceFeatures(src_fpfhs);sac_ia.setInputTarget(cloud_tgt_o);sac_ia.setTargetFeatures(tgt_fpfhs);// 设置SAC-IA配准的参数sac_ia.setMinSampleDistance(0.05f);sac_ia.setMaxCorrespondenceDistance(0.01f);sac_ia.setMaximumIterations(500);// 创建一个空的PointCloud对象来接收结果pcl::PointCloud<pcl::PointXYZ> final_registration;// 执行配准,并将结果存储在final_registration中sac_ia.align(final_registration);return sac_ia;
}
NDT& ndt_registration(NDT & ndt, PointCloud& final_cloud,PointCloud::Ptr cloud_src_o, PointCloud::Ptr cloud_tgt_o)
{// 配置NDTndt.setTransformationEpsilon(0.1);ndt.setStepSize(0.5);ndt.setResolution(2.0);ndt.setMaximumIterations(20);ndt.setInputSource(cloud_src_o);ndt.setInputTarget(cloud_tgt_o);ndt.align(final_cloud);return ndt;
}ICP& icp_registration(ICP & icp, PointCloud & final_cloud, PointCloud::Ptr cloud_src_o, PointCloud::Ptr cloud_tgt_o)
{icp.setMaximumIterations(50);// 两次变化矩阵之间的差值icp.setTransformationEpsilon(1e-10);// 均方误差icp.setEuclideanFitnessEpsilon(0.01);icp.setInputSource(cloud_src_o);//录入source点云icp.setInputTarget(cloud_tgt_o);//录入target点云icp.align(final_cloud);//最终配准结果return icp;
}
int main(int argc, char** argv)
{//加载点云文件PointCloud::Ptr cloud_src_o(new pcl::PointCloud<pcl::PointXYZ>);//原点云,待配准pcl::io::loadPLYFile("ply/bun_zipper.ply", *cloud_src_o);PointCloud::Ptr cloud_tgt_o(new pcl::PointCloud<pcl::PointXYZ>);//目标点云pcl::io::loadPLYFile("ply/bun_zipper2.ply", *cloud_tgt_o);clock_t start = clock();//下采样pcl::VoxelGrid<pcl::PointXYZ>::Ptr voxel_grid(new pcl::VoxelGrid<pcl::PointXYZ>);downsampling(cloud_src_o, cloud_tgt_o, voxel_grid);创建一个NormalEstimationOMP对象,进行法线计算NormalEstimation ne;Normal::Ptr src_normals(new pcl::PointCloud<pcl::Normal>);Normal::Ptr tgt_normals(new pcl::PointCloud<pcl::Normal>);KdTreeT::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>());normalestimation(ne, src_normals, tgt_normals, tree, cloud_src_o, cloud_tgt_o);//计算FPFH特征/*FPFHEstimation fpfh;FPFH::Ptr src_fpfhs(new pcl::PointCloud<pcl::FPFHSignature33>());FPFH::Ptr tgt_fpfhs(new pcl::PointCloud<pcl::FPFHSignature33>());fpfh_features(fpfh, src_fpfhs, tgt_fpfhs, cloud_src_o, cloud_tgt_o, tree, src_normals, tgt_normals);*/// 点云配准PointCloud::Ptr icp_result(new pcl::PointCloud<pcl::PointXYZ>);PointCloud final_cloud;ICP icp;ICP & reg_p = icp_registration(icp, final_cloud, cloud_src_o, cloud_tgt_o);/*NDT ndt;NDT & reg_p = ndt_registration(ndt, final_cloud, cloud_src_o, cloud_tgt_o);*//*GICP gicp;GICP& reg_p = gicp_registration(gicp, final_cloud, cloud_src_o, cloud_tgt_o);*///SAC_IA sac_ia;//SAC_IA& reg_p = sacia_registration(sac_ia, final_cloud, cloud_src_o, cloud_tgt_o, src_fpfhs, tgt_fpfhs);clock_t end = clock();cout << "total time: " << (double)(end - start) / (double)CLOCKS_PER_SEC << " s" << endl;//输出配准所用时间cout << "ICP has converged:" << reg_p.hasConverged() << " score: " << reg_p.getFitnessScore() << std::endl;Eigen::Matrix4f reg_p_trans;// 变换矩阵reg_p_trans = reg_p.getFinalTransformation();// 平移向量Eigen::Vector3f translation = reg_p_trans.block<3, 1>(0, 3);// 旋转矩阵Eigen::Matrix3f rotation = reg_p_trans.block<3, 3>(0, 0);// 转换为四元数Eigen::Quaternionf quaternion(rotation);// 使用四元数重新计算欧拉角Eigen::Vector3f euler_angles_rad = quaternion.toRotationMatrix().eulerAngles(2, 1, 0);获取欧拉角(弧度)//Eigen::Vector3f euler_angles_rad = rotation.eulerAngles(0, 1, 2);// 将弧度转换为角度Eigen::Vector3f euler_angles_deg = euler_angles_rad * 180.0 / M_PI;printinfo(reg_p_trans, rotation, translation, euler_angles_deg, quaternion);//使用创建的变换对未过滤的输入点云进行变换pcl::transformPointCloud(*cloud_src_o, *icp_result, reg_p_trans);visualize_pcd(cloud_src_o, cloud_tgt_o, icp_result);return (0);
}

这里面有四种点云配准方法,ICP,NDT,GICP,SAC-IA,其中使用SAC-IA的时候要把fpfh计算的代码解开注释,其他算法使用的时候不需要解开fpfh计算的代码;提醒下,fpfh和SAC-IA计算较为缓慢,出结果需要四五分钟

这份配准所需点云文件链接:

链接:https://pan.baidu.com/s/1QduGSfYcMN2MLRa08e0eSg 
提取码:wstc 

六、保存配置

为了在以后新建项目时不重复进行第三部分的配置,可以保存属性表;点击visual studio2022的视图下的其他窗口,找到属性管理器,点击

下方会出现属性管理器的字样,点击

然后右键Debug | x64,点击添加新项目属性表

随便命个名,点击添加,我命名为PCL.props

这里就会出现PCL的属性表,双击之后,重复,第三部分的配置即可,这个属性表会保存在和你的cpp文件的同级目录下

然后你就可以新建一个项目,在新项目中也找到Debug | x64,右键添加现有属性表,找到我们刚才配置的PCL.props,就可以导入我们刚才的配置了

六、未来如果你要用PCL做某些大型项目,可能会遇到 fatal error C1128: 节数超过对象文件格式限制: 请使用 /bigobj 进行编译,这种问题,解决方法:

打开该项目的“属性页”对话框,单击“C/C++”项,单击“命令行”属性页,在“附加选项”框中键入编译器选项,添加 /bigobj,再次编译即可。

在 Visual Studio 中使用 /bigobj 编译选项的主要好处是允许生成更大的对象文件。这是通过扩展 COFF(Common Object File Format)的限制来实现的。以下是 /bigobj 选项的一些具体好处:

  1. 增加节的数量限制: 正常情况下,COFF 格式的对象文件有限制,例如节的数量不能超过 2^16-1(65535)。使用 /bigobj 可以将这个限制提高到 2^32-1(约 4.29 亿),这对于包含大量代码的大型项目非常有用。

  2. 提供更多的符号: 对于有大量符号(例如函数、变量、模板实例化)的代码,/bigobj 也提供了更多的符号支持。

  3. 处理复杂的模板: 使用大量模板特化和模板元编程的 C++ 代码可能会生成非常大的对象文件。/bigobj 让编译器能够处理这些复杂的模板情况。

  4. 适用于大型项目: 对于非常大的项目,尤其是那些有大量源代码文件或者是由多个库组合而成的项目,使用 /bigobj 选项可以避免在编译过程中出现对象文件格式限制的错误。

使用 /bigobj 选项没有显著的缺点,除了可能会增加编译后的对象文件大小。然而,它确实是解决某些大型或复杂项目导致的对象文件格式限制问题的必要手段。如果你的项目没有遇到相关的编译限制问题,那么通常不需要使用这个选项。

PCL使用SAC-IA \ICP\NDT\GICP进行点云配准-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/255414.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python进阶--爬取美女图片壁纸(基于回车桌面网的爬虫程序)

目录 一、前言 二、爬取下载美女图片 1、抓包分析 a、分析页面 b、明确需求 c、抓包搜寻 d、总结特点 2、编写爬虫代码 a、获取图片页网页源代码 b、提取所有图片的链接和标题 c、下载并保存这组图片 d、 爬取目录页的各种类型美女图片的链接 e、实现翻页 三、各…

【十四】【C++】list 的常见用法

list 的初始化和遍历 /*list的初始化和遍历*/ #if 1 #include <list> #include <vector> #include <iostream> #include<algorithm> using namespace std;void TestList1(){list<int> L1;list<int> L2(10, 5);vector<int> v{1,2,3,4…

精灵图,字体图标,CSS3三角

精灵图 1.1为什么需要精灵图 一个网页中往往会应用很多小的背景图像作为修饰&#xff0c;当网页中的图像过多时&#xff0c;服务器就会频繁的接受和发送请求图片&#xff0c;造成服务器请求压力过大&#xff0c;这将大大降低页面的加载速度。 因此&#xff0c;为了有效地减少…

【踏雪无痕的痕二】——小学一年级数学题窥探蝴蝶效应

目录 一、背景介绍二、思路&方案三、过程1.结果一致过程不一致带来的偏差2.再举两个例子&#xff0c;你品一品3.我曾经的培养计划背后的"力量"&#xff1f;4.蝴蝶效应——混沌或非线性理论什么是蝴蝶效应&#xff1f; 5.内心深处的小恶魔(人性的使然) 四、总结 一…

Java基础知识总结(持续更新中)

Java基础知识&#xff08;持续更新&#xff09; 类型转化&#xff1a;数字、字符串、字符之间相互转化 数字 <-> 字符串 // 数字转字符串 // method1int number 5;String str String.valueOf(number);// method2int number 5;Integer itr number; //int装箱为对…

使用耳机壳UV树脂制作一个耳机壳需要多长时间?

使用耳机壳UV树脂制作一个耳机壳所需的时间取决于多个因素&#xff0c;包括工艺流程、加工方式、设备和技术水平等。一般来说&#xff0c;制作一个耳机壳需要数小时到数天不等。 以下是影响制作时间的几个主要因素&#xff1a; 获取耳模时间&#xff1a;获取耳模的时间取决于…

数据库学习案例20240206-ORACLE NEW RAC agent and resource关系汇总。

1 集群架构图 整体集群架构图如下&#xff1a; 1 数据库启动顺序OHASD层面 操作系统进程init.ohasd run启动ohasd.bin init.ohasd run 集群自动启动是否被禁用 crsctl enable has/crsGIHOME所在文件系统是否被正常挂载。管道文件npohasd是否能够被访问&#xff0c; cd /var/t…

口腔助手|口腔挂号预约小程序|基于微信小程序的口腔门诊预约系统的设计与实现(源码+数据库+文档)

口腔小程序目录 目录 基于微信小程序的口腔门诊预约系统的设计与实现 一、前言 二、系统功能设计 三、系统实现 1、小程序前台界面实现 2、后台管理员模块实现 四、数据库设计 1、实体ER图 2、具体的表设计如下所示&#xff1a; 五、核心代码 六、论文参考 七、最新…

Spark安装(Yarn模式)

一、解压 链接&#xff1a;https://pan.baidu.com/s/1O8u1SEuLOQv2Yietea_Uxg 提取码&#xff1a;mb4h tar -zxvf /opt/software/spark-3.0.3-bin-hadoop3.2.tgz -C /opt/module/spark-yarn mv spark-3.0.3-bin-hadoop3.2/ spark-yarn 二、配置环境变量 vim /etc/profile…

空气质量预测 | Matlab实现基于SVR支持向量机回归的空气质量预测模型

文章目录 效果一览文章概述源码设计参考资料效果一览 文章概述 政府机构使用空气质量指数 (AQI) 向公众传达当前空气污染程度或预测空气污染程度。 随着 AQI 的上升,公共卫生风险也会增加。 不同国家有自己的空气质量指数,对应不同国家的空气质量标准。 基于支持向量机(Su…

【MATLAB源码-第138期】基于matlab的D2D蜂窝通信仿真,对比启发式算法,最优化算法和随机算法的性能。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 D2D蜂窝通信介绍 D2D蜂窝通信允许在同一蜂窝网络覆盖区域内的终端设备直接相互通信&#xff0c;而无需数据经过基站或网络核心部分转发。这种通信模式具有几个显著优点&#xff1a;首先&#xff0c;它可以显著降低通信延迟&…

Day30 回溯算法part06

又是眼红别人的一天 重新安排行程 菜鸡思路&#xff1a;把从jfk往下所有的情况都列举出来&#xff0c;result数组包含五个元素的时候返回数组。 我们只需要找到一个行程&#xff0c;就是在树形结构中唯一的一条通向叶子节点的路线 N皇后 这个isValid函数也很不好想啊 首先…

seata分布式事务

文章目录 1、分布式事务1.1 事务的ACID原则原子性一致性隔离性持久性 1.2 分布式事务的问题示例代码准备环境1. seata_demo数据库2. 启动nacos seata-demo父工程pom.xml order-servicepom.xmlapplication.ymlOrderApplicationOrderControllerOrderServiceImplAccountClientStor…

Elasticsearch:通过 ingest pipeline 对大型文档进行分块

在我之前的文章 “Elasticsearch&#xff1a;使用 LangChain 文档拆分器进行文档分块” 中&#xff0c;我详述了如何通过 LangChain 对大的文档进行分块。那个分块的动作是通过 LangChain 在 Python 中进行实现的。对于使用版权的开发者来说&#xff0c;我们实际上是可以通过 i…

【大厂AI课学习笔记】【1.6 人工智能基础知识】(1)人工智能、机器学习、深度学习之间的关系

6.1 人工智能、机器学习与深度学习的关系 必须要掌握的内容&#xff1a; 如上图&#xff1a;人工智能>机器学习>深度学习。 机器学习是人工智能的一个分支&#xff0c;该领域的主要研究对象是人工智能&#xff0c;特别是如何在经验学习中改进具体算法的性能。 深度学习…

TCP 传输控制协议——详细

目录 1 TCP 1.1 TCP 最主要的特点 1.2 TCP 的连接 TCP 连接&#xff0c;IP 地址&#xff0c;套接字 1.3 可靠传输的工作原理 1.3.1 停止等待协议 &#xff08;1&#xff09;无差错情况 &#xff08;2&#xff09;出现差错 &#xff08;3&#xff09;确认丢失和确认迟到…

【linux系统体验】-archlinux折腾日记

archlinux 一、系统安装二、系统配置及美化2.1 中文输入法2.2 安装virtualbox增强工具2.3 终端美化2.4 桌面面板美化 三、问题总结3.1 一、系统安装 安装步骤人们已经总结了很多很全: Arch Linux图文安装教程 大体步骤&#xff1a; 磁盘分区安装 Linux内核配置系统&#xff…

redis双写一致

redis双写一致&#xff0c;指的是redis缓存与mysql数据同步 双写一致常见方案有很多&#xff1a; 同步双写&#xff1a;更新完mysql后立即同时更新redis mq同步&#xff1a;程序在更新完mysql后&#xff0c;投递消息到中间键mq&#xff0c;一个程序监听mq&#xff0c;获得消…

基于Springboot的足球社区管理系统(有报告)。Javaee项目,springboot项目。

演示视频&#xff1a; 基于Springboot的足球社区管理系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构…

电力负荷预测 | Matlab实现基于LSTM长短期记忆神经网络的电力负荷预测模型(结合时间序列)

文章目录 效果一览文章概述源码设计参考资料效果一览 文章概述 电力负荷预测 | Matlab实现基于LSTM长短期记忆神经网络的电力负荷预测模型(结合时间序列) 所谓预测,就是指通过对事物进行分析及研究,并运用合理的方法探索事物的发展变化规律,对其未来发展做出预先估计和判断…