Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Cara menggunakan NumPy untuk membaca dan menyimpan data awan titik dalam Python

Cara menggunakan NumPy untuk membaca dan menyimpan data awan titik dalam Python

WBOY
WBOYke hadapan
2022-09-02 16:52:162424semak imbas

[Cadangan berkaitan: Tutorial video Python3]

Kata Pengantar

Baru-baru ini semasa saya belajar pemprosesan awan titik Set data Modelnet40 digunakan, yang mempunyai sejumlah kategori 40 Data awan titik setiap sampel disimpan dalam fail TXT 3 data pertama dalam setiap baris mewakili koordinat xyz a titik. Saya perlu membaca setiap titik dalam fail TXT dan kemudian menggunakan Open3D untuk memaparkannya. Bagaimana untuk membaca data daripada fail TXT? NumPy Menyediakan fungsi yang sangat berkuasa loadtxt yang boleh melaksanakan fungsi ini dengan sangat mudah. Mari lihat kod:

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()

Seperti yang anda lihat daripada kod di atas, anda hanya memerlukan satu baris kod untuk membaca data awan titik dalam fail TXT, dan kemudian anda boleh antara muka panggilan Open3D dipaparkan. Sebelum memperkenalkan penggunaan fungsi loadtxt,

lihat pada kesan paparan Open3D:

Penggunaan fungsi loadtxt

Penggunaan Asas

Dalam contoh di atas, memandangkan data dalam setiap baris dalam TXT dipisahkan dengan koma, selain daripada menetapkan laluan fail apabila memanggil loadtxt fungsi, Perlu menetapkan parameter delimiter=",". Selain itu, jenis data lalai bagi fungsi ini ialah float64 Jika jenis data lain, anda perlu menetapkan dtype kepada jenis yang sepadan.

points_data = np.loadtxt("airplane_0001.txt", delimiter=",") #没有指定数据类型
print('shape: ', points_data.shape)
print('data type: ', points_data.dtype)

Hasil:

bentuk: (10000, 6)
jenis data: float64

Nyatakan Jenis data setiap lajur

Jika kita mempunyai fail CSV:

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

Jenis data bagi 3 lajur pertama fail ialah titik terapung dan jenis data 2 lajur terakhir ialah jenis integer, maka ia tidak sesuai untuk menetapkan dtype untuk membaca dengan cara sebelumnya. Tetapi tidak mengapa Fungsi loadtxt boleh menetapkan jenis data setiap lajur data, tetapi ia lebih rumit sedikit:

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)

Tumpuan bagi kod ini ialah kandungan di dalam dtype={}, 'names' digunakan untuk menetapkan nama setiap lajur data dan 'formats' digunakan untuk menetapkan jenis data setiap lajur data, dengan 'f4' mewakili float32 dan 'i4' mewakili int32. Selain itu, baris pertama dalam fail CSV bukan kandungan data dan anda boleh menetapkan parameter skiprows=1 untuk melangkau kandungan baris pertama.

Hasil keluaran:

data: [(-0.09879, -0.1823 , 0.1638 , 1, 1) ( 0.9946 , 0.25, 0.0420 )
( 0.1899 , -0.2922 , -0.9263 , 3, 3) (-0.9892 , 0.07461, -0.01235, 4, 4)]
jenis data: [('x', '

Anda boleh melihat bahawa dengan menetapkan dtype dengan cara ini, setiap baris data yang dibaca menjadi jenis tuple.

Gunakan dengan penjana

Daripada dokumentasi NumPy, anda boleh tahu bahawa parameter pertama fungsi loadtxt boleh menjadi objek fail, nama fail atau penjana. Apakah kegunaan hantaran dalam penjana? Mari lihat beberapa contoh.

Mengendalikan berbilang pembatas

Jika kandungan fail kami seperti ini, setiap baris data mempunyai 3 pembatas ",", "/" dan "-" :

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

Dalam kes ini, berbilang pembatas tidak boleh ditetapkan melalui parameter delimiter boleh diproses melalui penjana pada masa ini:

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)
Kod ini membina penjana untuk menggantikan semua pembatas setiap baris dalam fail dengan pembatas ruang lalai bagi fungsi

dan kemudian menghantar penjana ke dalam fungsi loadtxt, seperti ini loadtxt fungsi berjaya menghuraikan data dalam fail. loadtxt

Hasil keluaran:

[[ 9.87 1.82 1.63 1. 11. 1. ]

[ 9.94 7.44 1.02 ] 2. .
[ 1.89 2.92 9.26 1. 11. 3. ]
[ 0.98 7.46 1.23 1. 11. 4. ]]

Baca baris yang ditentukan >

在某些情况下,我们需要读取指定几行的数据,那么也可以通过生成器来实现。还是上面的文件内容,我们通过生成器来读取第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.  ]]

通过上面的例子可以知道,loadtxt函数结合生成器使用可以实现很多的功能。

tofile和fromfile函数

TXT文件中读取到点云数据后,我想把数据保存到二进制文件中,需要怎么操作呢?NumPyndarray类提供了tofile函数可以非常方便地将数据保存到二进制文件中。把数据以二进制文件保存后又怎么读进来呢?NumPy还提供了一个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()

在上面这段示例代码中,我从airplane_0001.txt文件中读取了点云数据,然后通过tofile函数将数据保存到二进制文件airplane_0001.bin中,再用fromfile函数从二进制文件中把点云数据读取出来用Open3D进行显示。

为了前后呼应,让我们换个角度再看一眼显示效果:

【相关推荐:Python3视频教程

Atas ialah kandungan terperinci Cara menggunakan NumPy untuk membaca dan menyimpan data awan titik dalam Python. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:jb51.net. Jika ada pelanggaran, sila hubungi admin@php.cn Padam