PCL深度图像(1)

简介: 目前深度图像的获取方法有激光雷达深度成像法,计算机立体视觉成像,坐标测量机法,莫尔条纹法,结构光法等等,针对深度图像的研究重点主要集中在以下几个方面,深度图像的分割技术 ,深度图像的边缘检测技术 ,基于不同视点的多幅深度图像的配准技术,基于深度数据的三维重建技术,基于三维深度图像的三维目标识别技术,深度图像的多分辨率建模和几何压缩技术等等,在PCL 中深度图像与点云最主要的区别在于  其近邻的检索方式的不同,并且可以互相转换。

目前深度图像的获取方法有激光雷达深度成像法,计算机立体视觉成像,坐标测量机法,莫尔条纹法,结构光法等等,针对深度图像的研究重点主要集中在以下几个方面,深度图像的分割技术 ,深度图像的边缘检测技术 ,基于不同视点的多幅深度图像的配准技术,基于深度数据的三维重建技术,基于三维深度图像的三维目标识别技术,深度图像的多分辨率建模和几何压缩技术等等,在PCL 中深度图像与点云最主要的区别在于  其近邻的检索方式的不同,并且可以互相转换。

(这一章是我认为非常重要的)

模块RangeImage相关概念以及算法的介绍

深度图像(Depth Images)也被称为距离影像(Range Image),是指将从图像采集器到场景中各点的距离值作为像素值的图像,它直接反应了景物可见表面的几何形状,利用它可以很方便的解决3D目标描述中的许多问题,深度图像经过点云变换可以计算为点云数据,有规则及有必要信息的点云数据可以反算为深度图像数据

不同视角获得深度图像的过程:

                                 

   (1)PCL中的模块RangeImage相关类的介绍

 pcl_range_image库中包含两个表达深度图像和对深度图像进行操作的类,其依赖于pcl::common模块,深度图像(距离图像)的像素值代表从传感器到物体的距离以及深度,  深度图像是物体的三维表示形式,一般通过立体照相机或者ToF照相机获取,如果具备照相机的内标定参数,就可以将深度图像转换为点云

1.class pcl::RangeImage

    RangeImage类继承于PointCloud,主要功能是实现一个特定视点得到一个三维场景的深度图像。其继承关系如下:

                                       

类RangeImage的成员有:

Public Member Functions

template<typename PointCloudType >
void  createFromPointCloud (const PointCloudType &point_cloud, float angular_resolution=pcl::deg2rad(0.5f), float max_angle_width=pcl::deg2rad(360.0f), float max_angle_height=pcl::deg2rad(180.0f), const Eigen::Affine3f &sensor_pose=Eigen::Affine3f::Identity(), CoordinateFrame coordinate_frame=CAMERA_FRAME, float noise_level=0.0f, float min_range=0.0f, int border_size=0)
  从点云创建深度图像,point_cloud为指向创建深度图像所需要的点云的引用angular_resolution为模拟的深度传感器的角度分辨率,即深度图像中一个像素对应的角度大小,max_angle_width为模拟的深度传感器的水平最大采样角度,max_angle_height为模拟传感器的垂直方向最大采样角度,sensor_pose设置模拟的深度传感器的位姿是一个仿射变换矩阵,默认为4*4的单位矩阵变换,coordinate_frame定义按照那种坐标系统的习惯默认为CAMERA_FRAMEnoise_level获取深度图像深度时,近邻点对查询点距离值的影响水平,min_range设置最小的获取距离,小于最小获取距离的位置为传感器的盲区,border_size获得深度图像的边缘的宽度 默认为0 该函数中涉及的角度的单位都是弧度
template<typename PointCloudType >
void  createFromPointCloudWithKnownSize (const PointCloudType &point_cloud, float angular_resolution, const Eigen::Vector3f &point_cloud_center, float point_cloud_radius, const Eigen::Affine3f &sensor_pose=Eigen::Affine3f::Identity(), CoordinateFrame coordinate_frame=CAMERA_FRAME, float noise_level=0.0f, float min_range=0.0f, int border_size=0)
 

从点云创建深度图像,其中参数中有关场景大小的提示,提高了获取深度图像时的计算速度point_cloud为指向创建深度图像所需要的点云的引用,angular_resolution为模拟的深度传感器的角度分辨率,弧度表示,point_cloud_center为点云外接球体的中心,默认为(0,0,0)point_cloud_radius为点云外接球体的半径sensor_pose设置模拟的深度传感器的位姿是一个仿射变换矩阵,默认为4*4的单位矩阵变换,coordinate_frame定义按照那种坐标系统的习惯默认为CAMERA_FRAME,noise_level获取深度图像深度时,近邻点对查询点距离值的影响距离,以米为单位,min_range设置最小的获取距离,小于最小获取距离的位置为传感器的盲区,border_size获得深度图像的边缘的宽度 默认为0 该函数中涉及的角度的单位都是弧度

template<typename PointCloudTypeWithViewpoints >
void  createFromPointCloudWithViewpoints (const PointCloudTypeWithViewpoints &point_cloud, float angular_resolution, float max_angle_width, float max_angle_height, CoordinateFrame coordinate_frame=CAMERA_FRAME, float noise_level=0.0f, float min_range=0.0f, int border_size=0)
  从点云创建深度图像,点云中包含深度信息,其中,point_cloud为指向创建深度图像所需要的点云的引用,angular_resolution为模拟的深度传感器的角度分辨率,即深度图像中一个像素对应的角度大小,max_angle_width为模拟的深度传感器的水平最大采样角度,max_angle_height为模拟传感器的垂直方向最大采样角度,sensor_pose设置模拟的深度传感器的位姿是一个仿射变换矩阵,默认为4*4的单位矩阵变换,coordinate_frame定义按照那种坐标系统的习惯默认为CAMERA_FRAME,noise_level获取深度图像深度时,近邻点对查询点距离值的影响水平,如果该值比较小,则常用Z-缓冲区中深度平均值作为查询点的深度,min_range设置最小的可视深度,小于最小获取距离的位置为传感器的盲区,border_size获得深度图像的边缘的宽度 默认为0 该函数中涉及的角度的单位都是弧度
void  createEmpty (float angular_resolution, const Eigen::Affine3f &sensor_pose=Eigen::Affine3f::Identity(), RangeImage::CoordinateFrame coordinate_frame=CAMERA_FRAME, float angle_width=pcl::deg2rad(360.0f), float angle_height=pcl::deg2rad(180.0f))
  创建一个空的深度图像,以当前视点不可见点填充,其中,angle_width为模拟的深度传感器的水平采样角度,默认为PI*2(360);angle_height垂直方向的采样角度默认为PI(180)*****其他参数同上
template<typename PointCloudType >
void  integrateFarRanges (const PointCloudType &far_ranges)
  将已有的远距离测量结果融合到深度图像中,
PCL_EXPORTS void  cropImage (int border_size=0, int top=-1, int right=-1, int bottom=-1, int left=-1)
  裁剪深度图像到最小尺寸,使这个最小尺寸包含所有点云,其中,board_size设置裁剪后深度图像的边界尺寸, top为裁剪框的边界***********默认都为-1
void  setTransformationToRangeImageSystem (const Eigen::Affine3f &to_range_image_system)
  设置从深度图像坐标系(传感器的坐标系)转换到世界坐标系的变换矩阵
float  getAngularResolution () const
  获得深度图像X和Y方向的角分辨率  弧度表示
void  setAngularResolution (float angular_resolution)
  设置深度图像在X方向和Y方向的新的角分辨率,angular_resolution即每个像素所对应的弧度
void  calculate3DPoint (float image_x, float image_y, float range, PointWithRange &point) const
  根据深度图像点(X Y)和距离(range)计算返回场景中的3D点的point
void  calculate3DPoint (float image_x, float image_y, PointWithRange &point) const
  根据给定的深度图像点和离该点最近像素上的距离值计算返回场景中的3D 点point

(详细的解释请官网查看)       

  (2)class pcl::RangeImagePlanner             

RangeImagePlanner 来源于最原始的深度图像,但又区别于原始的深度图像,因为该类不使用球类投影方式,而是通过一个平面投影方式进行投影(相机一一般采用这种投影方式),因此对于已有的利用深度传感器获取的深度图像来说比较实用,类的继承关系如下:

                                                        

Public Member Functions

PCL_EXPORTS void  setDisparityImage (const float *disparity_image, int di_width, int di_height, float focal_length, float base_line, float desired_angular_resolution=-1)
  从给定的视差图像中创建图像,其中disparity_image是输入的视差图像,di_width视差图像的宽度di_height视差图像的高度focal_length, 产生视差图像的照相机的焦距,base_line是用于产生视差图像的立体相对的基线长度,desired_angular_resolution预设的角分辨率 每个像素对应的弧度,该值不能大于点云的密度,
PCL_EXPORTS void  setDepthImage (const float *depth_image, int di_width, int di_height, float di_center_x, float di_center_y, float di_focal_length_x, float di_focal_length_y, float desired_angular_resolution=-1)
  从已存在的深度影像中创建深度图像,其中,depth_image是输入的浮点形的深度图像,di_width,深度图像的宽度,di_height图像的高度,di_center_x  di_center_y 是照相机投影中心XY的坐标。di_focal_length_x  di_focal_length_y是照相机水平  垂直方向上的焦距,desired_angular_resolution预设的角分辨率 每个像素对应的弧度,该值不能大于点云的密度,
template<typename PointCloudType >
void  createFromPointCloudWithFixedSize (const PointCloudType &point_cloud, int di_width, int di_height, float di_center_x, float di_center_y, float di_focal_length_x, float di_focal_length_y, const Eigen::Affine3f &sensor_pose, CoordinateFrame coordinate_frame=CAMERA_FRAME, float noise_level=0.0f, float min_range=0.0f)
  从已存在的点云中创建图像,point_cloud为指向创建深度图像所需要的点云对象的引用,di_width视差图像的宽度di_height视差图像的高度 di_center_x  di_center_y 是照相机投影中心XY的坐标  di_focal_length_x  di_focal_length_y是照相机水平  垂直方向上的焦距    sensor_pose是模拟深度照相机的位姿  coordinate_frame为点云所使用的坐标系  noise_level传感器的水平噪声,
virtual void  calculate3DPoint (float image_x, float image_y, float range, Eigen::Vector3f &point) const
  根据给定图像点和深度图创建3D点,其中image_x  iamge_y range  分别为XY 坐标和深度,point为生成的3D点
virtual void  getImagePoint (const Eigen::Vector3f &point, float &image_x, float &image_y, float &range) const
  从给定的3D点point中计算图像点(X Y)和深度值

    等等具体看官网

(3)应用实例

 如何从点云创建深度图,如何从点云和给定的传感器的位置来创建深度图像,此程序是生成一个矩形的点云,然后基于该点云创建深度图像

新建文件range_image_creation.cpp:

#include <pcl/range_image/range_image.h>    //深度图像的头文件

int main (int argc, char** argv) {
  pcl::PointCloud<pcl::PointXYZ> pointCloud;   //定义点云的对象
  
  // 循环产生点云的数据
  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
   //angular_resolution为模拟的深度传感器的角度分辨率,即深度图像中一个像素对应的角度大小
  float angularResolution = (float) (  1.0f * (M_PI/180.0f));  //   1.0 degree in radians
   //max_angle_width为模拟的深度传感器的水平最大采样角度,
  float maxAngleWidth     = (float) (360.0f * (M_PI/180.0f));  // 360.0 degree in radians
  //max_angle_height为模拟传感器的垂直方向最大采样角度  都转为弧度
  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;    //noise_level获取深度图像深度时,近邻点对查询点距离值的影响水平
  float minRange = 0.0f;     //min_range设置最小的获取距离,小于最小获取距离的位置为传感器的盲区
  int borderSize = 1;        //border_size获得深度图像的边缘的宽度
  
  pcl::RangeImage rangeImage;
  rangeImage.createFromPointCloud(pointCloud, angularResolution, maxAngleWidth, maxAngleHeight,
                                  sensorPose, coordinate_frame, noiseLevel, minRange, borderSize);
  
  std::cout << rangeImage << "\n";
}

 

显示结果

微信公众号号可扫描二维码一起共同学习交流

 未完待续******************************88888

相关文章
|
7月前
|
C++ Python
C++ PCL三维点云物体目标识别
C++ PCL三维点云物体目标识别
404 1
C++ PCL三维点云物体目标识别
|
传感器 编解码 索引
|
存储 算法
|
数据可视化 算法
|
数据挖掘 Windows
PCL超体聚类
超体聚类是一种图像的分割方法。 超体(supervoxel)是一种集合,集合的元素是“体”。与体素滤波器中的体类似,其本质是一个个的小方块。与大部分的分割手段不同,超体聚 类的目的并不是分割出某种特定物体,超体是对点云实施过分割(over segmentation),将场景点云化成很多小块,并研究每个小块之间的关系。
1644 0
|
编解码 数据可视化 数据挖掘
PCL特征点与配准(1)
关于输入一个具体的物体的点云,从场景中找出与该物体点云相匹配的,这种方法可以用来抓取指定的物体等等,具体的代码的解释如下,需要用到的一些基础的知识,在之前的博客中都有提及,其中用到的一些方法可以翻阅前面的博客,当然有问题可以关注公众号,与众多爱好者一起交流 具体的代码实现 #include #include //点云类型头文件 #include //对应表示两个实体之间的匹配(例如,点,描述符等)。
2407 0
|
存储 算法 数据可视化
PCL点云配准(1)
在逆向工程,计算机视觉,文物数字化等领域中,由于点云的不完整,旋转错位,平移错位等,使得要得到的完整的点云就需要对局部点云进行配准,为了得到被测物体的完整数据模型,需要确定一个合适的坐标系,将从各个视角得到的点集合并到统一的坐标系下形成一个完整的点云,然后就可以方便进行可视化的操作,这就是点云数据的配准。
2051 0
|
数据可视化 算法
PCL点云配准(2)
(1)正态分布变换进行配准(normal Distributions Transform) 介绍关于如何使用正态分布算法来确定两个大型点云之间的刚体变换,正态分布变换算法是一个配准算法,它应用于三维点的统计模型,使用标准最优化技术来确定两个点云间的最优匹配,因为其在配准的过程中不利用对应点的特征计算和匹配,所以时间比其他方法比较快, 对于代码的解析 /* 使用正态分布变换进行配准的实验 。
2223 0
|
机器学习/深度学习 数据可视化 算法
PCL行人检测
首先我们知道Hog特征结合SVM分类器已经被广泛应用于图像识别中,尤其在行人检测中获得了极大的成功,HOG+SVM进行行人检测的方法是法国研究人员Dalal在2005的CVPR上提出的,而如今虽然有很多行人检测算法不断提出,但基本都是以HOG+SVM的思路为主,那么PCL中也是利用这一思想来进行行人的检测, 总体思路: 1、提取正负样本hog特征 2、投入svm分类器训练,得到model 3、由model生成检测子 4、利用检测子检测负样本,得到hardexample 5、提取hardexample的hog特征并结合第一步中的特征一起投入训练,得到最终检测子。
1548 0
PCL点云分割(2)
关于点云的分割算是我想做的机械臂抓取中十分重要的俄一部分,所以首先学习如果使用点云库处理我用kinect获取的点云的数据,本例程也是我自己慢慢修改程序并结合官方API 的解说实现的,其中有很多细节如果直接更改源程序,可能会因为数据类型,或者头文件等各种原因编译不过,会导致我们比较难得找出其中的错误,...
1825 0