资讯详情

资讯详情

VS2017配置PCL 1.9.1:Windows点云开发环境搭建与排错全攻略

VS2017配置PCL 1.9.1win10系统下几乎是每个入门点云处理的同学都要迈的一道坎。说它是坎不是因为PCL本身多难而是这套组合里每一步都藏着细节预编译包和VS版本必须匹配、第三方依赖多到记不住、环境变量漏一个就全局崩盘。这篇文章是我自己从零到一配置PCL 1.9.1的完整实操记录从下载安装、工程属性配置、跑通第一个Demo到最后把常见的报错链路全部梳理一遍适合刚接触三维点云、准备在Windows上搭开发环境的人直接照着抄。1. 版本匹配才是PCL配置的头等大事1.1 官方预编译包和VS版本之间的ABI绑定关系很多人配置PCL第一个坑就是版本乱配。PCL官方虽然开源但Windows下最省事的做法是直接下载编译好的Release包而这个Release包是用特定版本的Visual Studio编译出来的。PCL 1.9.1官方提供的Windows安装包绑定的是MSVC 2017工具集平台工具集V141也就是说它默认就是为了VS2017准备的。这个约束的核心原因是C ABI二进制接口兼容性问题。VS2015、VS2017、VS2019、VS2022虽然说从VS2015开始C二进制兼容性做得不错但PCL 1.9.1的预编译库依赖的运行时库、STL实现细节仍然是基于VS2017那一代工具链生成的。你拿VS2015去链接可能运气好也能过但一旦触发_ITERATOR_DEBUG_LEVEL、_CONTAINER_DEBUG_LEVEL这类检查会直接给你一堆莫名其妙的LNK2038错误。拿VS2019或VS2022新建工程去连PCL 1.9.1也经常出现库文件不匹配、符号解析失败的问题。我的建议很直接既然标题是VS2017配置PCL1.9.1那就老老实实用VS2017平台工具集保持默认的V141不要乱动。如果你机器上已经装了VS2019或者VS2022也没关系多版本VS可以共存新工程指定平台工具集为“Visual Studio 2017 (v141)”也能编但新手阶段没必要给自己增加变量。1.2 装VS2017之前先确认这些组件和系统前提安装VS2017时不要一路默认安装。默认的工作负载不一定包含C桌面开发环境后面你新建项目时连pcl/point_types.h都找不到。在Visual Studio Installer里必须勾选“使用C的桌面开发”这一个工作负载。它会自动带上MSVC V141工具集、Windows 10 SDK以及C调试器。有个小建议在VS Installer右侧的“单个组件”里可以顺便把“C CMake tools for Windows”勾上。PCL官方推荐用CMake管理工程后面你想把项目转成CMake结构的时候会发现这个组件非常有用。Windows 10 SDK版本不用刻意追求最新系统自带的默认版本即可关键是和项目属性里“Windows SDK 版本”保持下拉框所选一致。另外PCL 1.9.1官方同时提供了win32和win64的预编译包但我强烈建议一律使用win64版本。点云处理动不动就是几十万上百万个点32位进程地址空间只有2GB很容易爆内存而且PCL里的VTK可视化模块在64位下稳定得多。后续在VS里也要记得把平台切到x64这件事我放到第3章细说。2. 下载与安装PCL 1.9.1主程序、调试符号和第三方库一次理清2.1 需要下载的文件各自派什么用场PCL 1.9.1在GitHub Release页面和官方SourceForge上都能找到国内网络环境下可以优先试试清华镜像或中科大镜像里对应的pcl目录下载速度会友好很多。需要下载的文件主要看三个文件体积作用PCL-1.9.1-AllInOne-msvc2017-win64.exe几百MB级别主安装包包含PCL库本身以及大部分第三方依赖pcl-1.9.1-pdb-msvc2017-win64.zip几十MB级别PCL各模块的调试符号文件出Bug时能定位到PCL源码内部第三方依赖包如OpenNI2相关按需深度相机驱动支持普通点云处理不需要不要忽略PDB文件。新手可能觉得PDB没用但当你哪天真去查一个崩溃堆栈没有PDB你看到的全是地址偏移量有了PDB就能看到PCL库内部的具体函数名排查效率完全是两个级别。2.2 安装目录怎么选OpenNI2勾不勾安装目录是第一个容易被忽视的坑。PCL默认安装路径是C:\Program Files\PCL 1.9.1这个路径带空格和Program Files目录虽然官方安装包和VS2017项目配置都能处理但后续如果你要用CMake、写批处理脚本、或者和其他工具链集成路径里的空格经常引发一些奇奇怪怪的解析问题。所以我在自己的电脑上习惯手动改成C:\PCL或D:\PCL全程路径不带空格、不带中文。这一步能帮你以后省掉大量排查时间。安装过程中有一个OpenNI2的勾选项它是用来支持Kinect、华硕Xtion这类RGB-D深度相机的。如果你只是处理PCD文件或激光雷达点云完全不装也没问题如果你有深度相机开发需求建议勾上它只是额外多几个驱动库不影响其他功能。2.3 环境变量配置PCL_ROOT和Path怎么补安装完成后先验证安装目录结构。正常情况应该能看到bin、include、lib、cmake和3rdParty这几个核心目录。3rdParty下面应该包含Boost、Eigen、FLANN、Qhull、VTK 8.1等依赖库这就说明AllInOne包确实把第三方依赖全部打包好了。接下来配置环境变量。Win10直接按Win键搜索“编辑系统环境变量”打开“高级”选项卡里的“环境变量”新建一个系统变量变量名PCL_ROOT变量值C:\PCL改成你自己的安装路径然后在系统变量Path里新建以下条目%PCL_ROOT%\bin%PCL_ROOT%\3rdParty\VTK\bin%PCL_ROOT%\3rdParty\FLANN\bin%PCL_ROOT%\3rdParty\Qhull\bin如果装了OpenNI2再加%PCL_ROOT%\3rdParty\OpenNI2\Redist和%PCL_ROOT%\3rdParty\OpenNI2\Tools这里特别提醒一下配置完环境变量之后已经打开的VS2017必须要全部关闭再重新打开或者干脆重启一下电脑否则Path不会刷新到VS的进程环境里。很多教程没说这一步导致用户明明配置好了却还是报找不到DLL其实是VS压根没读到新环境变量。3. VS2017项目属性配置一步步来别跳步3.1 新建项目并切换x64打开VS2017新建一个空项目名字随意比如PCLDemo。创建完成之后第一件事不是写代码而是检查工具栏上的解决方案平台。默认是x86但因为前面下载安装的是win64版本必须把平台切到x64。在“解决方案平台”下拉框里选择“配置管理器”在“活动解决方案平台”里选“新建”创建x64平台。这一步漏掉的话编译时会出现LNK1112: 模块计算机类型“x86”与目标计算机类型“x64”冲突这种错误。字符串一看就是架构不匹配但新手第一反应往往是去百度这个具体报错而不是回头检查平台。3.2 包含目录和库目录六个路径缺一不可右键项目 → 属性先确认顶部的“配置”是Debug或Release都行但注意它只对当前配置生效。我建议现在就把Debug和Release分开配一遍因为两者的库文件不同后面我会专门讲库名规则。在“VC目录”下配置包含目录下面这份是我实际使用的列表假设安装路径是C:\PCLC:\PCL\include\pcl-1.9C:\PCL\3rdParty\Boost\include\boost-1_66C:\PCL\3rdParty\Eigen\eigen3C:\PCL\3rdParty\FLANN\includeC:\PCL\3rdParty\Qhull\includeC:\PCL\3rdParty\VTK\include\vtk-8.1如果你装了OpenNI2再加C:\PCL\3rdParty\OpenNI2\Include。这六个目录分别对应PCL核心头文件、Boost智能指针相关头文件、Eigen矩阵库、FLANN近邻搜索、Qhull凸包计算以及VTK可视化头文件。少了任何一个你在编译时都会遇到形形色色的“无法打开包含文件”错误。库目录同样在“VC目录”下配置C:\PCL\libC:\PCL\3rdParty\Boost\libC:\PCL\3rdParty\FLANN\libC:\PCL\3rdParty\Qhull\libC:\PCL\3rdParty\VTK\lib如果你只配置PCL自己的lib目录VTK相关的符号会在链接阶段全部报LNK2019。这不是玄学是PCL可视化模块底层确实依赖VTK你的程序必须把VTK库也送进链接器。3.3 附加依赖项Debug和Release的库名规则链接器设置是配置过程里最容易出问题的地方。先定位到“链接器” → “输入” → “附加依赖项”在这里把需要用到的.lib文件逐个加进去。PCL自己的库文件命名规则很简单Release版叫pcl_xxx.libDebug版叫pcl_xxx_debug.lib。所以Debug和Release配置必须分别填写不能一套走天下。对于新手我不建议手打一长串库名很容易拼错或者漏一个。更高效的姿势是打开C:\PCL\lib目录在资源管理器里按名字排序切换到Debug配置时全选所有带_debug后缀的lib文件把文件名全部复制出来粘贴到附加依赖项里切换到Release配置时全选不带_debug后缀的lib文件再粘贴一遍。VTK的库文件在C:\PCL\3rdParty\VTK\lib目录下命名规则是vtkxxx-8.1.libRelease和vtkxxx-8.1d.libDebug。同样按配置全选复制粘贴。这一步虽然会生成几十行库名看起来夸张但实际效果最稳能有效避免手写库列表时漏掉某个VTK模块。Boost不需要手动加lib因为Boost的头文件内部通过#pragma comment(lib)自动链接了库前提是Boost的库目录已经加进“VC目录”的库目录。只要你不去主动禁用这个机制Boost不会给你找麻烦。3.4 预处理定义与C标准NOMINMAX为什么必须加在“C/C” → “预处理器” → “预处理器定义”里把下面三个定义加进去_CRT_SECURE_NO_WARNINGS_SCL_SECURE_NO_WARNINGSNOMINMAX前两个是为了屏蔽老C风格函数比如strcpy、sprintf在MSVC下的安全警告。PCL源码里大量使用了这类函数不加的话编译日志会被警告刷屏但这还不是最严重的。最严重的是NOMINMAX。Windows的windows.h头文件里有min和max两个宏而PCL和Eigen大量使用std::min、std::max。如果你没有定义NOMINMAX这两个宏会把代码里的std::min强行替换成min轻则编译报错重则出现一堆匪夷所思的模板解析错误。你可能会看到类似error C2589: “(”:“::”右边的非法标记的报错一查百度告诉你要加NOMINMAX就是这个原因。另外在“C/C” → “语言” → “C语言标准”里建议显式选择“ISO C14”。PCL 1.9.1发布时C14正流行和它的源码兼容性最好。虽然VS2017默认支持C14但显式设置一次可以避免某些配置模板把它改成了更低标准。4. 第一个PCL程序生成点云、保存、再读回来显示4.1 完整代码与关键行解释配置完成后需要写一个程序验证整个链路。我第一个Demo不喜欢去下载外部PCD文件而是直接生成随机点云这样即使离线的机器也能跑通全流程。在项目中新建一个main.cpp粘贴以下代码#include pcl/io/pcd_io.h #include pcl/point_cloud.h #include pcl/point_types.h #include pcl/visualization/pcl_visualizer.h #include cstdlib #include ctime #include iostream int main(int argc, char** argv) { // 1. 生成随机点云 pcl::PointCloudpcl::PointXYZ::Ptr cloud(new pcl::PointCloudpcl::PointXYZ()); cloud-width 500; cloud-height 1; cloud-is_dense false; cloud-points.resize(cloud-width * cloud-height); std::srand(static_castunsigned int(std::time(nullptr))); for (size_t i 0; i cloud-points.size(); i) { cloud-points[i].x static_castfloat(std::rand() % 1000) / 100.0f; cloud-points[i].y static_castfloat(std::rand() % 1000) / 100.0f; cloud-points[i].z static_castfloat(std::rand() % 1000) / 100.0f; } // 2. 保存为PCD文件 pcl::io::savePCDFileBinary(random_cloud.pcd, *cloud); std::cout saved random_cloud.pcd, points cloud-size() std::endl; // 3. 读回PCD文件 pcl::PointCloudpcl::PointXYZ::Ptr loaded(new pcl::PointCloudpcl::PointXYZ()); if (pcl::io::loadPCDFilepcl::PointXYZ(random_cloud.pcd, *loaded) -1) { std::cerr read pcd failed std::endl; return -1; } std::cout loaded points loaded-size() std::endl; // 4. 可视化 pcl::visualization::PCLVisualizer viewer(PCL 1.9.1 Demo); viewer.setBackgroundColor(0, 0, 0); viewer.addPointCloudpcl::PointXYZ(loaded, scene); viewer.addCoordinateSystem(1.0); while (!viewer.wasStopped()) { viewer.spinOnce(100); } return 0; }整个流程非常清晰生成500个随机点 → 保存成二进制PCD → 再读回来 → 用PCLVisualizer显示。如果这一套走通说明IO模块、可视化模块、第三方依赖全部正常。4.2 调试会话的工作目录设置粘贴完代码后先别急着按F5。在项目属性 → “调试” → “工作目录”里把路径设置为$(ProjectDir)。这一步是很多人会踩的经典坑。我当年第一次跑这个Demo时程序直接崩溃控制台提示找不到random_cloud.pcd。原因很简单默认情况下程序的工作目录不是项目目录而是x64\Debug输出目录代码里用相对路径写文件时PCD文件被写到了x64\Debug下面但下次运行时它又会在另一个目录去找文件自然找不到。设置$(ProjectDir)之后源码、PCD文件、运行结果全部对齐在同一个项目目录下再也不用到处找文件在哪。4.3 如何判断配置真正跑通按F5编译运行如果代码和配置都正确会发生两件事第一控制台窗口会依次打印saved random_cloud.pcd, points500和loaded points500说明PCL的IO模块完全可用。第二会弹出一个黑色背景的点云可视化窗口里面有一堆随机分布的点还有一个彩色坐标轴。你可以用鼠标左键旋转视角、滚轮缩放、右键平移说明VTK渲染管线也正常工作了。如果程序跑到这里窗口正常弹出恭喜你VS2017 PCL 1.9.1的整套配置就正式通关了。剩下的就是擦掉眼泪去跑真正的项目代码。5. 配置完成后依旧翻车的完整排查链路5.1 编译期错误打不开头文件、找不到源文件很多时候配置步骤看着都做了但编译时还是报C1083: 无法打开包含文件: pcl/point_types.h: No such file or directory。遇到这个错误不要慌按顺序排查三个位置。第一检查包含目录是否写对。特别是安装路径如果含有空格或中文VS的路径解析偶尔会出问题尽量用不带空格的路径。第二检查“解决方案平台”是不是x64有些配置步骤做完之后平台自动切回了x86那包含目录里的win64路径全部失效。第三检查“包含目录”是配置在项目属性而不是单个文件属性上。如果只把某个文件单独设置了包含目录删除或新建文件时设置就丢了。如果是C2039或者E0135这类错误一般是某个头文件内部依赖另一个头文件找不到大概率还是某个第三方目录漏配了。比如报Boost相关错误就回头检查Boost的include目录是否在列表里。5.2 链接期错误LNK2038、LNK2019的定位思路编译过了链接报错是配置PCL时最磨人的阶段。先说LNK2038这类错误。典型的错误信息是LNK2038: mismatch detected for _ITERATOR_DEBUG_LEVEL: value 2 doesnt match value 0这个错误翻译过来就是你当前配置的Debug/Release模式和链接的库文件不匹配。比如当前工程是Debug模式附加依赖项里却写的是不带_debug后缀的Release库马上触发这个错。解决方式就是回到第3.3节严格按照Debug和Release分别配置库文件。再说LNK2019这类无法解析的外部符号。这个错误的一个致命原因是VTK库没有被正确链接。比如你的代码里用了PCLVisualizer但附加依赖项只加了PCL的libVTK的lib一个没加链接器就会发现所有和VTK渲染相关的函数全部无法解析。另一个常见原因是附加依赖项里PCL库缺失比如你调用了pcl::io::loadPCDFile却只加了pcl_common.lib没加pcl_io.lib一样会报错。一个有用的排查思路看错误的符号名判断它属于哪个模块再回去检查那个模块的lib是否在附加依赖项里。比如看到pcl::visualization::PCLVisualizer::spinOnce就去检查pcl_visualization_debug.lib看到vtkRenderer::Render就去检查vtkRenderingCore-8.1d.lib。5.3 运行期错误缺DLL的处理顺序编译链接都过了双击运行或者按F5启动时弹出“由于找不到pcl_common.dll无法继续执行代码”这是环境变量没生效或者没配全。首先检查环境变量里Path是否加上了%PCL_ROOT%\bin然后确认是否重启过VS。如果加了还是报缺DLL就逐个补上VTK、FLANN、Qhull对应的bin目录。还不行就直接打开C:\PCL\bin目录看看缺失的DLL是否真的存在于这个目录里。有时候杀毒软件会把不常调用的DLL隔离掉这时候需要在确认文件来源可靠的前提下恢复文件。这里提个应急手段可以把C:\PCL\bin和C:\PCL\3rdParty\VTK\bin里的DLL全部复制到exe同目录程序立刻就能跑。但这个方式治标不治本后续换一个工程又要复制一遍正确方案还是把环境变量配好。5.4 混合项目冲突NOMINMAX之外的OpenCV/Qt共处问题如果你不只是做PCL还同时用OpenCV或者Qt会发现单独配置PCL没问题两个库放在一起就各种编译错误。最常见的还是min/max宏冲突这个用NOMINMAX可以解决。但如果两个库都定义了同名符号或者依赖了不同版本的Boost、Eigen冲突就会很复杂。我的经验是把PCL相关的包含目录尽量往后放或者把OpenCV等第三方库的包含目录往后放。因为PCL头文件内部包含顺序很敏感优先保证PCL自己的头文件不被其他库的头文件干扰。另外尽量保持工程里只有一个版本的Eigen。OpenCV自带的老版本Eigen和PCL 1.9.1自带的Eigen如果同时出现在包含路径里会出现eigen3/Eigen/Core找不到或版本宏不一致的问题。这类多库混合的问题最有效的办法是把不同库的包含目录严格控制在不同项目里不要让一个项目同时把PCL、OpenCV、Qt的头文件都塞进全局包含目录。6. 自检清单、CMake工程接入和后续版本建议6.1 配置自检清单按顺序打勾为避免配置完又不确定自己是否漏了哪一步我贴一份自己的自检清单照着逐项打勾检查项期望结果VS2017已安装“使用C的桌面开发”能新建C空项目PCL 1.9.1安装路径不带空格和中文推荐C:\PCL环境变量PCL_ROOT已配置echo %PCL_ROOT%能输出路径Path里包含PCL、VTK、FLANN、Qhull的bin目录系统找不到DLL的概率大幅降低解决方案平台为x64编译不报架构冲突包含目录六项齐全能打开pcl/point_types.h库目录五项齐全链接不报VTK相关LNK2019Debug配置加_debug后缀库清单Debug编译链接通过Release配置加普通库清单Release编译链接通过预处理定义含NOMINMAX不报min/max宏冲突Debug工作目录设为$(ProjectDir)PCD文件位置固定Demo程序能保存并读回PCD控制台打印点数Demo程序能弹可视化窗口VTK渲染正常6.2 在CMake工程中使用PCL避免重复踩坑手动配置VS工程只是第一步实际项目里我更推荐直接用CMake管理工程。PCL安装包自带的CMake配置文件就在C:\PCL\cmake下CMake能找到它你只需要在CMakeLists.txt里写cmake_minimum_required(VERSION 3.10) project(pcl_demo) set(CMAKE_CXX_STANDARD 14) find_package(PCL 1.9 REQUIRED COMPONENTS common io visualization) include_directories(${PCL_INCLUDE_DIRS}) add_definitions(${PCL_DEFINITIONS}) add_executable(pcl_demo main.cpp) target_link_libraries(pcl_demo ${PCL_LIBRARIES})find_package(PCL ...)这行是关键它会自动去读PCLConfig.cmake帮你把包含目录、库目录、依赖的VTK等第三方库全部配置好这比手动在VS属性页里填几十行路径省太多事。如果CMake提示找不到PCL在CMakeLists.txt里指定一下PCL_DIR变量指向C:\PCL\cmake即可。6.3 关于PCL更高版本与VS2017的边界配置完PCL 1.9.1之后很多人会问要不要升级到新版本。坦率说PCL官方后续几个版本逐渐把Windows预编译包转向了VS2019和VS2022工具链VS2017用户继续使用PCL 1.9.1是最省心的选择。PCL 1.9.1的功能已经覆盖了点云滤波、配准、分割、特征提取、可视化等核心模块入门学习和一般科研项目完全够用。如果你的项目确实需要新版PCL里的某些算法而你又不想折腾源码编译比较务实的路径是先升级到VS2019或VS2022再去用对应版本号的PCL预编译包。反过来坚持用VS2017的话停留在PCL 1.9.x系列是风险最小的。另外我个人的习惯是把配置好的VS属性保存成“属性表”Property Sheet具体做法是视图 → 属性管理器 → 右键项目 → 添加新项目属性表把第3章所有配置都写进去以后新建PCL工程直接双击导入包含目录、库目录、附加依赖项自动全部就位再也不用重新抄一遍路径。这个技巧我用了很久省下来的时间够多写好几个点云处理模块了。这次配置如果还有什么没说明白的地方欢迎在评论区把你的报错信息贴出来看到都会回。
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →