【发布时间】:2017-06-08 13:18:10
【问题描述】:
我正在尝试将带有 rgb 信息的点云从 pcl 格式转换为 cv::Mat 并返回到 pcl。我在 stackoverflow 上找到了convert mat to pointcloud。
代码更新
因此,我使用在 stackoverflow 上找到的代码作为起点。现在有以下内容:
//input pcl::PointCloud<pcl::PointXYZRGB> point_cloud_ptr
cv::Mat OpenCVPointCloud(3, point_cloud_ptr.points.size(), CV_64FC1);
OpenCVPointCloudColor = cv::Mat(480, 640, CV_8UC3);
for(int y=0;y<OpenCVPointCloudColor.rows;y++)
{
for(int x=0;x<OpenCVPointCloudColor.cols;x++)
{
OpenCVPointCloud.at<double>(0,y*OpenCVPointCloudColor.cols+x) = point_cloud_ptr.points.at(y*OpenCVPointCloudColor.cols+x).x;
OpenCVPointCloud.at<double>(1,y*OpenCVPointCloudColor.cols+x) = point_cloud_ptr.points.at(y*OpenCVPointCloudColor.cols+x).y;
OpenCVPointCloud.at<double>(2,y*OpenCVPointCloudColor.cols+x) = point_cloud_ptr.points.at(y*OpenCVPointCloudColor.cols+x).z;
cv::Vec3b color = cv::Vec3b(point_cloud_ptr.points.at(y*OpenCVPointCloudColor.cols+x).b,point_cloud_ptr.points.at(y*OpenCVPointCloudColor.cols+x).g,point_cloud_ptr.points.at(y*OpenCVPointCloudColor.cols+x).r);
OpenCVPointCloudColor.at<cv::Vec3b>(cv::Point(x,y)) = color;
}
}
cv::imshow("view 2", OpenCVPointCloudColor);
cv::waitKey(30);
显示上面的图像可确保正确提取颜色(通过肉眼将图像与原始图像进行比较)。然后我想将其转换回点云:
pcl::PointCloud<pcl::PointXYZRGB>::Ptr point_cloud_ptr(new pcl::PointCloud<pcl::PointXYZRGB>);
for(int y=0;y<OpenCVPointCloudColor.rows;y++)
{
for(int x=0;x<OpenCVPointCloudColor.cols;x++)
{
pcl::PointXYZRGB point;
point.x = OpencVPointCloud.at<double>(0,y*OpenCVPointCloudColor.cols+x);
point.y = OpencVPointCloud.at<double>(1,y*OpenCVPointCloudColor.cols+x);
point.z = OpencVPointCloud.at<double>(2,y*OpenCVPointCloudColor.cols+x);
cv::Vec3b color = OpenCVPointCloudColor.at<cv::Vec3b>(cv::Point(x,y));
//Try 1 not working
//uint8_t r = (color[2]);
//uint8_t g = (color[1]);
//uint8_t b = (color[0]);
//Try 2 not working
//point.r = color[2];
//point.g = color[1];
//point.b = color[0];
//Try 3 not working
//uint8_t r = (color.val[2]);
//uint8_t g = (color.val[1]);
//uint8_t b = (color.val[0]);
//test working WHY DO THE ABOVE CODES NOT WORK :/
uint8_t r = 255;
uint8_t g = 0;
uint8_t b = 0;
int32_t rgb = (r << 16) | (g << 8) | b;
point.rgb = *reinterpret_cast<float*>(&rgb);
point_cloud_ptr -> points.push_back(point);
}
}
谁能解释为什么明确指定 255,0,0 的值将所有颜色都染成红色。但是如果我从彩色图像中选择输出,云的颜色是错误的?
偶然发现this,除了云类型不同之外,我看不出我的代码有什么不同?
更新
阅读this 关于 PCL 的讨论以我切换到 xyzrgba 结束(stackoverflow 也提到过)。然后我在转换回来时尝试的代码是:
point.b = OpenCVPointCloudColor.at<cv::Vec3b>(x,y)[0];
point.g = OpenCVPointCloudColor.at<cv::Vec3b>(x,y)[1];
point.r = OpenCVPointCloudColor.at<cv::Vec3b>(x,y)[2];
point.a = 255;
生成的颜色云与在 XYZRGB 中创建的颜色云不同,但仍然是错误的:/ WTF?
额外
即使我使用 cvCloudColor.at<cv::Vec3f>(x,y) = cv::Vec3f(0,0,255); 将红色强制添加到所有点 OpenCVPointCloudColor,然后从 OpenCVPointCloudColor 读取仍然会在 pcl 云中创建错误的颜色信息。
【问题讨论】:
-
在示例中,您似乎将点存储在
OpenCVPointCloudColor中,同时尝试从colorImage读取它们。是一样的吗? -
@iamai 是的,我现在将更新问题,使它们具有相同的变量名。 (只是在两个函数调用中使用它们)。
-
(与上面的代码无关)如果您尝试从使用 OpenCV 加载的图像中读取它们,请注意默认颜色系统是 BGR 而不是 RGB。这可能会影响颜色。
-
@like444 是的,没错。但这对上面的代码应该没有任何影响吧?
标签: c++ opencv ros point-cloud-library point-clouds