从一个点云里面创建一个深度图

这次,我们将显示如何从一个点云和一个给定的传感器来创造深度图。下面的代码,创建了一个在观察者前面的矩形。

#include <pcl/range_image/range_image.h>

int main (int argc, char** argv) {
  pcl::PointCloud<pcl::PointXYZ> pointCloud;
  
  // Generate the data
  for (float y=-0.5f; y<=0.5f; y+=0.01f) {
    for (float z=-0.5f; z<=0.5f; z+=0.01f) {
      pcl::PointXYZ point;
      point.x = 2.0f - y;
      point.y = y;
      point.z = z;
      pointCloud.points.push_back(point);
    }
  }
  pointCloud.width = (uint32_t) pointCloud.points.size();
  pointCloud.height = 1;
  
  // We now want to create a range image from the above point cloud, with a 1deg angular resolution
  float angularResolution = (float) (  1.0f * (M_PI/180.0f));  //   1.0 degree in radians
  float maxAngleWidth     = (float) (360.0f * (M_PI/180.0f));  // 360.0 degree in radians
  float maxAngleHeight    = (float) (180.0f * (M_PI/180.0f));  // 180.0 degree in radians
  Eigen::Affine3f sensorPose = (Eigen::Affine3f)Eigen::Translation3f(0.0f, 0.0f, 0.0f);
  pcl::RangeImage::CoordinateFrame coordinate_frame = pcl::RangeImage::CAMERA_FRAME;
  float noiseLevel=0.00;
  float minRange = 0.0f;
  int borderSize = 1;
  
  pcl::RangeImage rangeImage;
  rangeImage.createFromPointCloud(pointCloud, angularResolution, maxAngleWidth, maxAngleHeight,
                                  sensorPose, coordinate_frame, noiseLevel, minRange, borderSize);
  
  std::cout << rangeImage << "\n";
}

下面是代码解释:

#include <pcl/range_image/range_image.h>

int main (int argc, char** argv) {
  pcl::PointCloud<pcl::PointXYZ> pointCloud;
  
  // Generate the data
  for (float y=-0.5f; y<=0.5f; y+=0.01f) {
    for (float z=-0.5f; z<=0.5f; z+=0.01f) {
      pcl::PointXYZ point;
      point.x = 2.0f - y;
      point.y = y;
      point.z = z;
      pointCloud.points.push_back(point);
    }
  }
  pointCloud.width = (uint32_t) pointCloud.points.size();
  pointCloud.height = 1;

上面包含了点云的头文件,并生成了一个矩形的点云数据

  float angularResolution = (float) (  1.0f * (M_PI/180.0f));  //   1.0 degree in radians
  float maxAngleWidth     = (float) (360.0f * (M_PI/180.0f));  // 360.0 degree in radians
  float maxAngleHeight    = (float) (180.0f * (M_PI/180.0f));  // 180.0 degree in radians
  Eigen::Affine3f sensorPose = (Eigen::Affine3f)Eigen::Translation3f(0.0f, 0.0f, 0.0f);
  pcl::RangeImage::CoordinateFrame coordinate_frame = pcl::RangeImage::CAMERA_FRAME;
  float noiseLevel=0.00;
  float minRange = 0.0f;
  int borderSize = 1;

上面那个部分定义了我们想去创建的深度图的参数。

角度分辨率是1度,意味着光线将以一度来区别近邻的像素点。maxAngleWidth=360和maxAngleHeight=190意味着我们模拟的深度图传感器有一个360度环绕的效果。你可以总是使用这些设置,因为深度图将被裁剪成自动观察的区域。你可以节省计算通过减少值。对于一个180度的激光雷达,后面的点将看不见,msxAngleWidth=180就够了。

sensorPose定义了6DOF视觉传感器的位置,以roll=pitch=yaw=0这个位置为原点的。

coordinate_frame=CAMERA_FRAME告诉我们x是朝右的,y是朝下的,z是朝前的。一个可选的参数是LASER_FRAME,x是朝前的,y是朝左的,z是朝下的。

对于noiseLevel=0来说,深度图通过一个normal z-buffer来创建的。

如果minRange比0要大,那么靠得很近的点就会被忽略。

borderSize比0大的话,将会在裁剪的时候留下一边框的未观察到的点。

 pcl::RangeImage rangeImage;
  rangeImage.createFromPointCloud(pointCloud, angularResolution, maxAngleWidth, maxAngleHeight,
                                  sensorPose, coordinate_frame, noiseLevel, minRange, borderSize);
  
  std::cout << rangeImage << "\n";

上面的这个代码从点云里面创建了深度图。

深度图是继承PointCloud这个类,这个点有x,y,z和深度。这里有3种点。有效的点的深度都是大于0的,无法观察到的点如x=y=z=NAN和深度=-INFINITY。很远的点x=y=z=NAN深度=INFINITY

运行结果

range image of size 42x36 with angular resolution 1deg/pixel and 1512 points

 

 

 

 

 

 

你可能感兴趣的:(转换,PCL,点云,深度图)