设为首页收藏本站
网站公告 | 这是第一条公告
     

 找回密码
 立即注册
缓存时间14 现在时间14 缓存数据 “你总爱编织谎言,我总是配合表演。”

“你总爱编织谎言,我总是配合表演。” -- 配合

查看: 310|回复: 1

Python如何用NumPy读取和保存点云数据

[复制链接]

  离线 

TA的专栏

  • 打卡等级:热心大叔
  • 打卡总天数:225
  • 打卡月天数:0
  • 打卡总奖励:3337
  • 最近打卡:2025-04-15 15:13:09
等级头衔

等級:晓枫资讯-上等兵

在线时间
0 小时

积分成就
威望
0
贡献
470
主题
430
精华
0
金钱
4713
积分
957
注册时间
2023-1-7
最后登录
2025-4-15

发表于 2023-2-10 22:50:02 | 显示全部楼层 |阅读模式
前言

最近在学习点云处理的时候用到了
  1. Modelnet40
复制代码
数据集,该数据集总共有
  1. 40
复制代码
个类别,每个样本的点云数据存放在一个
  1. TXT
复制代码
文件中,每行的前3个数据代表一个点的
  1. xyz
复制代码
坐标。我需要把
  1. TXT
复制代码
文件中的每个点读取出来,然后用
  1. Open3D
复制代码
进行显示。怎么把数据从
  1. TXT
复制代码
文件中读取出来呢?
  1. NumPy
复制代码
提供了一个功能非常强大的函数
  1. loadtxt
复制代码
可以非常简单地实现这个功能。来看一下代码:
  1. import open3d as o3d
  2. import numpy as np

  3. def main():
  4.     points_data = np.loadtxt("airplane_0001.txt", delimiter=",", dtype=np.float32)
  5.     pcd = o3d.geometry.PointCloud()
  6.     pcd.points = o3d.utility.Vector3dVector(points_data[:, :3])
  7.     o3d.visualization.draw_geometries([pcd])

  8. if __name__ == '__main__':
  9.     main()
复制代码
从上面的代码可以看到,只需要一行代码就可以把
  1. TXT
复制代码
文件中的点云数据读取进来了,接下来就可以调用
  1. Open3D
复制代码
的接口进行显示了。在介绍
  1. loadtxt
复制代码
函数的用法之前,
顺便看一下Open3D的显示效果:
235130ev9gsvqvzb2vzv18.png


loadtxt函数的用法


基本用法

在上面的例子中,由于
  1. TXT
复制代码
里面每一行的数据是用逗号分割的,所以在调用
  1. loadtxt
复制代码
函数的时候除了设置文件路径外,还需要设置参数
  1. delimiter=","
复制代码
。另外,该函数默认的数据类型为
  1. float64
复制代码
,如果是其他数据类型的话还需要设置
  1. dtype
复制代码
为对应类型。
  1. points_data = np.loadtxt("airplane_0001.txt", delimiter=",") #没有指定数据类型
  2. print('shape: ', points_data.shape)
  3. print('data type: ', points_data.dtype)
复制代码
结果:
  1. shape:  (10000, 6)data type:  float64 
复制代码
指定每一列的数据类型

假如我们有一个
  1. CSV
复制代码
文件:
  1. x,y,z,label,id
  2. -0.098790,-0.182300,0.163800,1,1
  3. 0.994600,0.074420,0.010250,0.2,2
  4. 0.189900,-0.292200,-0.926300,3,3
  5. -0.989200,0.074610,-0.012350,4,4
复制代码
该文件前面3列的数据类型是浮点型,后面2列的数据类型为整型,那么按照前面的方式设置
  1. dtype
复制代码
来读取就不合适了。不过没关系,
  1. loadtxt
复制代码
函数可以设置每一列数据的数据类型,只不过稍微复杂一点,来看一下代码:
  1. data = np.loadtxt("test.txt", delimiter=",",
  2.                       dtype={'names': ('x', 'y', 'z', 'label', 'id'), 
  3.                             'formats': ('f4', 'f4', 'f4', 'i4', 'i4')},
  4.                       skiprows=1)
  5. print('data: ', data)
  6. print('data type: ', data.dtype)
复制代码
这段代码的重点是
  1. dtype={}
复制代码
里面的内容,
  1. 'names'
复制代码
用来设置每一列数据的名称,
  1. 'formats'
复制代码
则用来设置每一列数据的数据类型,其中
  1. 'f4'
复制代码
表示
  1. float32
复制代码
  1. 'i4'
复制代码
表示
  1. int32
复制代码
。另外,
  1. CSV
复制代码
文件中的第一行不是数据内容,可以设置参数
  1. skiprows=1
复制代码
跳过第一行的内容。
输出结果:
  1. 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')]
复制代码
可以看到,通过这样的方式设置
  1. dtype
复制代码
,读取的每一行数据变成了一个
  1. tuple
复制代码
类型。

结合生成器使用

  1. NumPy
复制代码
的文档中可以知道,
  1. loadtxt
复制代码
函数的第一个参数可以是文件对象、文件名或者生成器。传入生成器有什么用呢?我们来看几个例子。
处理多个分隔符
假如我们的文件内容是这样的,每一行数据有3个分隔符",","/"和"-":
  1. 9.87,1.82,1.63,1/11-1
  2. 9.94,7.44,1.02,1/11-2
  3. 1.89,2.92,9.26,1/11-3
  4. 0.98,7.46,1.23,1/11-4
复制代码
这种情况下不能通过
  1. delimiter
复制代码
参数设置多个分隔符,这时候就可以通过生成器来进行处理:
  1. def generate_lines(file_path, delimiters=[]):
  2.     with open("test.txt") as f:
  3.         for line in f:
  4.             line = line.strip()
  5.             for d in delimiters:
  6.                 line = line.replace(d, " ")
  7.             yield line

  8. delimiters = [",", "/", "-"]
  9. generator = generate_lines("test.txt", delimiters)
  10. data = np.loadtxt(generator)
  11. print(data)
复制代码
这段代码构建了一个生成器将文件中每一行的分隔符全部替换成
  1. loadtxt
复制代码
函数默认的空格分隔符,然后把生成器传入
  1. loadtxt
复制代码
函数,这样
  1. loadtxt
复制代码
函数就能成功解析文件中的数据了。
输出结果:
  1. [[ 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行:
  1. def generate_lines(file_path, delimiters=[], rows=[]):
  2.     with open("test.txt") as f:
  3.         for i, line in enumerate(f):
  4.             line = line.strip()
  5.             for d in delimiters:
  6.                 line = line.replace(d, " ")
  7.             if i in rows:
  8.                 yield line

  9. delimiters = [",", "/", "-"]
  10. rows = [1, 2]
  11. generator = generate_lines("test.txt", delimiters, rows)
  12. data = np.loadtxt(generator)
  13. print(data)
复制代码
输出结果:
  1. [[ 9.94  7.44  1.02  1.   11.    2.  ] [ 1.89  2.92  9.26  1.   11.    3.  ]]
复制代码
通过上面的例子可以知道,
  1. loadtxt
复制代码
函数结合生成器使用可以实现很多的功能。

tofile和fromfile函数

  1. TXT
复制代码
文件中读取到点云数据后,我想把数据保存到二进制文件中,需要怎么操作呢?
  1. NumPy
复制代码
  1. ndarray
复制代码
类提供了
  1. tofile
复制代码
函数可以非常方便地将数据保存到二进制文件中。把数据以二进制文件保存后又怎么读进来呢?
  1. NumPy
复制代码
还提供了一个
  1. fromfile
复制代码
函数用于从文本文件和二进制文件中读取数据。
  1. import open3d as o3d
  2. import numpy as np

  3. def main():
  4.     points_data = np.loadtxt(
  5.         "airplane_0001.txt", delimiter=",", dtype=np.float32)

  6.     bin_file = 'airplane_0001.bin'
  7.     points_data = points_data[:, :3]
  8.     points_data.tofile(bin_file)

  9.     pc = np.fromfile(bin_file, dtype=np.float32)
  10.     pc = pc.reshape(-1, 3)
  11.     pcd = o3d.geometry.PointCloud()
  12.     pcd.points = o3d.utility.Vector3dVector(pc)
  13.     o3d.visualization.draw_geometries([pcd])

  14. if __name__ == '__main__':
  15.     main()
复制代码
在上面这段示例代码中,我从
  1. airplane_0001.txt
复制代码
文件中读取了点云数据,然后通过
  1. tofile
复制代码
函数将数据保存到二进制文件
  1. airplane_0001.bin
复制代码
中,再用
  1. fromfile
复制代码
函数从二进制文件中把点云数据读取出来用
  1. Open3D
复制代码
进行显示。
为了前后呼应,让我们换个角度再看一眼显示效果:
235130pn8an5andsrq5996.png

到此这篇关于Python如何用NumPy读取和保存点云数据的文章就介绍到这了,更多相关Python NumPy 内容请搜索晓枫资讯以前的文章或继续浏览下面的相关文章希望大家以后多多支持晓枫资讯!

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
晓枫资讯-科技资讯社区-免责声明
免责声明:以上内容为本网站转自其它媒体,相关信息仅为传递更多信息之目的,不代表本网观点,亦不代表本网站赞同其观点或证实其内容的真实性。
      1、注册用户在本社区发表、转载的任何作品仅代表其个人观点,不代表本社区认同其观点。
      2、管理员及版主有权在不事先通知或不经作者准许的情况下删除其在本社区所发表的文章。
      3、本社区的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,举报反馈:点击这里给我发消息进行删除处理。
      4、本社区一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
      5、以上声明内容的最终解释权归《晓枫资讯-科技资讯社区》所有。
http://bbs.yzwlo.com 晓枫资讯--游戏IT新闻资讯~~~

  离线 

TA的专栏

等级头衔

等級:晓枫资讯-列兵

在线时间
0 小时

积分成就
威望
0
贡献
0
主题
0
精华
0
金钱
20
积分
20
注册时间
2022-12-25
最后登录
2022-12-25

发表于 2025-4-22 19:14:24 | 显示全部楼层
顶顶更健康!!!
http://bbs.yzwlo.com 晓枫资讯--游戏IT新闻资讯~~~
严禁发布广告,淫秽、色情、赌博、暴力、凶杀、恐怖、间谍及其他违反国家法律法规的内容。!晓枫资讯-社区
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

1楼
2楼

手机版|晓枫资讯--科技资讯社区 本站已运行

CopyRight © 2022-2025 晓枫资讯--科技资讯社区 ( BBS.yzwlo.com ) . All Rights Reserved .

晓枫资讯--科技资讯社区

本站内容由用户自主分享和转载自互联网,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。

如有侵权、违反国家法律政策行为,请联系我们,我们会第一时间及时清除和处理! 举报反馈邮箱:点击这里给我发消息

Powered by Discuz! X3.5

快速回复 返回顶部 返回列表