PCL区域生长分割后,用OpenCV显示RGB点云无颜色如何解决?
解决PCL区域生长分割后OpenCV Viz无颜色显示的问题
问题根源
你的代码里只把点云的坐标信息(x,y,z)存入了buffer,完全丢弃了PCL区域生长算法生成的RGB颜色数据。OpenCV的WCloudCollection默认会用单一颜色渲染点云,自然看不到分割后的彩色效果。
修复步骤及代码修改
我们需要同时保存点的坐标和颜色信息,然后在创建Viz Widget时传入颜色数据,具体修改如下:
- 调整缓冲区数据类型:用
cv::Vec6f替代cv::Vec3f,用来存储(x,y,z,r,g,b)六个分量(颜色分量要转成0-1的浮点数,因为OpenCV Viz的颜色范围是0到1)。 - 修正点云数据读取逻辑:从
colored_cloud中同时提取坐标和RGB颜色,并转换格式。 - 正确创建带颜色的点云Widget:使用
WCloud的重载构造函数,分别传入坐标矩阵和颜色矩阵。
修改后的核心代码片段:
// 把buffer的类型改成存储x,y,z,r,g,b的Vec6f std::vector<cv::Vec6f> buffer; // 替换原来的循环,同时提取坐标和颜色 pcl::PointCloud <pcl::PointXYZRGB>::Ptr colored_cloud = reg.getColoredCloud(); for (int j = 0; j < colored_cloud->points.size(); j++) { // PCL的RGB是uint8类型,转成0-1的float适配OpenCV Viz float r = colored_cloud->points[j].r / 255.0f; float g = colored_cloud->points[j].g / 255.0f; float b = colored_cloud->points[j].b / 255.0f; buffer.push_back(cv::Vec6f( colored_cloud->points[j].x, colored_cloud->points[j].y, colored_cloud->points[j].z, r, g, b )); } // 拆分坐标和颜色矩阵 cv::Mat cloudMat(static_cast<int>(buffer.size()), 1, CV_32FC6, &buffer[0]); cv::Mat coords = cloudMat.colRange(0, 3); // 提取x,y,z坐标 cv::Mat colors = cloudMat.colRange(3, 6); // 提取r,g,b颜色 // 创建带颜色的点云Widget cv::viz::WCloud cloudWidget(coords, colors); viewer.setBackgroundColor(cv::viz::Color::black()); viewer.showWidget("Cloud", cloudWidget); viewer.spin(); // 用spin()替代spinOnce()可持续显示窗口,直到手动关闭 buffer.clear();
额外注意事项
- 如果你坚持用
WCloudCollection,需要给每个云添加时单独指定颜色,但直接用WCloud传入颜色矩阵更简单直接。 - 可以在代码中打印
colored_cloud->points[0].r/g/b的值,验证区域生长算法是否成功给不同簇分配了差异化颜色。 spinOnce()只会刷新一次窗口就结束,容易导致看不到效果,换成spin()可以让窗口持续显示直到手动关闭。
内容的提问来源于stack exchange,提问作者Giant Cloud




