QT(VS) Lastools点云的头文件解析和文件读写

一、导入LasTools库

参考博客1:QT中配置LASLib实现.las格式点云文件读取
参考博客2:LAS点云的读写以及投影信息的读写(LASlib)
参考博客3:点云:LAStools / LASlib 读写点云
LAS文件格式描述PDF下载:官方下载PDF
下载好编译过的LasTools并解压

  • .pro文件中添加
#导入LasTools库
INCLUDEPATH += D:\LAStools\include\LASlib //.cpp文件以及.h文件路径
LIBS        += -LD:\LAStools\lib\LASlib\Release\  //.lib文件路径,我用的是release
               -lLASlib //lib文件具体名字

+= 是不覆盖追加
-L是转译,后面是导入lib文件的文件夹路径
-l是转译,引入lib文件

  • .h或者.cpp文件中加入
#include <LASlib/lasreader.hpp>
#include <LASlib/laswriter.hpp>

二、LAS文件信息

LAS数据结构介绍

1、LAS文件的头文件信息以及对应的意思

1.1、常用的读取与写入的信息

//打印头文件信息
// 初始化 header
LASheader lasHeader = lasreader->header;
//x,y,z三个方向的偏移值
F64 x_offset = lasHeader.x_offset;
F64 y_offset = lasHeader.y_offset;
F64 z_offset = lasHeader.z_offset;
//x,y,z三个方向的比例尺因子
F64 x_scale_factor = lasHeader.x_scale_factor;
F64 y_scale_factor = lasHeader.y_scale_factor;
F64 z_scale_factor = lasHeader.z_scale_factor;
//点云数据x,y,z三个方向的的最大、最小值
F64 min_x = lasHeader.min_x;
F64 max_x = lasHeader.max_x;
F64 min_y = lasHeader.min_y;
F64 max_y = lasHeader.max_y;
F64 min_z = lasHeader.min_z;
F64 max_z = lasHeader.max_z;
//点数据格式ID,说明点数据的存储格式,0-10具体看PDF
U8 point_data_format = lasHeader.point_data_format;
//点数据记录区长度 和point_data_format 有关,具体大小看LAS规定
U16 point_data_record_length = lasHeader.point_data_record_length;
//点云数据的具体数量
U32 number_of_point_records = lasHeader.number_of_point_records;
//每个返回的总点记录数组
U32 number_of_points_by_return[5];
memcpy(number_of_points_by_return, lasHeader.number_of_points_by_return, sizeof(U32)*5);

//读取.las文件的版本号
//主
U8 version_major = lasHeader.version_major;
//副
U8 version_minor = lasHeader.version_minor;

坐标 = 采集值×比例因子(scale_factor)+偏移值(offset)。

1.2、写入需要注意的信息

写入时设置这个必须设置正确,下面为初始化的时候的大小,如有附加其他信息,如user_data_in_header请及时修改header_size offset_to_point_data

//部分只有1.4版本有,请看LAS标准,或者LASheader 类
//las文件的头文件大小,LAS1.4版本为375, LAS1.3为235,LAS1.2为227
//LAS1.4比1.3多140,LAS1.3比1.2多8
lasHeader.header_size = 375;
//从文件开始到第一个点存储数据位置的字节数,一般和上面header_size一样
lasHeader.offset_to_point_data = lasHeader.header_size;

h e a d e r − s i z e = ( o r i g i n ) h e a d e r − s i z e + u s e r − d a t a − i n − h e a d e r − s i z e header_{-}size = (origin) header_{-}size +user_{-}data_{-}in_{-}header_{-}size headersize=(origin)headersize+userdatainheadersize
o f f s e t − t o − p o i n t − d a t a = ( o r i g i n ) o f f s e t − t o − p o i n t − d a t a + u s e r − d a t a − a f t e r − h e a d e r − s i z e offset_{-}to_{-}point_{-}data = (origin) offset_{-}to_{-}point_{-}data + user_{-}data_{-}after_{-}header_{-}size offsettopointdata=(origin)offsettopointdata+userdataafterheadersize

1.3、可选信息

下面为可选设置,非必须,如不设置默认即可

//此字段应设置为0到65,535之间的值。如果值为零,则表示未分配 ID,这是由多个独立源聚合(例如,从多个带合并的平铺)产生的 LAS 文件的规范。
//注意,这个方案允许一个项目包含最多65,535个唯一源。示例源可以包括数据存储库 ID 或时间上一致的数据的原始集合,例如机载系统的航线或出勤编号、移动系统的航线编号或静态系统的设置标识符。
U16 file_source_ID = lasHeader.file_source_ID;

//4个组成完整全局唯一标识符(GUID)的四个字段现在被保留用作项目标识符(Project Identifier,Project ID)。该字段仍然是可选的。
//project_ID的分配时间由处理软件决定。与唯一项目关联的所有文件的 ProjectID 应该相同。
//通过分配project_ID 和使用file_source_ID ,项目中的每个文件和文件中的每个点都可以全局唯一地标识
U32 project_ID_GUID_data_1 = lasHeader.project_ID_GUID_data_1 ;
//...

//全局编码,用于记录点云某些全局属性,16Bits的设置位,0-15
//其中Bits4是设置坐标系统 1为WKT ,0为GEOTIFF
//Bits5-Bits15必须为0
U16 global_encoding = lasHeader.global_encoding;

//描述生成软件本身的ASCII数据。此字段提供一种文件描述,用于指定在LAS文件创建过程中使用的生成软件包和版本(例如,“TerraScan V-10.8”、“Realm V-4.2”等),必须小于32字符, 剩余空字符必须为空,即"\0".
char* set_generating_software="TerraScan V-10.8";
//赋值
strncpy(lasHeader.generating_software, set_generating_software, 32);

//描述点云数据来源的字符。如由硬件扫描得出“ALTM 1210”,合并一个或多个文件的“MERGE”,修改单个文件的 “MODIFICATION”修改单个文件的... 必须小于32字符, 剩余空字符必须为空,即"\0".
char* set_generating_software="LAStools (c) by rapidlasso GmbH";
//赋值
strncpy(lasHeader.system_identifier, set_system_identifier, 32);

time_t now = time(NULL); 
tm* tm_t = localtime(&now);
//设置文件创建年份 ,tm_t为本地时间类
lasHeader.file_creation_year = tm_t->tm_year + 1900;
//设置文件创建天数
lasHeader.file_creation_day = tm_t->tm_yday;

//点的数量。兼容旧版本时,点数不大于UINT32_MAX,以及点数据记录格式值小于6。否则,它必须被设置为零。
lasHeader.extended_number_of_point_records;
//每个返回的总点记录数组。兼容旧版本时,点数不大于UINT32_MAX,且点数据记录格式小于6,则这些字段包含每个返回的总点记录数组.否则,该数组中的每个成员都必须设置为零
lasHeader.extended_number_of_points_by_return;

//这个值提供了从 LAS 文件开始到波形数据包记录的第一个字节的偏移量(以字节为单位)。
//请注意,这将是第一个字节的波形数据包头。如果文件中没有包含任何波形记录,或者它们存储在外部,则此值必须为零。
//值得注意的是,LAS 1.4允许多个扩展可变长度记录(EVLRs)  ,并且波形数据包记录不一定是文件中的第一个 EVLR。
lasHeader.start_of_waveform_data_packet_record;

//该值提供从LAS文件的开头到第一个EVLR的第一个字节的偏移量(以字节为单位)。
//如果任何软件在可变长度记录或点记录中添加/删除数据,则必须更新该偏移值。
lasHeader.start_of_first_extended_variable_length_record;
//此字段包含在点数据记录之后存储在文件中的当前EVLR数(如果存在,包括波形数据包记录)。
//如果EVLR的数量发生变化,则必须更新此数量。如果没有EVLR,则此值为零。
lasHeader.number_of_extended_variable_length_records;

Variable Length Record Header 非必须

LASvlr* vlrs= = lasHeader.vlrs;
//必须为0
vlrs.reserved;

//user_id字段是 ASCII 字符数据,用于标识创建VLRs的用户。
//有可能有许多VLRs从不同的来源与不同的user_id。
//如果字符数据小于16个字符,则其余数据必须为空。
//user_id 必须向 LAS 规范管理机构注册。这些user_id 的管理确保不会有两个人意外地使用相同的用户 ID
vlrs.user_id;
//record_id依赖于user_id。每个user_id可以有0到65,535个record_id。LAS 规范管理自己的record_id(规范拥有的user_id) ; 否则record_id将由给定user_id的所有者管理。
//因此,允许每个user_id以它们希望的任何方式分配0到65,535个record_id。公布给定record_id的含义由给定user_id的所有者决定。应忽略未知的user_id/record_id组合。
vlrs.record_id;

//标头标准部分结束后记录的字节数。
//因此,整个记录长度是54字节(VLR 的头大小)加上记录的可变长度部分中的字节数。
vlrs.record_length_after_header;

//数据的可选文本说明。任何剩余的未使用字符必须为空,即"\0"。
vlrs.description;

//可变长度的数据
vlrs.data;

Variable Length Records (VLRs) 公共标题块后面可以跟随任意数量的可变长度记录(VLRs) ,只要总长度不会使点记录数据的开始部分的lasHeader.offset_to_point_dataU32类型的大小。(VLRs) 的数量在公共标题块的lasHeader.number_of_variable_length_records字段中指定。(VLRs) 记录必须按顺序访问,因为每个(VLRs) 的大小包含在(VLRs) 头中。每个(VLRs) 头的长度为54字节。
Extended Variable Length Records (EVLRs) 在本质上与(VLRs) 相同,但可以承载更大的有效载荷,不同地方为record_length_after_header字段是8字节而不是2字节,每个(EVLRs)头的长度为60字节。

1.3.1、Coordinate Reference System VLRs
所有数据都需要点数据的坐标参考系(CRS)信息。CRS 信息将放置在`(VLRs) `或` (EVLRs) `中(注意,如果作者希望保持遗留兼容性,那么必须使用`(VLRs) `中的 GeoTIFF)。
CRS 由 GeoTIFF 或 WKT 表示,`global_encoding`设置。`point_data_format` 0-5可以使用 GeoTIFF 或 WKT,但不能同时使用两者。`point_data_format` 6-10必须使用 WKT
lasHeader.vlr_geo_ogc_wkt_math;
lasHeader.vlr_geo_ogc_wkt;
  • GeoTIFF信息 GeoTIFF官网
    只需要使用6个 GeoTIFF 标记中的3个。
    ModelTiePointTag(33922),ModelPixelScaleTag(33550),ModelTransformationTag(34264)这三条不记录。
    GeoKeyDirectoryTag(34735),GeoDoubleParamsTag(34736),GeoAsciiParamsTag(34737)这三条记录
lasHeader.vlr_geo_keys->key_directory_version;//通常为1
lasHeader.vlr_geo_keys->key_revision;//通常为1
lasHeader.vlr_geo_keys->minor_revision;//通常为0
lasHeader.vlr_geo_keys->number_of_keys;//下面lasHeader.vlr_geo_key_entries的数量
lasHeader.vlr_geo_key_entries->key_id;//每个 GeoTIFF 数据片段定义的key ID
//0表示数据作为 Ushort 在 下面value_offse 字段中
//34736 表示数据位于 下面value_offse 为索引的 lasHeader.vlr_geo_double_params中
//34737 表示数据位于 下面value_offse 为索引的 lasHeader.vlr_geo_ascii_params中
lasHeader.vlr_geo_key_entries->tiff_tag_location;
lasHeader.vlr_geo_key_entries->count;//lasHeader.vlr_geo_ascii_params值的字符串中的字符数,否则是1
lasHeader.vlr_geo_key_entries->value_offset;//含义因上述tiff_tag_location的值而异

//记录一个双精度数组,其中包含由上面geo_key中的标记集引用的值(通过索引value_offset)
lasHeader.vlr_geo_double_params;
//记录一个ASCII 数据数组,它包含许多由空终止符字符分隔的字符串,其中包含由上面geo_key中的标记集引用的值(通过索引value_offset)
lasHeader.vlr_geo_ascii_params
1.3.2、其他VLR的描述定义。
lasHeader.vlr_classification->class_number;//定义的类的值
lasHeader.vlr_classification->description;//该类的具体描述
//这些记录包含了描述波形数据包的配置的信息
lasHeader.vlr_wave_packet_descr
//data[0] Bits per Sample 支持2到32位。
//data[1] Waveform Compression Type 此字段将指示与此描述符相关联的波形包所使用的压缩算法。值为0表示没有压缩。零是当前支持的唯一值。
//(U32*)&(data[2]))[0] Number of Samples 与这个波形包类型相关的样本数。这个值总是表示完全解压缩的波形包。
//(U32*)&(data[6]))[0] Temporal Sample Spacing 以皮秒为单位的时间采样间距。示例值可能是500、1000、2000等等,分别表示2GHz、1GHz 和500MHz 的数字化器频率
//(F64*)&(data[10]))[0] Digitizer Gain 
//(F64*)&(data[18]))[0] Digitizer Offset
//数字化器的增益和偏移量用于将原始数字化值转换为绝对数字化器,公式如下:

V O L T S = O F F S E T + G A I N ∗ R a w − W a v e f o r m − A m p l i t u d e VOLTS=OFFSET+GAIN*Raw_{-}Waveform_{-}Amplitude VOLTS=OFFSET+GAINRawWaveformAmplitude

三、读取Las文件

用Matlab处理LAS点云(1)——LAS文件概述

LASreadOpener lasreadopener;
lasreadopener.set_file_name(filePath.toStdString().c_str());
LASreader* lasreader = lasreadopener.open();

filePathQString变量,需要转换,才能对应输入

1、LAS写入LASpoint 以及LASpoint 赋值

// 初始化 point
LASpoint lasPoint;
lasPoint.init(&lasHeader, lasHeader.point_data_format, lasHeader.point_data_record_length, 0);//最后为点云数量

//公共头块中“点数据记录格式”有0-5共6种,下文为format 0的所有信息
//x,y,z三个方向的采集值
lasPoint.set_x(1);
lasPoint.set_y(1);
lasPoint.set_z(1);
//点的RGB颜色值
lasPoint.set_R(0);
lasPoint.set_G(0);
lasPoint.set_B(0);
//GPS时间
lasPoint.set_gps_time(1);
//反射(回波)强度,脉冲返回幅度的整数值
lasPoint.set_intensity(0);
//反射号,给定脉冲的返回编号
lasPoint.set_return_number(2);
//反射数(特定脉冲),给定脉冲的返回次数
lasPoint.set_number_of_returns(0);
//扫描角度
lasPoint.set_scan_angle_rank(90);
//航线边界,航拍时改变方向前的最后一个点
lasPoint.set_edge_of_flight_line(1);
//分类,扫描点所属类别
lasPoint.set_classification(0);

2、点云数据读取

std::vector<LASpoint> vPoint;
while (lasReader->read_point())
{
	LASpoint& pointReader = lasReader->point;
	LASpoint p;
	p.x = pointReader.get_x();
	vPoint.push_back(p);
}

依此类推,将set关键字改为get就可以读取相应数据

3、关闭文件流

lasreader->close();
delete lasreader;
lasreader= nullptr;

四、写入点云到LAS文件

1、打开写入文件流

LASwriteOpener lasWriterOpener;
lasWriterOpener.set_file_name("./1.las");
LASwriter* lasWriter = lasWriterOpener.open(&lasHeader);//附带输入头文件信息

2、写入点云数据,更新头信息,并关闭


double minX = DBL_MAX, minY = DBL_MAX, minZ = DBL_MAX;
double maxX = -DBL_MAX, maxY = -DBL_MAX, maxZ = -DBL_MAX;
//DBL_MAX是一个大数
for (int i = 0; i < vPoints.size(); i++)
{
	//写入
	lasWriter->write_point(&vPoints.at(i));
	lasWriter->update_inventory(&vPoints.at(i));
	//坐标边界
	double x = vPoints.at(i).x;
	double y = vPoints.at(i).y;
	double z = vPoints.at(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;
}
//更新header边界信息,所有点云的最高、最低值
lasHeader.set_bounding_box(minX, minY, minZ, maxX, maxY, maxZ);
// 更新
lasWriter->update_header(&lasHeader, true);    
// 关闭
lasWriter->close();
delete lasWriter;
lasWriter = nullptr;
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 Jetson Nano 上使用 Qt Creator 进行 libargus 开发,需要将 libargus 的头文件和库文件添加到您的项目中,以下是具体步骤: 1. 打开 Qt Creator,创建一个新的项目。 2. 在项目的属性中,添加 libargus 的头文件和库文件。具体操作为:打开项目的属性,选择“Build & Run”,在“Build Steps”选项卡中,点击“Add Library”按钮,在弹出的对话框中选择“External Library”,并添加 libargus 的头文件和库文件路径。 - 头文件路径:在 Jetson Nano 上,libargus 的头文件通常位于 `/usr/include/` 目录下。在 Qt Creator 中,您需要将该路径添加到项目的头文件搜索路径中。 - 库文件路径:在 Jetson Nano 上,libargus 的库文件通常位于 `/usr/lib/aarch64-linux-gnu/tegra/` 目录下。在 Qt Creator 中,您需要将该路径添加到项目的库文件搜索路径中。 3. 配置项目的编译选项,以便能够链接 libargus 库。具体操作为:打开项目的属性,选择“Build & Run”,在“Build Settings”选项卡中,添加 libargus 库文件的链接选项。 - 在“Linker Flags”中,添加 `-largus` 选项,以链接 libargus 库文件。 4. 编写代码:在 Qt Creator 中,您可以编写 C++ 代码,调用 libargus 的接口实现图像和视频的采集。具体的接口调用方法可以参考 Nvidia 官方文档或者其他相关的教程。 5. 编译和运行:在 Qt Creator 中,您可以编译和运行您的程序,进行图像和视频的采集和处理。 这样,您就可以在 Jetson Nano 上使用 Qt Creator 进行 libargus 开发了。希望以上步骤能对您有所帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值