2017-10-12 94 views
0

我将此深度图像转换为pcl :: pointcloud。pcl ::点云到cv ::垫深度图像

enter image description here

使用下列内容:

PointCloud::Ptr PointcloudUtils::RGBDtoPCL(cv::Mat depth_image, Eigen::Matrix3f& _intrinsics) 
{ 
    PointCloud::Ptr pointcloud(new PointCloud); 

    float fx = _intrinsics(0, 0); 
    float fy = _intrinsics(1, 1); 
    float cx = _intrinsics(0, 2); 
    float cy = _intrinsics(1, 2); 

    float factor = 1; 

    depth_image.convertTo(depth_image, CV_32F); // convert the image data to float type 

    if (!depth_image.data) { 
     std::cerr << "No depth data!!!" << std::endl; 
     exit(EXIT_FAILURE); 
    } 

    pointcloud->width = depth_image.cols; //Dimensions must be initialized to use 2-D indexing 
    pointcloud->height = depth_image.rows; 
    pointcloud->resize(pointcloud->width*pointcloud->height); 

#pragma omp parallel for 
    for (int v = 0; v < depth_image.rows; v += 4) 
    { 
     for (int u = 0; u < depth_image.cols; u += 4) 
     { 
      float Z = depth_image.at<float>(v, u)/factor; 

      PointT p; 
      p.z = Z; 
      p.x = (u - cx) * Z/fx; 
      p.y = (v - cy) * Z/fy; 

      p.z = p.z/1000; 
      p.x = p.x/1000; 
      p.y = p.y/1000; 

      pointcloud->points.push_back(p); 

     } 
    } 

    return pointcloud; 

} 

这个伟大的工程,我已经运行在云上的一些处理,现在我需要将点云转换回CV ::垫深度图像。我找不到这样的例子,并且无法绕过它。与上述功能相反的是什么?

我该如何将pcl :: pointcloud转换回cv :: mat?

谢谢。

+0

你想的'PX, py,pz'代表一个浮点像素? – zindarod

+0

嗨,谢谢你的回复。我想是的,是的。基本上我想结束上面的图像。相同数量的列/行。 – anti

+0

...目标是扭转上述功能。所以从图像到点云,然后回到完全相同的图像。谢谢! – anti

回答

0

这是未经测试的代码,因为我的机器上没有点云。 从您自己的转换代码中,我假设您的图像是单通道图像。

void PCL2Mat(PointCloud::Ptr pointcloud, cv::Mat& depth_image, int original_width, int original_height) 
{ 
    if (!depth_image.empty()) 
     depth_image.release(); 

    depth_image.create(original_height, original_width, CV_32F); 

    int count = 0; 

    #pragma omp parallel for 
    for (int v = 0; v < depth_image.rows; ++v) 
    { 
     for (int u = 0; u < depth_image.cols; ++u) 
     { 
      depth_image.at<float>(v, u) = pointcloud->points.at(count++).z * 1000; 

     } 
    } 

    depth_image.convertTo(depth_image,CV_8U); 

} 
+0

谢谢!我运行这个:'PCL2Mat(newCloud,newDepth,depth_image.cols,depth_image.rows,depth_image.channels());''它给了我一个黑色的图像。 – anti

+0

嗯,我没有PointCloud,我不知道你在点云数据上执行了什么流程,所以我不能再帮你了。但是这段代码应该向你展示从PCL转换为Mat的基础知识。 – zindarod

+0

这是为了测试目的而直接转换而不进行处理的情况。它可能是渠道吗?再次感谢 – anti

0

我不知道OpenCV的方法,但如果你做一些让您的点云数据是非结构化的过程可能是这样的

% rescale the points by 1000 
p.x = p.x * 1000; p.y = p.y * 1000; p.z = p.z * 1000; 

% project points on image plane and correct center point + factor 
image_p.x = (p.x * fx/p.z -cf) * factor; 
image_p.y = (p.y * fy/p.z -cy) * factor; 

现在取决于你有做了什么点云可能不会完全映射到图像矩阵像素中心点(或某些应用程序的左上角),或者您可能缺少点 - > NaN/0值像素。你怎么处理是你的,但最简单的方法是将投image_p.x和image_p.y为整数,确保它们withing图像边界,并设置

depth_image.at<float>(image_p.y, image_p.x) = p.Z;`