Search code examples
python-2.7numpyrosrospy

how to read generator data as numpy array


def laser_callback(self, laserMsg):
     cloud = self.laser_projector.projectLaser(laserMsg)
     gen = pc2.read_points(cloud, skip_nans=True, field_names=('x', 'y', 'z'))
     self.xyz_generator = gen
     print(gen)

I'm trying to convert the laser data into pointcloud2 data, and then display them using matplotlib.pyplot. I tried traversing individual points in the generator but it takes a long time. Instead I'd like to convert them into a numpy array and then plot it. How do I go about doing that?


Solution

  • Take a look at some of these other posts which seem to answer the basic question of "convert a generator to an array":

    Without knowing exactly what your generator is returning, the best I can do is provide a somewhat generic (but not particularly efficient) example:

    #!/usr/bin/env -p python
    
    import numpy as np
    
    # Sample generator of (x, y, z) tuples
    def my_generator():
        for i in range(10):
            yield (i, i*2, i*2 + 1)
            i += 1
    
    def gen_to_numpy(gen):
        return np.array([x for x in gen])
    
    gen = my_generator()
    array = gen_to_numpy(gen)
    
    print(type(array))
    print(array)
    

    Output:

    <class 'numpy.ndarray'>
    [[ 0  0  1]
     [ 1  2  3]
     [ 2  4  5]
     [ 3  6  7]
     [ 4  8  9]
     [ 5 10 11]
     [ 6 12 13]
     [ 7 14 15]
     [ 8 16 17]
     [ 9 18 19]]
    

    Again though, I cannot comment on the efficiency of this. You mentioned that it takes a long time to plot by reading points directly from the generator, but converting to a Numpy array will still require going through the whole generator to get the data. It would probably be much more efficient if the laser to pointcloud implementation you are using could provide the data directly as an array, but that is a question for the ROS Answers forum (I notice you already asked this there).