环境:visual studio2022,libLAS1.8。
目录
visual studio2022编译依赖静态库gdal
版本:gdal2.4.1
- 在地址上下载源码,这里我选择的是2.4.1版本。将其解压放置libLAS根目录下
- 在cmd窗口下进入vcvars64.bat所在的目录执行该脚本
- 更改gdal-2.4.1根目录下的nmake.opt配置文件
# 更改GDAL_HOME的值
GDAL_HOME = "C:\Users\wzh\Desktop\libLAS\gdal-2.4.1\installlation"
- 进入gdal-2.4.1项目的根目录,分别执行以下命令:
- 执行过程中报错gdal-2.4.1\ogr\ogrlinestring.cpp(2554): error C2039: "fabs": 不是 "std" 的成员:将ogrlinestring.cpp中的fas前的
std::
删除
# 变量MSVC_VER的值可以在集成开发环境vs中查看_MSC_VER的值 nmake -f makefile.vc MSVC_VER=1939 WIN64=1
- 执行
nmake -f makefile.vc MSVC_VER=1939 WIN64=1 install
- 执行
nmake -f makefile.vc MSVC_VER=1939 WIN64=1 devinstall
- 执行过程中报错gdal-2.4.1\ogr\ogrlinestring.cpp(2554): error C2039: "fabs": 不是 "std" 的成员:将ogrlinestring.cpp中的fas前的
- 成功后,将会在GDAL_HOME目录下生成如下文件
visual studio2022编译依赖静态库geotiff
1.编译libtiff
- 在地址上下载libtiff,这里我下载的是4.0.6.将其解压放置libLAS根目录下
- 进入tiff-4.0.6根目录下,执行
nmake -f makefile.vc MSVC_VER=1939 WIN64=1
中报错libtiff\tiffiop.h(62): note: 参见“snprintf”的前一个定义
,打开tiffiop.h文件,将如下内容注释:
//#if !defined(HAVE_SNPRINTF) && !defined(HAVE__SNPRINTF)
//#undef snprintf
//#define snprintf _TIFF_snprintf_f
//extern int snprintf(char* str, size_t size, const char* format, ...);
//#endif
- 上述步骤执行成功,会在tiff-4.0.6\libtiff目录下生成库文件等
2.编译geotiff
- 在地址上下载geotiff,这里下载的是1.2.5。将其解压放置libLAS根目录下
- 将编译libtiff时,项目根目录下的libtiff目录复制到libLAS\libgeotiff-1.2.5目录下
- 进入libgeotiff-1.2.5目录下,分别执行
- nmake -f makefile.vc MSVC_VER=1939 WIN64=1
- nmake -f makefile.vc MSVC_VER=1939 WIN64=1 install
- nmake -f makefile.vc MSVC_VER=1939 WIN64=1 devinstall
visual studio2022编译依赖静态库zlib
我使用的版本为1.2.11。这个教程较多,省略。
visual studio2022编译依赖静态库liblas
由于本次PCL读取las格式的点云数据文件使用第三方libLAS库,地址为:https://github.com/libLAS/libLAS
。为了方便使用,将其编译成静态lib。以Debug版本的静态库为例,编译Release版本的静态库雷同,步骤如下:
- 打开vs创建新项目,模板类型选择库=》静态库
- 位置选择克隆项目的根目录
- 然后移除liblas项目下的源文件
- 将liblas目录下的四个文件复制到libLAS根目录下,并将liblas目录删除。目录调整结构如下:
- 打开liblas.sln文件,右击头文件、源文件将需要编译的文件加进来:主要是src目录以及include目录
- libLAS项目根目录下新建libs目录,将boost,gdal,geotiff,tiff,zip这些静态库放置该目录下。其中boost相关的静态库不用再编译了,可以在PCL 1.13.0\3rdParty\Boost\lib目录下找到。
- 将boost,gdal,geotiff,tiff,zip这些库的头文件放置libLAS\include目录下。其中boost库的头文件在PCL 1.13.0\3rdParty\Boost\include目录下可以找到,可以直接拿来用。
- 在项目属性页中进行基本的配置
- 预编译头选择不使用
- 配置属性=》VC++目录=》包含目录进行头文件目录的包含,新增如下内容:
.\include .\include\gdal_2.4.1 .\include\libgeotiff-debug .\include\libtiff .\include\boost .\include\zip
- 将安装好的PCL1.13.0
PCL 1.13.0\3rdParty\Boost\include\boost-1_80
目录下的boost文件夹复制到libLAS\include目录下
- 配置属性=》VC++目录=》库目录进行依赖库的包含,新增如下内容
.\libs
- 配置属性=》C/C++=》预处理器中新增预处理器定义如下:
_CRT_SECURE_NO_WARNINGS BOOST_BIND_GLOBAL_PLACEHOLDERS
- 编译过程中遇到一个问题:
xxx.obj : warning LNK4042: 对象被多次指定;已忽略多余的指定
,解决方法是更改编译输出的文件名,如下所示:
- 最终进行编译,会在输出目录下生成静态库
在plc项目中读取las格式的点云数据文件
- 示例代码如下:
#include "liblas/liblas.hpp"
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <boost/thread/thread.hpp>
#include <vector>
int main(int argc, char** argv)
{
// 读取las文件
std::ifstream ifs("./dataset/祖庙牌坊.las", std::ios::in | std::ios::binary);
liblas::ReaderFactory f;
liblas::Reader reader = f.CreateWithStream(ifs);
//获取las数据点的个数
unsigned long int nPoints = reader.GetHeader().GetPointRecordsCount();
// 初始化点云
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
cloud->width = nPoints;
cloud->height = 1;
cloud->resize(nPoints);
std::vector<uint8_t> pclassification(nPoints); //记录类别信息
std::vector<liblas::Color> pcolor(nPoints); //记录颜色信息
std::vector<uint16_t> pintencity(nPoints); //记录强度信息
for (int i = 0; i < nPoints; i++)
{
reader.ReadNextPoint();
const liblas::Point& p = reader.GetPoint();
float px = (float)p.GetX();
float py = (float)p.GetY();
float pz = (float)p.GetZ();
(*cloud)[i].x = px;
(*cloud)[i].y = py;
(*cloud)[i].z = pz;
pclassification[i] = p.GetClassification().GetClass();
pcolor[i] = p.GetColor();
pintencity[i] = p.GetIntensity();
}
ifs.close();
boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("3D Viewer"));
viewer->setBackgroundColor(0, 0, 0);
viewer->setWindowName("可视化las格式的点云");
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> cloud_color(cloud, 0, 0, 255);
viewer->addPointCloud<pcl::PointXYZ>(cloud, cloud_color, "sample cloud");
viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "sample cloud");
while (!viewer->wasStopped())
{
viewer->spinOnce(100);
boost::this_thread::sleep(boost::posix_time::microseconds(100000));
}
return 0;
}