Home > Software design >  how to accelerate the numpy for-loop, for coloring point-cloud by its intensity
how to accelerate the numpy for-loop, for coloring point-cloud by its intensity

Time:02-02

enter code hereI want to color a point-cloud by its intensity.

currently I use the following for-loop to apply a colormap function to the intensity(4th-dim) of points:

import numpy as np
points = np.random.random([128*1200,4])
points_colors = np.zeros([points.shape[0], 3])

for idx, p_c in enumerate(points[:, 3]):
    points_colors[idx, :] = color_map(p_c)
points_colors /= 255.0

an example of color mapping function:

def color_map( value, minimum=0, maximum=255):
    minimum, maximum = float(minimum), float(maximum)
    ratio = 2 * (value-minimum) / (maximum - minimum)
    b = int(max(0, 255*(1 - ratio)))
    r = int(max(0, 255*(ratio - 1)))
    g = 255 - b - r
    return r, g, b

Coloring the point clouds consumes much more time than directly use open3d's original colormap(i.e. color by points' x,y,z-pose)

How could I accelerate the process of color-mapping point-clouds by its intensity?

Other solution that does not convert xyzi-point-cloud to xyzrgb-point-cloud is also welcomed.


Ps. the color_map I am actually using is a bit more complicated but has same output:

def rainbow_color_map(
    val,
    minval = 0
    maxval=256,
    normalize=False,
    colors=[(1, 1, 255), (1, 255, 1), (255, 1, 1)] * 10,
):
    i_f = float(val - minval) / float(maxval - minval) * (len(colors) - 1)

    i, f = int(i_f // 1), i_f % 1  # Split into whole & fractional parts.

    (r1, g1, b1), (r2, g2, b2) = colors[i], colors[i   1]
    if normalize:
        return (
            (r1   f * (r2 - r1)) / maxval,
            (g1   f * (g2 - g1)) / maxval,
            (b1   f * (b2 - b1)) / maxval,
        )
    else: 
        return r1   f * (r2 - r1), g1   f * (g2 - g1), b1   f * (b2 - b1)

CodePudding user response:

You can modify the function to calculate the array as a whole without using a loop:

def color_map(minimum, maximum, value):
    minimum, maximum = float(minimum), float(maximum)
    ratio = 2 * (value-minimum) / (maximum - minimum)
    
    b = 255*(1 - ratio)
    b[b<0] = 0
    b = b.astype(int)
    
    r = 255*(ratio - 1)
    r[r<0] = 0
    r = r.astype(int)
    
    g = 255 - b - r
    
    points_colors = np.c_[r, g, b]
    
    return points_colors

Then call the function like this :

import numpy as np
points = np.random.random([128*1200,4])
minimum, maximum = np.min(points[:, 3]), np.max(points[:, 3])
points_colors = color_map(minimum, maximum, points[:, 3])
  • Related