当前位置: 首页 > news >正文

使用Python读取las点云,写入las点云,无损坐标精度

目录

  • 1 为什么要写这个博文
  • 2 提出一些关键问题
  • 3 给出全部代码
    • 安装依赖
    • 源码(laspy v2.x)

1 为什么要写这个博文

搜索使用python读写las点云数据,可以找到很多结果。但是! 有些只是简单的demo,且没有发现/说明可能遇到的问题;有些晦涩难懂,不够实用主义;有些须付费观看,没有开源精神。

本人在使用laspy v2.3读写点云文件时,着实被坐标精度问题难到了,顺便就仔细学习了下las格式到底是什么来头。

您猜怎么着,如果能打开这个网址,都在这里面详细说明了:laspy document

我还是种个树吧,直接拔了就能用。文末贴源码。

2 提出一些关键问题

  1. 注意:
    * 实测版本 laspy v2.3,2.x版本应该都可用,但不适合1.x版本。
    * las 存储数据时,需要设置 scales 和 offsets,否则会出现精度问题。
    * las 存储颜色时,数值类型为 16 位无符号整型。rgb = (normal_rgb * 65535).astype(np.uint16)

  2. las 格式原生支持的属性字段,与las版本密切相关。官方说明:https://laspy.readthedocs.io/en/latest/intro.html#point-records

  3. 对 scales 和 offsets 的理解:
    比例scales 表明数据的准确性。 0.001 是毫米精度。这意味着如果您的坐标是 0.123456,它将被限制为 0.123。
    偏移offset 的目的是避免整数溢出。假设您要存储 123456789.123。在 LAS 文件中,您实际上将存储一个整数:123456789123,该整数将在读取时使用比例因子转换为 123456789.123。但 123456789123 比 32 位整数所能存储的要大得多。因此存储时,将该值偏移 123450000,实际存的是6789123。
    (6789123 * 0.001 + 123450000 = 123456789.123)
    段落出处

3 给出全部代码

安装依赖

使用 pip (# 选择一个安装就好):

# Install _without_ LAZ support
pip install laspy# Install with LAZ support via lazrs
pip install laspy[lazrs]# Install with LAZ support via laszip
pip install laspy[laszip]# Install with LAZ support via both lazrs & laszip
pip install laspy[lazrs,laszip]

使用 conda (# 选择一个安装就好):

conda install -c conda-forge laspy
conda install -c conda-forge lazrs-python

源码(laspy v2.x)

三个工具函数:
read_las_fit() : 读取 las 文件
write_las_fit(): 保存 las 文件
get_las_header_attrs() : 获取不同 las 版本支持的固有属性
备注:_fit 的意思是,可以支持各种属性信息的读取和写入

import laspy
import numpy as npdef read_las_fit(filename, attrs=None):"""读取 las 文件,获取三维坐标 xyz, 颜色 rgb, 属性 attr_dict。当文件没有 RGB 信息时,返回全0的 RGB 信息Args:filename: <str> las 文件路径attrs: <list> 需要额外获取的属性信息 如 ['label']Returns:xyz, rgb, attr_dict"""if attrs is None:attrs = []# 默认返回 scales, offsets ,合并 ["scales", "offsets"]attrs = list(set(attrs + ["scales", "offsets"]))# 读取点云inFile = laspy.read(filename)# inFile.point_format.dimensions可以获取所有的维度信息N_points = len(inFile)x = np.reshape(inFile.x, (N_points, 1))y = np.reshape(inFile.y, (N_points, 1))z = np.reshape(inFile.z, (N_points, 1))xyz = np.hstack((x, y, z))# TODO 注意。如果是大写的 X Y Z,需要转换后才是真实坐标: real_x = scale[0] * inFile.X + offset[0]# 初始化 rgb 全是 0rgb = np.zeros((N_points, 3), dtype=np.uint16)if hasattr(inFile, "red") and hasattr(inFile, "green") and hasattr(inFile, "blue"):r = np.reshape(inFile.red, (N_points, 1))g = np.reshape(inFile.green, (N_points, 1))b = np.reshape(inFile.blue, (N_points, 1))# i = np.reshape(inFile.Reflectance, (N_points, 1))rgb = np.hstack((r, g, b))else:print(f"注意:{filename.split('/')[-1]} 没有RGB信息,返回全0的RGB信息!")# 组织其他属性信息attr_dict = {}for attr in attrs:# 先判断 header 中是否有该属性if hasattr(inFile.header, attr):value = getattr(inFile.header, attr)if hasattr(value, "array"):attr_dict[attr] = np.array(value)else:attr_dict[attr] = value# 再判断 是否为额外属性elif hasattr(inFile, attr):value = getattr(inFile, attr)if hasattr(value, "array"):attr_dict[attr] = np.array(value)else:attr_dict[attr] = valueelse:attr_dict[attr] = Noneprint(f"注意:{filename.split('/')[-1]} 没有属性 {attr} 信息!")return xyz, rgb, attr_dictdef write_las_fit(out_file, xyz, rgb=None, attrs=None):"""将点云数据写入 las 文件,支持写入 坐标xyz, 颜色rgb, 属性attrsArgs:out_file: 输出文件路径xyz: 点云坐标 ndarray (N, 3)rgb: 点云颜色 ndarray (N, 3)attrs:固有属性:file_source_id, gps_time, Intensity, Number of Returns, ....额外属性:label, pred, ...注意:如果不传入 scales 和 offsets,则会自动计算Returns:"""if attrs is None:attrs = {}# 1. 创建 las 文件头。point_format和version决定了las支持哪些固有属性# 详情见 https://pylas.readthedocs.io/en/latest/intro.html?highlight=red#point-recordsheader = laspy.LasHeader(point_format=7, version="1.4")  # 7 支持rgb# 自动计算 scales 和 offsets,确保坐标精度无损# https://stackoverflow.com/questions/77308057/conversion-accuracy-issues-of-e57-to-las-in-python-using-pye57-and-laspyif "offset" not in attrs:min_offset = np.floor(np.min(xyz, axis=0))attrs["offset"] = min_offsetif "scales" not in attrs:attrs["scales"] = [0.001, 0.001, 0.001]  # 0.001 是毫米精度# 初始化一些需要保存的属性值。如果是固有属性,直接赋值; 如果是额外属性,添加到 header 中, 后续赋值extra_attr = []for attr, value in attrs.items():if hasattr(header, attr):  # 设置固有的属性的值, 如 scales, offsetsheader.__setattr__(attr, value)else:  # 添加额外属性,在 las 初始化后赋值header.add_extra_dim(laspy.ExtraBytesParams(name=attr, type=np.float32))extra_attr.append(attr)# 2. 创建 las 文件las = laspy.LasData(header)# 添加xyz坐标las.x = xyz[:, 0]las.y = xyz[:, 1]las.z = xyz[:, 2]# 添加RGB颜色,如果是归一化的颜色,则需要乘以 65535,转为 uint16if rgb is not None:if np.max(rgb) <= 1:rgb = (rgb * 65535).astype(np.uint16)  # 65535 = 2^16 - 1, las存储颜色是16位无符号整型las.red = rgb[:, 0]las.green = rgb[:, 1]las.blue = rgb[:, 2]# 添加额外属性for attr in extra_attr:# 当 value 是 n * 1 的 ndarray 时,转换为 1 维数组value = attrs[attr]if value.ndim == 2 and value.shape[1] == 1:value = value.flatten()las[attr] = value# 保存LAS文件las.write(out_file)def get_las_header_attrs(point_format=7, version="1.4"):"""根据 point_format 和 version 获取 las 文件的 header 属性说明文档:https://laspy.readthedocs.io/en/latest/intro.html#point-recordsArgs:point_format: 点格式version: 版本Returns:"""dimensions = []header = laspy.LasHeader(point_format=point_format, version=version)  # 7 支持rgbfor dim in header.point_format.dimensions:dimensions.append(dim.name)return dimensionsif __name__ == '__main__':# 测试1: 获取 las 文件头属性fields = get_las_header_attrs(7, "1.4")print(f"point_format=7, version=1.4, 头文件包含字段: {fields}")# 测试2: 读取LAS文件read_las_path = "/path_2_data/one_point_cloud.las"xyz_, rgb_, attrs_ = read_las_fit(read_las_path, ["scales", "offsets"])print(attrs_)# 测试3: 写入LAS文件save_las_path = "/path_2_data/one_point_cloud_fit.las"write_las_fit(save_las_path, xyz_, rgb_, {# "scales": attrs_["scales"],# "offsets": attrs_["offsets"]})

相关文章:

使用Python读取las点云,写入las点云,无损坐标精度

目录 1 为什么要写这个博文2 提出一些关键问题3 给出全部代码安装依赖源码&#xff08;laspy v2.x&#xff09; 1 为什么要写这个博文 搜索使用python读写las点云数据&#xff0c;可以找到很多结果。但是&#xff01; 有些只是简单的demo&#xff0c;且没有发现/说明可能遇到的…...

python开发二

python开发二 requests请求模块 requests 是一个常用的 Python 第三方库&#xff0c;用于发送 HTTP 请求。它提供了简洁且易于使用的接口&#xff0c;使得与 Web 服务进行交互变得非常方便。 发送 GET 请求并获取响应 import requestsresponse requests.get("https:/…...

部署JVS服务出现上传文件不可用,问题原因排查。

事情的起因是这样的&#xff0c;部门经理让我部署一下JVS资源共享框架&#xff0c;项目的地址是在这里 项目资源地址 各位小伙伴们做好了&#xff0c;我要开始发车了&#xff0c;全新的“裂开之旅” 简单展示一下如何部署JVS文档 直达链接 撕裂要开始了 本来服务启动的好好…...

机器视觉检测为什么是工业生产的刚需?

机器视觉检测在工业生产中被视为刚需&#xff0c;主要是因为它具备以下几个关键优势&#xff1a; 提高精度与效率&#xff1a;机器视觉系统可以进行高速、高精度的检测。这对于保证产品质量、减少废品非常关键。例如&#xff0c;在生产线上&#xff0c;机器视觉可以迅速识别产品…...

Adobe系列软件安装

双击解压 先运行Creative_Cloud_Set_Up.exe。 完毕后&#xff0c;运行AdobeGenP.exe 先Path&#xff0c;选路径&#xff0c;如 C:\Program Files\Adobe 后Search 最后Patch。 关闭软件&#xff0c;修图&#xff01;...

【FX110】2024外汇市场中交易量最大的货币对是哪个?

作为最大、最流动的金融市场之一&#xff0c;外汇市场每天的交易量高达几万亿美元&#xff0c;涉及到数百种货币。不同货币对的交易活跃程度并不一样&#xff0c;交易者需要根据货币对各自的特点去进行交易。 全年外汇市场中涉及美元的外汇交易超过50%&#xff01; 实际上&…...

leetcode尊享面试100题(549二叉树最长连续序列||,python)

题目不长&#xff0c;就是分析时间太久了。 思路使用dfs深度遍历&#xff0c;先想好这个函数返回什么&#xff0c;题目给出路径可以是子-父-子的路径&#xff0c;那么1-2-3可以&#xff0c;3-2-1也可以&#xff0c;那么考虑dfs返回两个值&#xff0c;对于当前节点node来说&…...

C#面试题: 寻找中间值

给定一个数组&#xff0c;在区间内从左到右查找中间值&#xff0c;每次查找最小值与最大值区间内的中间值&#xff0c;且这个区间元素数量不小于3。 例如 1.给定数组float[] data { 1, 2.3f, 4, 5.75f, 8.125f, 10.5f, 13, 15, 20 } 输出&#xff1a;10.5、5.75、4、2.3、8…...

987: 输出用先序遍历创建的二叉树是否为完全二叉树的判定结果

解法&#xff1a; 一棵二叉树是完全二叉树的条件是&#xff1a; 对于任意一个结点&#xff0c;如果它有右子树而没有左子树&#xff0c;则这棵树不是完全二叉树。 如果一个结点有左子树但是没有右子树&#xff0c;则这个结点之后的所有结点都必须是叶子结点。 如果满足以上条…...

13:HAL---SPI

目录 一:SPL通信 1:简历 2:硬件电路 3:移动数据图 4:SPI时序基本单元 A : 开/ 终条件 B:SPI时序基本单元 A:模式0 B:模式1 C:模式2 D:模式3 C:SPl时序 A:发送指令 B: 指定地址写 C:指定地址读 5&#xff1a;NSS(CS) 6&#xff1a;时钟 二: W25Q64 1:简历 2…...

微服务---gateway网关

目录 gateway作用 gateway使用 添加依赖 配置yml文件 自定义过滤器 nacos上的gateway的配置文件 我们现在知道了通过nacos注册服务&#xff0c;通过feign实现服务间接口的调用&#xff0c;那对于不同权限的用户访问同一个接口&#xff0c;我们怎么知道他是否具有访问的权…...

HTML4(二)

文章目录 1 开发者文档2 基本标签2.1 排版标签2.2 语义化标签2.3 行内元素与块级元素2.4 文本标签2.5 常用标签补充 3 图片标签4 超链接标签4.1 跳转页面4.2 跳转文件4.3 跳转锚点4.4 唤起指定应用 5 列表5.1 有序列表5.2 无序列表5.3 自定义列表 6 表格6.1 基本结构6.2 表格标…...

SpringBoot 扩展篇:ConfigFileApplicationListener源码解析

SpringBoot 扩展篇&#xff1a;ConfigFileApplicationListener源码解析 1.概述2. ConfigFileApplicationListener定义3. ConfigFileApplicationListener回调链路3.1 SpringApplication#run3.2 SpringApplication#prepareEnvironment3.3 配置environment 4. 环境准备事件 Config…...

蓝桥杯省三爆改省二,省一到底做错了什么?

到底怎么个事 这届蓝桥杯选的软件测试赛道&#xff0c;都说选择大于努力,软件测试一不卷二不难。省赛结束&#xff0c;自己就感觉稳啦&#xff0c;全部都稳啦。没想到一出结果&#xff0c;省三&#xff0c;g了。说落差&#xff0c;是真的有一点&#xff0c;就感觉和自己预期的…...

Unity EventSystem入门

概述 相信在学习Unity中&#xff0c;一定有被UI事件困扰的时候把&#xff0c;当添加UICanvas的时候&#xff0c;Unity会为我们自动添加EventSystem&#xff0c;这个是为什么呢&#xff0c;Unity的UI事件是如何处理的呢&#xff0c;在使用各个UI组件的时候&#xff0c;一定有不…...

第4章 Vim编辑器与Shell命令脚本

第4章 Vim编辑器与Shell命令脚本 1. Vim文本编辑器2. 编写Shell脚本2.2 接收用户的参数2.3 判断用户的参数 3. 流程控制语句3.1 if条件测试语句3.2 for条件循环语句3.3 while条件循环语句3.4 case条件测试语句 4. 计划任务服务程序复习题 1. Vim文本编辑器 Vim编辑器中设置了三…...

javaWeb快速部署到tomcat阿里云服务器

目录 准备 关闭防火墙 配置阿里云安全组 点击控制台 点击导航栏按钮 点击云服务器ECS 点击安全组 点击管理规则 点击手动添加 设置完成 配置web服务 使用yum安装heepd服务 启动httpd服务 查看信息 部署java通过Maven打包好的war包项目 Maven打包项目 上传项目 …...

[MQTT]Mosquitto的內網連接(intranet)和使用者/密碼權限設置

[MQTT | Raspberry Pi]Publish and Subscribe with RSSI Data of Esp32 on Intranet 延續[MQTT]Mosquitto的簡介、安裝與連接測試文章&#xff0c;接著將繼續測試在內網的兩台機器是否也可以完成發佈和訂閱作業。 同一網段的兩台電腦測試: 假設兩台電腦的配置如下: A電腦為發…...

某盾BLACKBOX逆向关键点

需要准备的东西&#xff1a; 1、原JS码 2、AST解混淆码 3、token(来源于JSON) 一、原JS码很好获取&#xff0c;每次页面刷新&#xff0c;混淆的代码都会变&#xff0c;这是正常&#xff0c;以下为部分代码 while (Qooo0) {switch (Qooo0) {case 110 14 - 55: {function O0…...

【2024全国青少年信息素养大赛初赛时间以及模拟题】

2024全国青少年信息素养大赛时间已经出来了 目录 全国青少年信息素养大赛智能算法挑战赛初中模拟卷 全国青少年信息素养大赛智能算法挑战赛初中模拟卷 1、比赛时间和考试内容&#xff1a; 算法创意实践挑战赛初中组于5月19日举行&#xff0c;检录时间为10:30-11:00&#xf…...

KubeSphere 容器平台高可用:环境搭建与可视化操作指南

Linux_k8s篇 欢迎来到Linux的世界&#xff0c;看笔记好好学多敲多打&#xff0c;每个人都是大神&#xff01; 题目&#xff1a;KubeSphere 容器平台高可用&#xff1a;环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...

进程地址空间(比特课总结)

一、进程地址空间 1. 环境变量 1 &#xff09;⽤户级环境变量与系统级环境变量 全局属性&#xff1a;环境变量具有全局属性&#xff0c;会被⼦进程继承。例如当bash启动⼦进程时&#xff0c;环 境变量会⾃动传递给⼦进程。 本地变量限制&#xff1a;本地变量只在当前进程(ba…...

基于ASP.NET+ SQL Server实现(Web)医院信息管理系统

医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上&#xff0c;开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识&#xff0c;在 vs 2017 平台上&#xff0c;进行 ASP.NET 应用程序和简易网站的开发&#xff1b;初步熟悉开发一…...

CMake基础:构建流程详解

目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...

全球首个30米分辨率湿地数据集(2000—2022)

数据简介 今天我们分享的数据是全球30米分辨率湿地数据集&#xff0c;包含8种湿地亚类&#xff0c;该数据以0.5X0.5的瓦片存储&#xff0c;我们整理了所有属于中国的瓦片名称与其对应省份&#xff0c;方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...

基于数字孪生的水厂可视化平台建设:架构与实践

分享大纲&#xff1a; 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年&#xff0c;数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段&#xff0c;基于数字孪生的水厂可视化平台的…...

【配置 YOLOX 用于按目录分类的图片数据集】

现在的图标点选越来越多&#xff0c;如何一步解决&#xff0c;采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集&#xff08;每个目录代表一个类别&#xff0c;目录下是该类别的所有图片&#xff09;&#xff0c;你需要进行以下配置步骤&#x…...

鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/

使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题&#xff1a;docker pull 失败 网络不同&#xff0c;需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...

OpenLayers 分屏对比(地图联动)

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能&#xff0c;和卷帘图层不一样的是&#xff0c;分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...

论文笔记——相干体技术在裂缝预测中的应用研究

目录 相关地震知识补充地震数据的认识地震几何属性 相干体算法定义基本原理第一代相干体技术&#xff1a;基于互相关的相干体技术&#xff08;Correlation&#xff09;第二代相干体技术&#xff1a;基于相似的相干体技术&#xff08;Semblance&#xff09;基于多道相似的相干体…...