将 3D 点列表栅格化为 2D 画布

Rasterize list of 3d points into 2d canvas

提问人:erik 提问时间:10/16/2023 最后编辑:erik 更新时间:10/17/2023 访问量:50

问:

我有一个 3D 点列表,这个列表看起来像(但包含大约 45k 个点)

ps = array([[0.77258706, 1.1149821 , 1.0494938 ],
       [0.77258706, 1.1149821 , 1.0494938 ],
       [0.77258706, 1.1149821 , 1.0494938 ],
       [1.3196146 , 1.2129393 , 0.96248001],
       [1.3197775 , 1.2117194 , 0.96213955],
       [1.3199375 , 1.2104989 , 0.96179962],
       [1.3200942 , 1.2092786 , 0.96145791],
       [1.3202487 , 1.2080572 , 0.96111906],
       [1.3204001 , 1.2068353 , 0.96078068]])

我想把它们投影到2D画布上。

由于点云已经正确对齐,我可以直接从点获取 x 和 y 坐标,并使用 z 组件设置颜色(所有值都会缩放以适合画布)。

canv = np.zeros(shape=[3840, 2160, 3])
for p in ps:
    x_pos = p[0] * scale_factor
    y_pos = p[1] * scale_factor
    val =   p[2] * color_scale_factor
    canv[int(x_pos)][int(y_pos)][0:3] = colors[int(val)].get_rgb()

目前,每帧大约需要 120 毫秒 (8FPS)。

有没有办法通过使用一些麻木魔法来显着改善这一点? 任何帮助都是值得赞赏的。

Python 数组 numpy 矩阵 投影

评论

1赞 Raphael 10/16/2023
对不起,您还能说明和是什么类型吗?colorsps
0赞 erik 10/17/2023
ps 是一个数组,如上所示(ps 表示点),colors 是一个“颜色对象”数组,.get_rgbs使其成为 RGB 三元组。我已经在改进版本中预先计算了 rgb 三元组,使其成为三元组数组。

答:

0赞 Raphael 10/16/2023 #1

使用 numpy 矢量化函数而不是 for 循环可能会有一些改进,但是由于我不知道 colors[val].get_rgb() 的作用,我无法为此提出解决方案。

但是,您可以尝试将函数包装在 numba jit 包装器中,这会预编译 python 代码并可以并行执行 for 循环。

import numba as nb
@nb.njit(parallel=True)
def convert(array_3d):
    canv = np.zeros(shape=[3840, 2160, 3])
    for p in array_3d:
        x_pos = p[0] * scale_factor
        y_pos = p[1] * scale_factor
        val =   p[2] * color_scale_factor
        canv[int(x_pos)][int(y_pos)][0:3] = colors[int(val)].get_rgb()
    return canv
3赞 pho 10/16/2023 #2

使用 numpy 函数而不是遍历点:

x_pos = (p[:, 0] * scale_factor).astype(int)
y_pos = (p[:, 1] * scale_factor).astype(int)
val =   (p[:, 2] * color_scale_factor).astype(int)

由于看起来像是某种对象的列表,因此您可以在执行任何操作之前预先计算 RGB 值数组:colorsColor

colors_rgb = np.array([c.get_rgb() for c in colors])

然后,您可以使用以下方法索引此数组:val

canv[x_pos, y_pos] = colors_rgb[val]

为了演示这一点,我将使用一个点列表示例和一个较小的画布:

canv = np.zeros((4, 4, 3))
p = np.array([[0.1, 0.1, 0],
              [1.1, 1.1, 1],
              [2.2, 2.2, 2],
              [3.3, 3.3, 3]])

scale_factor = color_scale_factor = 1

假设包含一堆对象(只要给出(至少)3 个长可迭代对象,它包含什么并不重要):colorsColorColor.get_rgb

class Color:
    def __init__(self, r, g, b):
        self.rgb = np.array([r, g, b]) / 255

    def get_rgb(self):
        return self.rgb

colors = [Color(255, 0, 0), Color(0, 255, 0), Color(0, 0, 255), Color(128, 128, 0), Color(0, 128, 128), Color(128, 0, 128)]

我们有:colors_rgb

array([[1.        , 0.        , 0.        ],
       [0.        , 1.        , 0.        ],
       [0.        , 0.        , 1.        ],
       [0.50196078, 0.50196078, 0.        ],
       [0.        , 0.50196078, 0.50196078],
       [0.50196078, 0.        , 0.50196078]])

并变成:canv

array([[[1.        , 0.        , 0.        ],
        [0.        , 0.        , 0.        ],
        [0.        , 0.        , 0.        ],
        [0.        , 0.        , 0.        ]],

       [[0.        , 0.        , 0.        ],
        [0.        , 1.        , 0.        ],
        [0.        , 0.        , 0.        ],
        [0.        , 0.        , 0.        ]],

       [[0.        , 0.        , 0.        ],
        [0.        , 0.        , 0.        ],
        [0.        , 0.        , 1.        ],
        [0.        , 0.        , 0.        ]],

       [[0.        , 0.        , 0.        ],
        [0.        , 0.        , 0.        ],
        [0.        , 0.        , 0.        ],
        [0.50196078, 0.50196078, 0.        ]]])