简体   繁体   中英

PCL: PCLvisualizer multiple point clouds (XYZ) in same viewport with different colours

I have a vector of point clouds of spatial points (XYZ only) which I am trying to display in the same window with different colours. I am using custom colour handlers in the PCLvisualizer.

Unfortunately the colours aren't different in the viewer on display however, but all the points are displayed in the same colour (the second one). It seems like the colour is changed for all the previous points in the viewer each time a new point cloud is added.

Here is my code:

pcl::visualization::PCLVisualizer viewer; 
viewer.setBackgroundColor (0, 0, 0); 

std::stringstream cloud_name; 
int counter(0); 
pcl::RGB rgb_color; 

for (auto curr_cloud : clouds_vector) 
{ 
    rgb_color = pcl::GlasbeyLUT::at(counter); 
    ++counter; 
    cloud_name.str(""); 
    cloud_name << "Cloud " << counter; 

    if (counter < 5) 
    { 
        pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> first_color(curr_cloud, rgb_color.r, rgb_color.g, rgb_color.b); 
        viewer.addPointCloud<pcl::PointXYZ> (curr_cloud, first_color, cloud_name.str()); 
    } 
    else 
    { 
        pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> second_color(curr_cloud, rgb_color.r, rgb_color.g, rgb_color.b); 
        viewer.addPointCloud<pcl::PointXYZ> (curr_cloud, second_color, cloud_name.str()); 
    } 

    viewer.setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 8, cloud_name.str()); 
}

Any ideas why this might be and what to change?

Many thanks to you all in advance!

EDIT : I have tried around a little, and the problem doesn't seem to be the way I'm visualising the point clouds itself (above described way is working with freshly created clouds with random values.

In my use case I am extracting multiple point clouds with the help of their indices from a single point cloud. If I do that they still all hold the same colour upon visualisation. I still can't figure out why that's the case though and am happy for any suggestions. Here is the full code with the extraction (for the benefit of a minimal example with a randomly created mother point cloud from which the extraction is taking place):

PointCloudT::Ptr cloud (new PointCloudT);
    // 100 points in point cloud, random coordinates
    cloud->resize(100);
    for (PointCloudT::iterator cloud_it (cloud->begin()); cloud_it != cloud->end(); ++cloud_it) {
        cloud_it->x = 1024 * rand () / (RAND_MAX + 1.0f);
        cloud_it->y = 1024 * rand () / (RAND_MAX + 1.0f);
        cloud_it->z = 1024 * rand () / (RAND_MAX + 1.0f);
    }

    // Create index vectors containing 20 indices each
    std::vector <pcl::PointIndices> point_indices_vector;
    int offset(20);
    pcl::PointIndices indices;
    for (int i=0;i<5;++i) {
        for (int j=0;j<20;++j) {
            indices.indices.push_back(j + i * offset);
        }
        point_indices_vector.push_back(indices);
        indices.indices.clear(); // <----- THIS WAS MISSING
    }

    // Create extraction object to copy points from 100 strong cloud to 20-point clouds
    pcl::ExtractIndices<PointT> extract;
    extract.setInputCloud (cloud);
    extract.setNegative (false);

    // Extract points and copy them to clouds vector
    std::vector<PointCloudT::Ptr, Eigen::aligned_allocator<PointCloudT::Ptr> > clouds_vector;
    PointCloudT::Ptr curr_segment_cloud;

    for (auto curr_index_vector : point_indices_vector) {
        curr_segment_cloud.reset (new PointCloudT);
        // Copy points of current line segment from source cloud into current segment cloud
        extract.setIndices(boost::make_shared<const pcl::PointIndices> (curr_index_vector));
        extract.filter (*curr_segment_cloud);

        // Push back point cloud into return vector
        clouds_vector.push_back(curr_segment_cloud);
    }

    // Create viewer
    pcl::visualization::PCLVisualizer viewer;
    viewer.setBackgroundColor (0, 0, 0);

    // Visualize point clouds from clouds vector
    std::stringstream cloud_name;
    int counter(0);
    pcl::RGB rgb;
    for (auto curr_cloud : clouds_vector) {
        ++counter;
        cloud_name.str("");
        cloud_name << "Cloud " << counter;

        // Generate unique colour
        rgb = pcl::GlasbeyLUT::at(counter);

        // Create colour handle
        pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> colour_handle(curr_cloud, rgb.r, rgb.g, rgb.b);

        // Add points to viewer and set parameters
        viewer.addPointCloud<pcl::PointXYZ> (curr_cloud, colour_handle, cloud_name.str());
        viewer.setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 8, cloud_name.str());
    }

    // Keep viewer running
    while (!viewer.wasStopped()) {
        viewer.spinOnce(100);
        boost::this_thread::sleep (boost::posix_time::microseconds (100000));
    }

Problem solved!

So if anybody wants to use the code... both of the snippets above are now working. (I found the mistake and corrected it in the above code snippet).

I'm embarrassed to say that I simply forgot to clear my extraction indices vector before extracting the points. So the last cloud was the full cloud again and was plotting over all of the before added points making them invisible. This way all the points seemed the same colour. oO

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM