一、参考链接
1、LASlib / LAStools
2、LASlib库将PCL库点云类型数据转换为las格式保存
3、.las数据转.pcd并显示
las格式详解:
[1]孙爱怡,王健.LAS格式的解析与转换[J].全球定位系统,2016,41(02):115-117+124.
二、代码
#include "lasreader.hpp"
#include "laswriter.hpp"
#include"LasReadWrite.h"
/* read las */
void LasLib::ReadLas(const std::string& LasPath, pcl::PointCloud<PointT>::Ptr& Read_cloud)
{
LASreadOpener lasReadOpener;
lasReadOpener.set_file_name(LasPath.data());
//lasReadOpener.set_file_name(sLasPath.c_str());
LASreader* lasReader = lasReadOpener.open(false);
#pragma region Las information
int majorVersion = lasReader->header.version_major; // las文件的版本号
int minorVersion = lasReader->header.version_minor;
int pointDataFormat = lasReader->header.point_data_format; // Lidar点的记录格式
int pointAmount = lasReader->header.number_of_point_records;// Lidar点的个数
double maxX = lasReader->header.max_x; // x坐标的最大值
double minX = lasReader->header.min_x; // x坐标的最小值
double maxY = lasReader->header.max_y; // y坐标的最大值
double minY = lasReader->header.min_y; // y坐标的最小值
double maxZ = lasReader->header.max_z; // z坐标的最大值
double minZ = lasReader->header.min_z; // z坐标的最小值
double deltaX = maxX - minX; // x坐标的取值范围
double deltaY = maxY - minY; // y坐标的取值范围
double deltaZ = maxZ - minZ; // z坐标的取值范围
double xOffset = lasReader->header.x_offset; // X方向的偏移量
double yOffset = lasReader->header.y_offset; // Y方向的偏移量
double zOffset = lasReader->header.z_offset; // Z方向的偏移量
double xScale = lasReader->header.x_scale_factor; // X方向的比例尺因子
double yScale = lasReader->header.y_scale_factor; // Y方向的比例尺因子
double zScale = lasReader->header.z_scale_factor; // Z方向的比例尺因子
#pragma endregion
int pNumber = 0;
while (lasReader->read_point())
{
LASpoint& pointReader = lasReader->point;
PointT p;
p.x = pointReader.get_x()- xOffset;
p.y = pointReader.get_y()- yOffset;
p.z = pointReader.get_z()- zOffset;
//p.r = pointReader.get_R();
//p.g = pointReader.get_G();
//p.b = pointReader.get_B();
//p.intensity = pointReader.get_intensity();
//p.pointSourceID = pointReader.get_point_source_ID();
//p.GPStime = pointReader.get_gps_time();
//p.classification = pointReader.get_classification();
Read_cloud->points.push_back(p);
pNumber++;
#pragma endregion
}
lasReader->close();
delete lasReader;
lasReader = nullptr;
}
/* write las */
void LasLib::WriteLas(const std::string& sResultPath, pcl::PointCloud<PointT>::Ptr& Write_cloud)
{
LASwriteOpener lasWriterOpener;
lasWriterOpener.set_file_name(sResultPath.data());
// init header
LASheader lasHeader;
lasHeader.x_scale_factor = 0.0001;
lasHeader.y_scale_factor = 0.0001;
lasHeader.z_scale_factor = 0.0001;
lasHeader.x_offset = (int)Write_cloud->points[0].x;
lasHeader.y_offset = (int)Write_cloud->points[0].y;
lasHeader.z_offset = (int)Write_cloud->points[0].z;
lasHeader.point_data_format = 3;
lasHeader.point_data_record_length = 34; // 变长记录
//lasHeader.number_of_point_records = vPoints.size();
// open laswriter
LASwriter* lasWriter = lasWriterOpener.open(&lasHeader);
// init point
LASpoint lasPoint;
lasPoint.init(&lasHeader, lasHeader.point_data_format, lasHeader.point_data_record_length, 0);
// write points
double minX = DBL_MAX, minY = DBL_MAX, minZ = DBL_MAX;
double maxX = -DBL_MAX, maxY = -DBL_MAX, maxZ = -DBL_MAX;
for (int i = 0; i < Write_cloud->points.size(); i++)
{
// populate the point
lasPoint.set_x(Write_cloud->points[i].x);
lasPoint.set_y(Write_cloud->points[i].y);
lasPoint.set_z(Write_cloud->points[i].z);
//lasPoint.set_R(write_cloud->points[i].r);
//lasPoint.set_G(write_cloud->points[i].g);
//lasPoint.set_B(write_cloud->points[i].b);
//lasPoint.set_intensity(write_cloud->points[i].intensity);
//lasPoint.set_point_source_ID(write_cloud->points[i].pointSourceID);
//lasPoint.set_gps_time(write_cloud->points[i].GPStime);
//lasPoint.set_classification(write_cloud->points[i].classification);
// write the point
lasWriter->write_point(&lasPoint);
// add it to the inventory
lasWriter->update_inventory(&lasPoint);
//range
double x = Write_cloud->points[i].x;
double y = Write_cloud->points[i].y;
double z = Write_cloud->points[i].z;
if (x < minX) minX = x;
if (x > maxX) maxX = x;
if (y < minY) minY = y;
if (y > maxY) maxY = y;
if (z < minZ) minZ = z;
if (z > maxZ) maxZ = z;
}
// update the boundary
lasHeader.set_bounding_box(minX, minY, minZ, maxX, maxY, maxZ);
// update the header
lasWriter->update_header(&lasHeader, true);
// close the writer
lasWriter->close();
delete lasWriter;
lasWriter = nullptr;
}