I have a List of 3D Points, this list looks something like (but contains around 45k points)
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]])
and I want to project these onto a 2D Canvas.
Due to the Pointcloud already being aligned correctly, I can just take the x and y coordinates directly from the points and use the z component to set the color (all the values get scaled to fit on the canvas).
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()
Currently this takes ca. 120ms per frame (8FPS).
Is there a way to significantly improve this by using some numpy magic? Any help is appreciated.
Use numpy functions instead of looping over the points:
x_pos = (p[:, 0] * scale_factor).astype(int)
y_pos = (p[:, 1] * scale_factor).astype(int)
val = (p[:, 2] * color_scale_factor).astype(int)
Since colors
seems like a list of some kind of Color
object, you can pre-calculate an array of RGB values prior to doing anything:
colors_rgb = np.array([c.get_rgb() for c in colors])
Then, you can index into this array using your val
:
canv[x_pos, y_pos] = colors_rgb[val]
To demonstrate this, I'm going to use an example list of points and a smaller canvas:
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
Assuming colors
contains a bunch of Color
objects (it doesn't matter what it contain as long as Color.get_rgb
gives a (at least) 3-long iterable):
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)]
We have colors_rgb
as:
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]])
and canv
becomes:
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. ]]])