
离线 TA的专栏
- 打卡等级:热心大叔
- 打卡总天数:225
- 打卡月天数:0
- 打卡总奖励:3337
- 最近打卡:2025-04-15 15:13:09
|
前言
最近在学习点云处理的时候用到了 数据集,该数据集总共有 个类别,每个样本的点云数据存放在一个 文件中,每行的前3个数据代表一个点的 坐标。我需要把 文件中的每个点读取出来,然后用 进行显示。怎么把数据从 文件中读取出来呢? 提供了一个功能非常强大的函数 可以非常简单地实现这个功能。来看一下代码: - import open3d as o3d
- import numpy as np
- def main():
- points_data = np.loadtxt("airplane_0001.txt", delimiter=",", dtype=np.float32)
- pcd = o3d.geometry.PointCloud()
- pcd.points = o3d.utility.Vector3dVector(points_data[:, :3])
- o3d.visualization.draw_geometries([pcd])
- if __name__ == '__main__':
- main()
复制代码从上面的代码可以看到,只需要一行代码就可以把 文件中的点云数据读取进来了,接下来就可以调用 的接口进行显示了。在介绍 函数的用法之前,
顺便看一下Open3D的显示效果:
loadtxt函数的用法
基本用法
在上面的例子中,由于 里面每一行的数据是用逗号分割的,所以在调用 函数的时候除了设置文件路径外,还需要设置参数 。另外,该函数默认的数据类型为 ,如果是其他数据类型的话还需要设置 为对应类型。 - points_data = np.loadtxt("airplane_0001.txt", delimiter=",") #没有指定数据类型
- print('shape: ', points_data.shape)
- print('data type: ', points_data.dtype)
复制代码 结果:- shape: (10000, 6)data type: float64
复制代码 指定每一列的数据类型
假如我们有一个 文件: - x,y,z,label,id
- -0.098790,-0.182300,0.163800,1,1
- 0.994600,0.074420,0.010250,0.2,2
- 0.189900,-0.292200,-0.926300,3,3
- -0.989200,0.074610,-0.012350,4,4
复制代码该文件前面3列的数据类型是浮点型,后面2列的数据类型为整型,那么按照前面的方式设置 来读取就不合适了。不过没关系, 函数可以设置每一列数据的数据类型,只不过稍微复杂一点,来看一下代码: - data = np.loadtxt("test.txt", delimiter=",",
- dtype={'names': ('x', 'y', 'z', 'label', 'id'),
- 'formats': ('f4', 'f4', 'f4', 'i4', 'i4')},
- skiprows=1)
- print('data: ', data)
- print('data type: ', data.dtype)
复制代码这段代码的重点是 里面的内容, 用来设置每一列数据的名称, 则用来设置每一列数据的数据类型,其中 表示 , 表示 。另外, 文件中的第一行不是数据内容,可以设置参数 跳过第一行的内容。
输出结果:- data: [(-0.09879, -0.1823 , 0.1638 , 1, 1) ( 0.9946 , 0.07442, 0.01025, 0, 2) ( 0.1899 , -0.2922 , -0.9263 , 3, 3) (-0.9892 , 0.07461, -0.01235, 4, 4)]data type: [('x', '<f4'), ('y', '<f4'), ('z', '<f4'), ('label', '<i4'), ('id', '<i4')]
复制代码可以看到,通过这样的方式设置 ,读取的每一行数据变成了一个 类型。
结合生成器使用
从 的文档中可以知道, 函数的第一个参数可以是文件对象、文件名或者生成器。传入生成器有什么用呢?我们来看几个例子。
处理多个分隔符
假如我们的文件内容是这样的,每一行数据有3个分隔符",","/"和"-":- 9.87,1.82,1.63,1/11-1
- 9.94,7.44,1.02,1/11-2
- 1.89,2.92,9.26,1/11-3
- 0.98,7.46,1.23,1/11-4
复制代码这种情况下不能通过 参数设置多个分隔符, 这时候就可以通过生成器来进行处理:- def generate_lines(file_path, delimiters=[]):
- with open("test.txt") as f:
- for line in f:
- line = line.strip()
- for d in delimiters:
- line = line.replace(d, " ")
- yield line
- delimiters = [",", "/", "-"]
- generator = generate_lines("test.txt", delimiters)
- data = np.loadtxt(generator)
- print(data)
复制代码这段代码构建了一个生成器将文件中每一行的分隔符全部替换成 函数默认的空格分隔符,然后把生成器传入 函数,这样 函数就能成功解析文件中的数据了。
输出结果:- [[ 9.87 1.82 1.63 1. 11. 1. ] [ 9.94 7.44 1.02 1. 11. 2. ] [ 1.89 2.92 9.26 1. 11. 3. ] [ 0.98 7.46 1.23 1. 11. 4. ]]
复制代码 读取指定的行
在某些情况下,我们需要读取指定几行的数据,那么也可以通过生成器来实现。还是上面的文件内容,我们通过生成器来读取第2行和第3行: - def generate_lines(file_path, delimiters=[], rows=[]):
- with open("test.txt") as f:
- for i, line in enumerate(f):
- line = line.strip()
- for d in delimiters:
- line = line.replace(d, " ")
- if i in rows:
- yield line
- delimiters = [",", "/", "-"]
- rows = [1, 2]
- generator = generate_lines("test.txt", delimiters, rows)
- data = np.loadtxt(generator)
- print(data)
复制代码 输出结果:- [[ 9.94 7.44 1.02 1. 11. 2. ] [ 1.89 2.92 9.26 1. 11. 3. ]]
复制代码通过上面的例子可以知道, 函数结合生成器使用可以实现很多的功能。
tofile和fromfile函数
从 文件中读取到点云数据后,我想把数据保存到二进制文件中,需要怎么操作呢? 的 类提供了 函数可以非常方便地将数据保存到二进制文件中。把数据以二进制文件保存后又怎么读进来呢? 还提供了一个 函数用于从文本文件和二进制文件中读取数据。 - import open3d as o3d
- import numpy as np
- def main():
- points_data = np.loadtxt(
- "airplane_0001.txt", delimiter=",", dtype=np.float32)
- bin_file = 'airplane_0001.bin'
- points_data = points_data[:, :3]
- points_data.tofile(bin_file)
- pc = np.fromfile(bin_file, dtype=np.float32)
- pc = pc.reshape(-1, 3)
- pcd = o3d.geometry.PointCloud()
- pcd.points = o3d.utility.Vector3dVector(pc)
- o3d.visualization.draw_geometries([pcd])
- if __name__ == '__main__':
- main()
复制代码在上面这段示例代码中,我从 文件中读取了点云数据,然后通过 函数将数据保存到二进制文件 中,再用 函数从二进制文件中把点云数据读取出来用 进行显示。
为了前后呼应,让我们换个角度再看一眼显示效果:
到此这篇关于Python如何用NumPy读取和保存点云数据的文章就介绍到这了,更多相关Python NumPy 内容请搜索晓枫资讯以前的文章或继续浏览下面的相关文章希望大家以后多多支持晓枫资讯!
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |
晓枫资讯-科技资讯社区-免责声明
免责声明:以上内容为本网站转自其它媒体,相关信息仅为传递更多信息之目的,不代表本网观点,亦不代表本网站赞同其观点或证实其内容的真实性。
1、注册用户在本社区发表、转载的任何作品仅代表其个人观点,不代表本社区认同其观点。
2、管理员及版主有权在不事先通知或不经作者准许的情况下删除其在本社区所发表的文章。
3、本社区的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,举报反馈:  进行删除处理。
4、本社区一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
5、以上声明内容的最终解释权归《晓枫资讯-科技资讯社区》所有。
|