用liblas/laslib将点云写入las文件
用liblas将点云写入las文件
首先配置liblas库,可以见上一篇博客
inline int writeLas(string lasPath, Points3Ds pt3Ds) {//point3ds是我自己定义的结构
std::ofstream ofs;
ofs.open(lasPath, std::ios::out | std::ios::binary);
if (!ofs.is_open()) {
std::cerr << "无法创建 LAS 文件" << std::endl;
return 1;
}
// 设置 LAS 文件的头部信息
liblas::Header header;
header.SetVersionMajor(1);
header.SetVersionMinor(2);
header.SetDataFormatId(liblas::ePointFormat2);
header.SetScale(0.00001, 0.00001, 0.00001);//要设置,不然保存的就是整形xyz
int pointsNum = pt3Ds.size(); //获取点数
header.SetPointRecordsCount(pointsNum); //设置点数
// 创建一个 LAS 写入器
liblas::Writer writer(ofs, header);
liblas::Point point(&header);
//记录数据范围
double minx = 99999999;
double miny = 99999999;
double minz = 99999999;
double maxx = -99999999;
double maxy = -99999999;
double maxz = -99999999;
// 遍历点云数据,添加到 LAS 文件中
for (const auto& pd : pt3Ds) {
// 设置点的坐标
double tx = pd.second.x;
double ty = pd.second.y;
double tz = pd.second.z;
minx = minx > tx ? tx : minx;
miny = miny > ty ? ty : miny;
minz = minz > tz ? tz : minz;
maxx = maxx < tx ? tx : maxx;
maxy = maxy < ty ? ty : maxy;
maxz = maxz < tz ? tz : maxz;
point.SetX(tx);
point.SetY(ty);
point.SetZ(tz);
// 设置点的颜色
liblas::Color color;
color.SetRed(pd.second.r);
color.SetGreen(pd.second.g);
color.SetBlue(pd.second.b);
point.SetColor(color);
// 将点写入文件
writer.WritePoint(point);
}
header.SetMax(maxx, maxy, maxz); //设置数据范围
header.SetMin(minx, miny, minz);
//(若中间处理过程点数有变化的话,可以通过此方法进行修改)
//(若无变动,则可以在一开始就设置点数)
writer.SetHeader(header); //设置文件头
writer.WriteHeader(); //重写文件头
// 关闭文件
ofs.close();
std::cout << "LAS 文件创建成功。" << std::endl;
return 0;
},
其中一定要SetScale啊,搞了很久!
在debug模式下可以顺利保存点云,但是release下报内存问题,没找到原因!
放弃准备用laslib试试
用laslib点云写入las文件
#include "LASlib\laswriter.hpp"
inline int writeLas(string lasPath, Points3Ds pt3Ds) {
// 创建和配置 LASwriteOpener
LASwriteOpener laswriteopener;
laswriteopener.set_file_name(lasPath.c_str());
// 是否创建成功
if (!laswriteopener.active()) {
std::cout << "Failed!\n";
return -1;
}
if (pt3Ds.size() == 0) {
std::cout << "empty point cloud,Please check!";
return -1;
}
// 创建和配置 LASheader
LASheader lasheader;
lasheader.x_scale_factor = 0.0001;
lasheader.y_scale_factor = 0.0001;
lasheader.z_scale_factor = 0.0001;
if (!pt3Ds.empty()) {
lasheader.x_offset =(int) pt3Ds.begin()->second.x;//以第一个点设置偏移量
lasheader.y_offset = (int)pt3Ds.begin()->second.y;
lasheader.z_offset = (int)pt3Ds.begin()->second.z;
}
lasheader.point_data_format = 3;
lasheader.point_data_record_length = 34;
// 设置其他必要的头部信息,如投影信息,点云范围等
LASwriter* laswriter = laswriteopener.open(&lasheader);
if (laswriter == 0) {
std::cout << "Failed!\n";
return -1;
}
// 创建 LASpoint
LASpoint laspoint;
laspoint.init(&lasheader, lasheader.point_data_format, lasheader.point_data_record_length, 0);
double minX = DBL_MAX, minY = DBL_MAX, minZ = DBL_MAX;
double maxX = -DBL_MAX, maxY = -DBL_MAX, maxZ = -DBL_MAX;
for (const auto& pd : pt3Ds) {
double x = pd.second.x;
double y = pd.second.y;
double z = pd.second.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;
laspoint.set_X((pd.second.x- lasheader.x_offset)/ lasheader.x_scale_factor);
laspoint.set_Y((pd.second.y- lasheader.y_offset)/ lasheader.y_scale_factor);
laspoint.set_Z((pd.second.z - lasheader.z_offset) / lasheader.z_scale_factor);
laspoint.set_point_source_ID(pd.first);
laspoint.set_R(pd.second.r);
laspoint.set_G(pd.second.g);
laspoint.set_B(pd.second.b);
//laspoint.set_intensity((U16)i);
//laspoint.set_gps_time(0.0006 * i);
laswriter->write_point(&laspoint);
laswriter->update_inventory(&laspoint);
}
// update the boundary
lasheader.set_bounding_box(minX, minY, minZ, maxX, maxY, maxZ);
// 关闭流
laswriter->update_header(&lasheader, TRUE);
laswriter->close();
delete laswriter;
laswriter = nullptr;
return 0;
}
如果出现写入las后发现点云的坐标是整形,那就要记得设置偏移量和scale_factor!!非常重要