前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >PCL深度图像(3)

PCL深度图像(3)

作者头像
点云PCL博主
发布2019-07-31 10:26:28
7030
发布2019-07-31 10:26:28
举报
文章被收录于专栏:点云PCL点云PCL

(2)如何从深度图像中提取边界

从深度图像中提取边界(从前景跨越到背景的位置定义为边界),对于物体边界:这是物体的最外层和阴影边界的可见点集,阴影边界:毗邻与遮挡的背景上的点集,Veil点集,在被遮挡物边界和阴影边界之间的内插点,它们是有激光雷达获取的3D距离数据中的典型数据类型,这三类数据及深度图像的边界如图:

代码解析:从磁盘中读取点云,创建深度图像并使其可视化,提取边界信息很重要的一点就是区分深度图像中当前视点不可见点几何和应该可见但处于传感器获取距离范围之外的点集 ,后者可以标记为典型边界,然而当前视点不可见点则不能成为边界,因此,如果后者的测量值存在,则提供那些超出传感器距离获取范围之外的数据对于边界的提取是非常重要的,

新建文件range_image_border_extraction.cpp:

代码语言:javascript
复制
#include <iostream>
#include <boost/thread/thread.hpp>
#include <pcl/range_image/range_image.h>
#include <pcl/io/pcd_io.h>
#include <pcl/visualization/range_image_visualizer.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/features/range_image_border_extractor.h>
#include <pcl/console/parse.h>typedef pcl::PointXYZ PointType;

float angular_resolution = 0.5f;
pcl::RangeImage::CoordinateFrame coordinate_frame = pcl::RangeImage::CAMERA_FRAME;bool setUnseenToMaxRange = false;

void printUsage (const char* progName)
{
 std::cout << "\n\nUsage: "<<progName<<" [options] <scene.pcd>\n\n"
           << "Options:\n"
           << "-------------------------------------------\n"
           << "-r <float>   angular resolution in degrees (default "<<angular_resolution<<")\n"
           << "-c <int>     coordinate frame (default "<< (int)coordinate_frame<<")\n"
           << "-m           Treat all unseen points to max range\n"
           << "-h           this help\n"
           << "\n\n";
}

int main (int argc, char** argv)
{
 if (pcl::console::find_argument (argc, argv, "-h") >= 0)
 {
   printUsage (argv[0]);    return 0;
 }  if (pcl::console::find_argument (argc, argv, "-m") >= 0)
 {
   setUnseenToMaxRange = true;
   cout << "Setting unseen values in range image to maximum range readings.\n";
 }  int tmp_coordinate_frame;  if (pcl::console::parse (argc, argv, "-c", tmp_coordinate_frame) >= 0)
 {
   coordinate_frame = pcl::RangeImage::CoordinateFrame (tmp_coordinate_frame);
   cout << "Using coordinate frame "<< (int)coordinate_frame<<".\n";
 }  if (pcl::console::parse (argc, argv, "-r", angular_resolution) >= 0)
   cout << "Setting angular resolution to "<<angular_resolution<<"deg.\n";
 angular_resolution = pcl::deg2rad (angular_resolution);  
 // Read pcd file or create example point cloud if not given-----  //
 pcl::PointCloud<PointType>::Ptr point_cloud_ptr (new pcl::PointCloud<PointType>);
 pcl::PointCloud<PointType>& point_cloud = *point_cloud_ptr;
 pcl::PointCloud<pcl::PointWithViewpoint> far_ranges;
 Eigen::Affine3f scene_sensor_pose (Eigen::Affine3f::Identity ());  //传感器的位置
 std::vector<int> pcd_filename_indices = pcl::console::parse_file_extension_argument (argc, argv, "pcd");  if (!pcd_filename_indices.empty ())
 {
   std::string filename = argv[pcd_filename_indices[0]];    if (pcl::io::loadPCDFile (filename, point_cloud) == -1)   //打开文件    {
     cout << "Was not able to open file \""<<filename<<"\".\n";
     printUsage (argv[0]);      return 0;
   }
   scene_sensor_pose = Eigen::Affine3f (Eigen::Translation3f (point_cloud.sensor_origin_[0],point_cloud.sensor_origin_[1],point_cloud.sensor_origin_[2])) *Eigen::Affine3f (point_cloud.sensor_orientation_);  //仿射变换矩阵  
   std::string far_ranges_filename = pcl::getFilenameWithoutExtension (filename)+"_far_ranges.pcd";    if (pcl::io::loadPCDFile(far_ranges_filename.c_str(), far_ranges) == -1)
     std::cout << "Far ranges file \""<<far_ranges_filename<<"\" does not exists.\n";
 } 
 else
 {
   cout << "\nNo *.pcd file given => Genarating example point cloud.\n\n";    for (float x=-0.5f; x<=0.5f; x+=0.01f)      //填充一个矩形的点云    
    {  for (float y=-0.5f; y<=0.5f; y+=0.01f)
     {
       PointType point;  point.x = x;  point.y = y;  point.z = 2.0f - y;
       point_cloud.points.push_back (point);  
     }
   }
   point_cloud.width = (int) point_cloud.points.size ();  point_cloud.height = 1;
 }  
  // -----Create RangeImage from the PointCloud-----  // 
 float noise_level = 0.0;      //各种参数的设置
 float min_range = 0.0f;  int border_size = 1;
 boost::shared_ptr<pcl::RangeImage> range_image_ptr (new pcl::RangeImage);
 pcl::RangeImage& range_image = *range_image_ptr;  
 range_image.createFromPointCloud (point_cloud, angular_resolution, pcl::deg2rad (360.0f), pcl::deg2rad (180.0f),
                                  scene_sensor_pose, coordinate_frame, noise_level, min_range, border_size);
 range_image.integrateFarRanges (far_ranges);  if (setUnseenToMaxRange)
   range_image.setUnseenToMaxRange ();  
     // -----Open 3D viewer and add point cloud-----  //
 pcl::visualization::PCLVisualizer viewer ("3D Viewer");   //创建视口
 viewer.setBackgroundColor (1, 1, 1);                      //设置背景颜色
 viewer.addCoordinateSystem (1.0f);              //设置坐标系
 pcl::visualization::PointCloudColorHandlerCustom<PointType> point_cloud_color_handler (point_cloud_ptr, 0, 0, 0);
 viewer.addPointCloud (point_cloud_ptr, point_cloud_color_handler, "original point cloud");   //添加点云  
     // -----Extract borders提取边界的部分-----  // 
 pcl::RangeImageBorderExtractor border_extractor (&range_image);
 pcl::PointCloud<pcl::BorderDescription> border_descriptions;
 border_extractor.compute (border_descriptions);     //提取边界计算描述子  
 // -----Show points in 3D viewer在3D 视口中显示点云-----  //
 pcl::PointCloud<pcl::PointWithRange>::Ptr border_points_ptr(new pcl::PointCloud<pcl::PointWithRange>),  //物体边界
 veil_points_ptr(new pcl::PointCloud<pcl::PointWithRange>),     //veil边界
shadow_points_ptr(new pcl::PointCloud<pcl::PointWithRange>);   //阴影边界
 pcl::PointCloud<pcl::PointWithRange>& border_points = *border_points_ptr, & veil_points = * veil_points_ptr,& shadow_points = *shadow_points_ptr;
      for (int y=0; y< (int)range_image.height; ++y)
 {    for (int x=0; x< (int)range_image.width; ++x)
   {      if (border_descriptions.points[y*range_image.width + x].traits[pcl::BORDER_TRAIT__OBSTACLE_BORDER])
       border_points.points.push_back (range_image.points[y*range_image.width + x]);      if (border_descriptions.points[y*range_image.width + x].traits[pcl::BORDER_TRAIT__VEIL_POINT])
       veil_points.points.push_back (range_image.points[y*range_image.width + x]);      if (border_descriptions.points[y*range_image.width + x].traits[pcl::BORDER_TRAIT__SHADOW_BORDER])
       shadow_points.points.push_back (range_image.points[y*range_image.width + x]);
   }
 }
 pcl::visualization::PointCloudColorHandlerCustom<pcl::PointWithRange> border_points_color_handler (border_points_ptr, 0, 255, 0);
 viewer.addPointCloud<pcl::PointWithRange> (border_points_ptr, border_points_color_handler, "border points");
 viewer.setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 7, "border points"); pcl::visualization::PointCloudColorHandlerCustom<pcl::PointWithRange> veil_points_color_handler (veil_points_ptr, 255, 0, 0);
 viewer.addPointCloud<pcl::PointWithRange> (veil_points_ptr, veil_points_color_handler, "veil points");
 viewer.setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 7, "veil points");
 pcl::visualization::PointCloudColorHandlerCustom<pcl::PointWithRange> shadow_points_color_handler (shadow_points_ptr, 0, 255, 255);
 viewer.addPointCloud<pcl::PointWithRange> (shadow_points_ptr, shadow_points_color_handler, "shadow points");
 viewer.setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 7, "shadow points");    // -----Show points on range image-----  //
 pcl::visualization::RangeImageVisualizer* range_image_borders_widget = NULL;
 range_image_borders_widget =
   pcl::visualization::RangeImageVisualizer::getRangeImageBordersWidget (range_image, -std::numeric_limits<float>::infinity (), std::numeric_limits<float>::infinity (), false,                                                                         border_descriptions, "Range image with borders");
 while (!viewer.wasStopped ())
 {
   range_image_borders_widget->spinOnce ();
   viewer.spinOnce ();
   pcl_sleep(0.01);
 }
}

编译的运行的结果./range_image_border_extraction -m

这将一个自定生成的,矩形状浮点型点云,有显示结果可以看出检测出的边界用绿色较大的点表示,其他的点用默认的普通的大小点来表示.

未完待续*****************8888888

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-05-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 点云PCL 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档