用liblas/laslib将点云写入las文件

本文详细介绍了如何使用liblas和laslib库将点云数据以LAS文件格式保存,包括设置文件头部信息、点坐标和颜色,以及解决可能遇到的问题如坐标类型转换和内存问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

用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!!非常重要

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值