ホームページ  >  記事  >  バックエンド開発  >  NumPy を使用して Python で点群データを読み取り、保存する方法

NumPy を使用して Python で点群データを読み取り、保存する方法

WBOY
WBOY転載
2022-09-02 16:52:162394ブラウズ

[関連する推奨事項: Python3 ビデオ チュートリアル ]

まえがき

最近点群処理を学習していたときのことModelnet40 データ セットが使用されます。このデータ セットには合計 40 カテゴリがあります。各サンプルの点群データは TXT ファイルに保存されます。 line 最初の 3 つのデータは、点の xyz 座標を表します。 TXT ファイル内の各ポイントを読み取り、Open3D を使用して表示する必要があります。 TXT ファイルからデータを読み取る方法は? NumPy は、この関数を非常に簡単に実装できる非常に強力な関数 loadtxt を提供します。コードを見てみましょう:

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

上記のコードからわかるように、TXT ファイル内の点群データを読み取るために必要なコードは 1 行だけです。 Open3Dのインターフェースが表示されます。 loadtxt 関数の使用法を紹介する前に、

Open3D の表示効果を見てみましょう:

loadtxt 関数の使い方

基本的な使い方

上記の例では、TXT の各行のデータがカンマで区切られているため、loadtxt を呼び出す際に関数を使用する場合は、ファイル パスの設定に加えて、パラメータ delimiter="," も設定する必要があります。また、この関数のデフォルトのデータ型は float64 ですが、他のデータ型の場合は、dtype を対応する型に設定する必要があります。

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

結果:

形状: (10000, 6)
データ型: float64

各列を指定データ型

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

ファイルの最初の 3 列のデータ型は浮動小数点で、次の 2 つの列が整数型である場合、前の方法で読み取るように dtype を設定することは適切ではありません。しかし、それは問題ではありません。loadtxt 関数はデータの各列のデータ型を設定できますが、少し複雑です。コードを見てみましょう:

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)

このコードの重要なポイントは、dtype={ }内部のコンテンツ 'names' は、データの各列の名前 'formats'## を設定するために使用されます。 # はデータの各列のデータ型を設定するために使用されます。そのうち、 'f4'float32 を表し、'i4'int32## を表します。 #。また、CSV ファイルの最初の行はデータの内容ではないため、パラメータ skiprows=1 を設定すると、最初の行の内容をスキップできます。

出力結果:

データ: [(-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)]

データ型: [('x', '

このように
dtype

を設定すると、読み取られたデータの各行が tuple 型になることがわかります。 ジェネレーターと組み合わせて使用​​する

NumPy

のドキュメントから、loadtxt 関数の最初のパラメーターはファイルオブジェクトまたはファイル名またはジェネレータ。ジェネレーターを渡すと何の役に立つのでしょうか?いくつかの例を見てみましょう。

複数の区切り文字の処理

ファイルの内容が次のような場合、データの各行には 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
この場合、

delimiter

パラメーターを使用して複数の区切り文字を設定することはできません。この場合、ジェネレーターを使用して処理できます:

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)
このコードは、ファイル内の各行のすべての区切り文字を

loadtxt

関数のデフォルトのスペース区切り文字に置き換えるジェネレーターを構築し、そのジェネレーターを loadtxt## に渡します。 # 関数を使用して、loadtxt 関数がファイル内のデータを正常に解析できるようにします。 出力結果:

[[ 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.  ]]

通过上面的例子可以知道,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视频教程

以上がNumPy を使用して Python で点群データを読み取り、保存する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はjb51.netで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。