numpy 从阵列到网格PLY文件

rlcwz9us  于 2023-06-23  发布在  其他
关注(0)|答案(2)|浏览(166)

我有一个numpy数组,其中包含表示点云的XYZ坐标。我想在列表中使用plyfile创建一个网格层文件,以便创建PLY网格文件。

vertex = [[52.45258174 78.63234647 -0.90487998]
           [52.46268174 78.68184647 1.09133402]
           [52.48928449 78.7930997 -0.90905187]
           [52.49938449 78.84259974 1.08716213]
           [52.5921233 78.92200466 -0.91276864]
           [52.6022233 78.97150466 1.08344536]]

PLY_vertices = PlyElement.describe(np.array(vertex, dtype=[('x', 'f4'), ('y', 'f4'),('z', 'f4')]), 'vertex')

ValueError: only one-dimensional arrays are supported
h43kikqp

h43kikqp1#

类似这样的东西应该可以做到这一点:

# If a zip object is okay
zip(arr1.flatten(), arr2.flatten(), arr3.flatten())

# If you want an ndarray
np.array(list(zip(arr1.flatten(), arr2.flatten(), arr3.flatten())))

它首先展平数组,然后创建所需的元组。
但是请记住,如果性能有问题,则应考虑使用3xN或Nx3坐标数组。
比如:

# 3xN array
np.vstack((arr1.flatten(), arr2.flatten(), arr3.flatten()))

# Nx3 array
np.column_stack((arr1.flatten(), arr2.flatten(), arr3.flatten()))
8hhllhi2

8hhllhi22#

https://pypi.org/project/plyfile/
显示了一些示例数组

vertex = numpy.array([(0, 0, 0),
                     (0, 1, 1),
                     (1, 0, 1),
                     (1, 1, 0)],
                     dtype=[('x', 'f4'), ('y', 'f4'),
                        ('z', 'f4')])
face = numpy.array([([0, 1, 2], 255, 255, 255),
                  ([0, 2, 3], 255,   0,   0),
                  ([0, 1, 3],   0, 255,   0),
                  ([1, 2, 3],   0,   0, 255)],
               dtype=[('vertex_indices', 'i4', (3,)),
                       ('red', 'u1'), ('green', 'u1'),
                      ('blue', 'u1')])

它们看起来像元组数组,但实际上是structured arrays。数据类型部分很重要。
我们可以进入构造方法,但首先需要提供上下文。

编辑

要创建结构化数组,数据必须是元组列表。
您的示例-二维数组:

In [221]: vertex = np.array([[52.45258174, 78.63234647, -0.90487998],
     ...:            [52.46268174, 78.68184647, 1.09133402],
     ...:            [52.48928449, 78.7930997, -0.90905187],
     ...:            [52.49938449, 78.84259974, 1.08716213],
     ...:            [52.5921233, 78.92200466, -0.91276864],
     ...:            [52.6022233, 78.97150466, 1.08344536]])
     ...: 
     ...: dtype=[('x', 'f4'), ('y', 'f4'),('z', 'f4')]

In [222]: vertex
Out[222]: 
array([[52.45258174, 78.63234647, -0.90487998],
       [52.46268174, 78.68184647,  1.09133402],
       [52.48928449, 78.7930997 , -0.90905187],
       [52.49938449, 78.84259974,  1.08716213],
       [52.5921233 , 78.92200466, -0.91276864],
       [52.6022233 , 78.97150466,  1.08344536]])

将其转换为元组列表:

In [223]: tups = [tuple(i) for i in vertex.tolist()]    
In [224]: tups
Out[224]: 
[(52.45258174, 78.63234647, -0.90487998),
 (52.46268174, 78.68184647, 1.09133402),
 (52.48928449, 78.7930997, -0.90905187),
 (52.49938449, 78.84259974, 1.08716213),
 (52.5921233, 78.92200466, -0.91276864),
 (52.6022233, 78.97150466, 1.08344536)]

现在创建结构化数组:

In [225]: M = np.array(tups, dtype)    
In [226]: M
Out[226]: 
array([(52.452583, 78.63235 , -0.90488   ),
       (52.46268 , 78.68185 ,  1.091334  ),
       (52.489285, 78.7931  , -0.9090519 ),
       (52.499386, 78.8426  ,  1.0871621 ),
       (52.592125, 78.922005, -0.91276866),
       (52.602222, 78.971504,  1.0834453 )],
      dtype=[('x', '<f4'), ('y', '<f4'), ('z', '<f4')])    
In [227]: M.shape, M.dtype
Out[227]: ((6,), dtype([('x', '<f4'), ('y', '<f4'), ('z', '<f4')]))

还有一个实用函数可以做到这一点:

In [232]: import numpy.lib.recfunctions as rf    
In [233]: M = rf.unstructured_to_structured(vertex, dtype)

第二次编辑

探索face结构:

In [236]: face = np.array([([0, 1, 2], 255, 255, 255),
     ...:                   ([0, 2, 3], 255,   0,   0),
     ...:                   ([0, 1, 3],   0, 255,   0),
     ...:                   ([1, 2, 3],   0,   0, 255)],
     ...:                dtype=[('vertex_indices', 'i4', (3,)),
     ...:                        ('red', 'u1'), ('green', 'u1'),
     ...:                       ('blue', 'u1')])

In [237]: face
Out[237]: 
array([([0, 1, 2], 255, 255, 255), ([0, 2, 3], 255,   0,   0),
       ([0, 1, 3],   0, 255,   0), ([1, 2, 3],   0,   0, 255)],
      dtype=[('vertex_indices', '<i4', (3,)), ('red', 'u1'), ('green', 'u1'), ('blue', 'u1')])

由于(3,),第一个字段返回一个二维数组:

In [238]: face['vertex_indices']
Out[238]: 
array([[0, 1, 2],
       [0, 2, 3],
       [0, 1, 3],
       [1, 2, 3]])

rf函数可以处理这个嵌套的dtype:

In [239]: arr = rf.structured_to_unstructured(face)

In [240]: arr
Out[240]: 
array([[  0,   1,   2, 255, 255, 255],
       [  0,   2,   3, 255,   0,   0],
       [  0,   1,   3,   0, 255,   0],
       [  1,   2,   3,   0,   0, 255]])

因此,如果你用足够的列创建一个2d数组,你可以创建一个face风格的结构化数组:

In [241]: rf.unstructured_to_structured(arr, face.dtype)
Out[241]: 
array([([0, 1, 2], 255, 255, 255), ([0, 2, 3], 255,   0,   0),
       ([0, 1, 3],   0, 255,   0), ([1, 2, 3],   0,   0, 255)],
      dtype=[('vertex_indices', '<i4', (3,)), ('red', 'u1'), ('green', 'u1'), ('blue', 'u1')])

同样,我只是从文档中提取的几个例子中工作。我还没有深入地研究过层格式。
有时,创建一个具有所需大小和dtype的“零”数组并单独填充字段值会更容易。许多rf函数都采用这种方法。通常数组的记录比字段多得多,所以我们不会因为在字段上迭代而损失太多的速度。

In [242]: M =  np.zeros(3, dtype=face.dtype)
In [243]: M
Out[243]: 
array([([0, 0, 0], 0, 0, 0), ([0, 0, 0], 0, 0, 0), ([0, 0, 0], 0, 0, 0)],
      dtype=[('vertex_indices', '<i4', (3,)), ('red', 'u1'), ('green', 'u1'), ('blue', 'u1')])

In [244]: M['vertex_indices'] = np.arange(9).reshape(3,3)
In [245]: M
Out[245]: 
array([([0, 1, 2], 0, 0, 0), ([3, 4, 5], 0, 0, 0), ([6, 7, 8], 0, 0, 0)],
      dtype=[('vertex_indices', '<i4', (3,)), ('red', 'u1'), ('green', 'u1'), ('blue', 'u1')])

相关问题