PCL系列——如何可视化深度图像

2023-05-16

博客新址: http://blog.xuezhisd.top
邮箱:xuezhisd@126.com


PCL系列

  • PCL系列——读入PCD格式文件操作
  • PCL系列——将点云数据写入PCD格式文件
  • PCL系列——拼接两个点云
  • PCL系列——从深度图像(RangeImage)中提取NARF关键点
  • PCL系列——如何可视化深度图像
  • PCL系列——如何使用迭代最近点法(ICP)配准
  • PCL系列——如何逐渐地配准一对点云
  • PCL系列——三维重构之泊松重构
  • PCL系列——三维重构之贪婪三角投影算法
  • PCL系列——三维重构之移动立方体算法

说明

通过本教程,我们将会学会:

  • 如何通过两种方式可视化深度图像。
  • 一种方式是在3D viewer中以点云的方式显示。(深度图来源于点云图)
  • 一种方式是作为一幅图像显示(以不同的颜色表示不同的深度值)

操作

  • 在VS2010 中新建一个文件 range_image_visualization.cpp,然后将下面的代码复制到文件中。
  • 参照之前的文章,配置项目的属性。设置包含目录和库目录和附加依赖项。
#include <iostream> //标准输入/输出
#include <boost/thread/thread.hpp> //多线程
#include <pcl/common/common_headers.h>
#include <pcl/range_image/range_image.h> //深度图有关头文件
#include <pcl/io/pcd_io.h> //pcd文件输入/输出
#include <pcl/visualization/range_image_visualizer.h> //深度图可视化
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/console/parse.h> //命令行参数解析

typedef pcl::PointXYZ PointType;


//参数 全局
float angular_resolution_x = 0.5f, //角分辨率(单位弧度)
      angular_resolution_y = angular_resolution_x;
pcl::RangeImage::CoordinateFrame coordinate_frame = pcl::RangeImage::CAMERA_FRAME; //坐标帧(相机帧)
bool live_update = true; //是否根据选择的视角更新深度图像

// 打印帮助信息
void printUsage (const char* progName)
{
  std::cout << "\n\nUsage: "<<progName<<" [options] <scene.pcd>\n\n"
            << "Options:\n"
            << "-------------------------------------------\n"
            << "-rx <float>  angular resolution in degrees (default "<<angular_resolution_x<<")\n"
            << "-ry <float>  angular resolution in degrees (default "<<angular_resolution_y<<")\n"
            << "-c <int>     coordinate frame (default "<< (int)coordinate_frame<<")\n"
            << "-l           live update - update the range image according to the selected view in the 3D viewer.\n"
            << "-h           this help\n"
            << "\n\n";
}

/*
void setViewerPose (pcl::visualization::PCLVisualizer& viewer, const Eigen::Affine3f& viewer_pose)
{
  Eigen::Vector3f pos_vector = viewer_pose * Eigen::Vector3f(0, 0, 0);
  Eigen::Vector3f look_at_vector = viewer_pose.rotation () * Eigen::Vector3f(0, 0, 1) + pos_vector;
  Eigen::Vector3f up_vector = viewer_pose.rotation () * Eigen::Vector3f(0, -1, 0);
  viewer.setCameraPosition (pos_vector[0], pos_vector[1], pos_vector[2],
                            look_at_vector[0], look_at_vector[1], look_at_vector[2],
                            up_vector[0], up_vector[1], up_vector[2]);
}
*/


// 主函数
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, "-l") >= 0)
  {
    live_update = true;
    std::cout << "Live update is on.\n";
  }
  if (pcl::console::parse (argc, argv, "-rx", angular_resolution_x) >= 0)
    std::cout << "Setting angular resolution in x-direction to "<<angular_resolution_x<<"deg.\n";
  if (pcl::console::parse (argc, argv, "-ry", angular_resolution_y) >= 0)
    std::cout << "Setting angular resolution in y-direction to "<<angular_resolution_y<<"deg.\n";
  int tmp_coordinate_frame;
  if (pcl::console::parse (argc, argv, "-c", tmp_coordinate_frame) >= 0)
  {
    coordinate_frame = pcl::RangeImage::CoordinateFrame (tmp_coordinate_frame);
    std::cout << "Using coordinate frame "<< (int)coordinate_frame<<".\n";
  }
  angular_resolution_x = pcl::deg2rad (angular_resolution_x);
  angular_resolution_y = pcl::deg2rad (angular_resolution_y);
  
  //读取pcd文件。如果没有指定文件,则创建样本云点
  pcl::PointCloud<PointType>::Ptr point_cloud_ptr (new pcl::PointCloud<PointType>);
  pcl::PointCloud<PointType>& point_cloud = *point_cloud_ptr;
  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)
    {
      std::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_);
  }
  else
  {
    std::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;
  }
  
  //从点云创建出深度图
  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_x, angular_resolution_y,
                                    pcl::deg2rad (360.0f), pcl::deg2rad (180.0f),
                                    scene_sensor_pose, coordinate_frame, noise_level, min_range, border_size); //从点云创建出深度图
  
  //打开一个3D图形窗口,并添加点云数据
  pcl::visualization::PCLVisualizer viewer ("3D Viewer");
  viewer.setBackgroundColor (1, 1, 1); //背景
  pcl::visualization::PointCloudColorHandlerCustom<pcl::PointWithRange> range_image_color_handler (range_image_ptr, 0, 0, 0);
  viewer.addPointCloud (range_image_ptr, range_image_color_handler, "range image");
  viewer.setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "range image");
  //viewer.addCoordinateSystem (1.0f, "global");
  //PointCloudColorHandlerCustom<PointType> point_cloud_color_handler (point_cloud_ptr, 150, 150, 150);
  //viewer.addPointCloud (point_cloud_ptr, point_cloud_color_handler, "original point cloud");
  viewer.initCameraParameters ();
  //setViewerPose(viewer, range_image.getTransformationToWorldSystem ()); //PCL 1.6 出错
  
  //以图像的形式显示深度图像,深度值作为颜色显示
  pcl::visualization::RangeImageVisualizer range_image_widget ("Range image");
  range_image_widget.showRangeImage (range_image);
  

  //主循环
  while (!viewer.wasStopped ())
  {
    range_image_widget.spinOnce ();
    viewer.spinOnce ();
    pcl_sleep (0.01);
    
    if (live_update) //根据3D显示,实时更新2D图像
    {
      scene_sensor_pose = viewer.getViewerPose(); //获取观测姿势
      range_image.createFromPointCloud (point_cloud, angular_resolution_x, angular_resolution_y,
                                        pcl::deg2rad (360.0f), pcl::deg2rad (180.0f),
                                        scene_sensor_pose, pcl::RangeImage::LASER_FRAME, noise_level, min_range, border_size); //重新生成新的深度图
      range_image_widget.showRangeImage (range_image); //重新显示
    }
  }
}
  • 重新生成项目。
  • 到改项目的Debug目录下,按住Shift,同时点击鼠标右键,在当前窗口打开CMD窗口。
  • 在命令行中输入range_image_visualization.exe,执行程序。结果如下图所示。
    • 图1是命令行的显示,因为没有指定pcd文件,程序生成了点云数据。
      图2是2D显示方式。
      图3是3D显示方式。
      2D显示方式会随3D显示的变化而自动变化。

图1
图2
图3

参考

  • How to visualize a range image
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

PCL系列——如何可视化深度图像 的相关文章

  • Opencv 3.4 中P3P位姿估计算法解析

    先上图 xff0c Opencv3 4中用两种算法实现P3P位姿估计问题 一种是基于距离P3P算法问题 xff08 算法1 xff1a P3P xff09 xff0c 一种是基于矩阵P3P算法问题 xff08 算法2 xff1a aP3P
  • 套接字

    套接字 socket 套接字 socket 是一个抽象层 应用程序可以通过它发送或接收数据 可对其进行像对文件一样的打开 读写和关闭等操作 套接字允许应用程序将I O插入到网络中 并与网络中的其他应用程序进行通信 网络套接字是IP地址与端口
  • 单片机_PWM输出原理详解

    单片机 PWM输出原理详解 理论篇 博主自己的经历告诉我 xff0c PWM波的理解和应用确实还是挺重要的 xff0c 这里专门花一期详细介绍一下 什么是PWM xff1f PWM xff0c 英文名Pulse Width Modulati
  • 命令远程执行小结

    远程执行命令 xff08 command remote execution xff09 主要可以使用如下几个命令 1 rexec 2 rsh amp rlogin 3 ssh 1 rexec 顾名思义 xff0c 就是remote exec
  • 去除多余的Merge branch提交

    去除多余的Merge branch提交 在项目开发中 xff0c 经常会有这样的情况发生 xff0c 开发完了一个新功能 xff0c 提交到远程仓库时 xff0c 发现提交失败 xff08 其他同事已对其做了更改 xff09 xff0c 先
  • 5 Ways To Fix Slow 802.11n Speed

    http www cnblogs com jjkv3 archive 2012 04 22 2464919 html o you went and bought a shiny new 802 11n router and were all
  • Linux下UTF-8字符编码问题

    这中间选自论坛我份发的帖子 地址是 xff1a http topic csdn net u 20101110 17 cab8cfc9 9ac6 47ce 98b4 e503e75e3e48 html seed 61 1835214465 a
  • Linux IPC总结(全)

    IPC进程间通信 Inter Process Communication 就是指多个进程之间相互通信 xff0c 交换信息的方法 Linux IPC基本上都是从Unix平台上继承而来的 主要包括最初的Unix IPC xff0c Syste
  • Zebra-VTYSH源码分析和改造(序)

    最近公司一网络产品需要在WEB和SNMP的基础上添加CLI接口 本身CLI xff08 Command Line Interface xff09 在产品中借助某芯片有简单ssdk sh xff0c 由于客户要求CLI要想Cisco那样 xf
  • Zebra-VTYSH源码分析和改造(一):Zebra软件架构

    1 Zebra 功能认识 ZEBRA 提供了一个类Cisco命令行的分级多用户命令解析引擎 VTY xff08 Virtual Terminal xff09 它是类似于Linux Shell的虚拟终端接口 xff0c 负责对访问的安全验证
  • 升级WEXT到NL80211/CFG80211

    内容包括 xff1a 1 分析两者的区别 2 分析两者的架构 xff0c 重点在后者 3 如何将在WE架构中用到的standard和private的command在新的架构中实现 请等待
  • 2011,我和CSDN亲密接触的一年

    从CSDN刚刚发出这次征文活动的时候 xff0c 就有一种想参加的冲动 xff0c 总想说些什么 xff0c 迟迟直到今天才开始下笔 和大家一样 xff0c 我也是一名普通的计算机研发人员 xff0c 说挨踢者也行 xff0c 说码农亦可
  • Zebra-VTYSH源码分析和改造(三):添加定制命令

    一 视图介绍 由上面几篇文章分析可见 xff0c 所有的命令都是包含在node中的 xff0c 根据Cisco或者H3常见路由器或者交换机的CLI格式可见 xff0c 一个node就对应着一个视图 xff08 View xff09 常用的视
  • Bringup wifi driver to android 6.0

    1 android root system core rootdir init rc mkdir data misc systemkeys 0700 system system mkdir data misc wifi 0770 wifi
  • global命令详解

    发信人 vale 浅谷 信区 VIM 标 题 global命令详解 发信站 水木社区 Fri Jun 15 17 05 55 2007 站内 global命令是Vim最强大的命令之一 xff08 个人认为是No 1 xff09 xff0c
  • [简单总结] WiFi中的RTS和CTS简单回顾

    通信协议中的RTS CTS协议 xff1a 即请求发送 允许发送协议 xff0c 相当于一种握手协议 xff0c 主要用来解决 34 隐藏终端 34 问题 34 隐藏终端 34 xff08 Hidden Stations xff09 是指
  • 蓝牙技术谈之跳频技术(一)

    跳频技术 Frequency Hopping Spread Spectrum xff1b FHSS 在同步 且同时的情况下 xff0c 接收两端以特定型式的窄频载波来传送讯号 xff0c 对于一个非特定的接收器 xff0c FHSS所产生的
  • Ubuntu自学笔记二

    磁盘管理 dev sd 文件 xff0c 此类文件是磁盘设备文件 xff0c 并不能直接访问磁盘 xff0c 必须要将磁盘挂载到某一个目录下才可以访问 dev sdb和 dev sdb1是U盘的设备文件 xff08 每个人的电脑U盘设备文件
  • 机器视觉设计,如何正确的选择相机和镜头?

    1 相机选择步骤 xff1a 目标物尺码 61 预估实际视场 0 75 根据精度算出分辨率 xff0c 预计出的实际视场 项目要求精度 61 相机的分辨率 根据相机分辨率大小 xff0c 选择合适的相机 xff0c 如果分别率一样的情况下
  • VCC、VDD、VSS以及VBAT的区别

    在STM32 的学习中 xff0c 发现有几种看起来相关的名称 xff0c 分别是VCC VDD VSS VBAT xff0c 在经过搜索查找之后 xff0c 总结如下 xff1a 1 VCC的C是Circuit的意思 xff0c 是指整个

随机推荐

  • vue中单个js写法

    1 vue export default 可以写很多东西 xff0c 包括变量和方法 xff0c 对象等 xff0c 只要是想作为开放的接口都可以写 xff0c 在 vue文件中一般写上data 以及method等 xff0c data指的
  • Ubuntu14.04安装Theano详细教程

    博客新址 http blog xuezhisd top 邮箱 xff1a xuezhisd 64 126 com 因为最近需要学习深度学习 xff0c 因此想要配置Theano xff0c 来开发深度学习算法 但是发现Theano安装总是出
  • Ubuntu-安装-cuda7.0-单显卡-超详细教程

    博客新址 http blog xuezhisd top 邮箱 xff1a xuezhisd 64 126 com 一 说明 本教程是在台式机上安装的 xff0c 只有一个NVIDIA显卡 操作系统是Ubuntu 14 04 64bit 双显
  • 使用Putty无法远程登录,显示服务器拒绝连接

    博客新址 http blog xuezhisd top 邮箱 xff1a xuezhisd 64 126 com putty连接不到linux的原因总结为以下几种情况 局域网内的两台电脑IP冲突 当使用DHCP自动分配IP时 xff0c 两
  • caffe安装系列——综述

    博客新址 http blog xuezhisd top 邮箱 xff1a xuezhisd 64 126 com 说明 网上关于caffe的安装教程非常多 xff0c 但是关于每一步是否操作成功 xff0c 出现了什么样的错误又该如何处理没
  • ls改头换面

    在linux中 xff0c ls命令可以使用颜色来区别不同的文件 路径 权限等等 但是有时候 xff0c ls的颜色配置不是非常合适 例如在黑色的背景下显示蓝色的文字 xff0c 看起来真是费劲啊 要修改颜色配置非常简单 xff0c 可以修
  • caffe安装系列——安装GCC4.7和G++4.7并降级

    博客新址 http blog xuezhisd top 邮箱 xff1a xuezhisd 64 126 com 说明 网上关于caffe的安装教程非常多 xff0c 但是关于每一步是否操作成功 xff0c 出现了什么样的错误又该如何处理没
  • caffe安装系列——安装NVIDIA显卡驱动

    博客新址 http blog xuezhisd top 邮箱 xff1a xuezhisd 64 126 com 说明 网上关于caffe的安装教程非常多 xff0c 但是关于每一步是否操作成功 xff0c 出现了什么样的错误又该如何处理没
  • caffe安装系列——安装cuda和cudnn

    博客新址 http blog xuezhisd top 邮箱 xff1a xuezhisd 64 126 com 说明 网上关于caffe的安装教程非常多 xff0c 但是关于每一步是否操作成功 xff0c 出现了什么样的错误又该如何处理没
  • caffe安装系列——安装Matlab

    博客新址 http blog xuezhisd top 邮箱 xff1a xuezhisd 64 126 com 说明 网上关于caffe的安装教程非常多 xff0c 但是关于每一步是否操作成功 xff0c 出现了什么样的错误又该如何处理没
  • caffe安装系列——安装OpenCV

    博客新址 http blog xuezhisd top 邮箱 xff1a xuezhisd 64 126 com 说明 网上关于caffe的安装教程非常多 xff0c 但是关于每一步是否操作成功 xff0c 出现了什么样的错误又该如何处理没
  • caffe安装系列——安装python依赖包

    博客新址 http blog xuezhisd top 邮箱 xff1a xuezhisd 64 126 com 说明 网上关于caffe的安装教程非常多 xff0c 但是关于每一步是否操作成功 xff0c 出现了什么样的错误又该如何处理没
  • caffe安装系列——安装caffe

    博客新址 http blog xuezhisd top 邮箱 xff1a xuezhisd 64 126 com 说明 网上关于caffe的安装教程非常多 xff0c 但是关于每一步是否操作成功 xff0c 出现了什么样的错误又该如何处理没
  • 服务器维护系列——VNC没有反应了怎么办?

    博客新址 http blog xuezhisd top 邮箱 xff1a xuezhisd 64 126 com 服务器维护系列 服务器维护系列 VNC没有反应了怎么办 xff1f 问题描述 服务器上存在多个用户 xff0c 大家通过VNC
  • PCL系列——读入PCD格式文件

    博客新址 http blog xuezhisd top 邮箱 xff1a xuezhisd 64 126 com PCL系列 PCL系列 读入PCD格式文件操作PCL系列 将点云数据写入PCD格式文件PCL系列 拼接两个点云PCL系列 从深
  • PCL系列——将点云数据写入PCD格式文件

    博客新址 http blog xuezhisd top 邮箱 xff1a xuezhisd 64 126 com PCL系列 PCL系列 读入PCD格式文件操作PCL系列 将点云数据写入PCD格式文件PCL系列 拼接两个点云PCL系列 从深
  • awk one lines

    From http www student northpark edu pemente awk awk1line txt HANDY ONE LINERS FOR AWK 22 July 2003 compiled by Eric Peme
  • PCL系列——拼接两个点云

    博客新址 http blog xuezhisd top 邮箱 xff1a xuezhisd 64 126 com PCL系列 PCL系列 读入PCD格式文件操作PCL系列 将点云数据写入PCD格式文件PCL系列 拼接两个点云PCL系列 从深
  • PCL系列——从深度图像(RangeImage)中提取NARF关键点

    博客新址 http blog xuezhisd top 邮箱 xff1a xuezhisd 64 126 com PCL系列 PCL系列 读入PCD格式文件操作PCL系列 将点云数据写入PCD格式文件PCL系列 拼接两个点云PCL系列 从深
  • PCL系列——如何可视化深度图像

    博客新址 http blog xuezhisd top 邮箱 xff1a xuezhisd 64 126 com PCL系列 PCL系列 读入PCD格式文件操作PCL系列 将点云数据写入PCD格式文件PCL系列 拼接两个点云PCL系列 从深