【PCL库+ubuntu+C++】 2.使用PCL实现对点云的变换

简介

本篇用一个4X4的矩阵,对点云数据进行平移和旋转变换,看到自动驾驶中对点云进行变换的时候用到的比较多

思路

  1. 引入库函数
#include  <pcl/common/transforms.h>

该头文件包含变换矩阵的API.
2. 程序的帮助文档,-h,–help都可以激活,写这个函数是一个优秀的习惯:

// This function displays the help
void showHelp(char * program_name)
{
  std::cout << std::endl;
  std::cout << "Usage: " << program_name << " cloud_filename.[pcd|ply]" << std::endl;
  std::cout << "-h:  Show this help." << std::endl;
}
...此处省略了很多代码...
// Show help
  if (pcl::console::find_switch (argc, argv, "-h") || pcl::console::find_switch (argc, argv, "--help")) {
    showHelp (argv[0]);
    return 0;
  }
  1. 从命令行接收参数(点云文件格式的)
// Fetch point cloud filename in arguments | Works with PCD and PLY files
  std::vector<int> filenames;
  bool file_is_pcd = false;

  filenames = pcl::console::parse_file_extension_argument (argc, argv, ".ply");

  if (filenames.size () != 1)  
  {
    filenames = pcl::console::parse_file_extension_argument (argc, argv, ".pcd");

    if (filenames.size () != 1) 
    {
      showHelp (argv[0]);
      return -1;
    } 
    else 
    {
      file_is_pcd = true;
    }
  }
  1. 初始化一个4X4的矩阵
/* Reminder: how transformation matrices work :

           |-------> This column is the translation
    | 1 0 0 x |  \
    | 0 1 0 y |   }-> The identity 3x3 matrix (no rotation) on the left
    | 0 0 1 z |  /
    | 0 0 0 1 |    -> We do not use this line (and it has to stay 0,0,0,1)

    METHOD #1: Using a Matrix4f
    This is the "manual" method, perfect to understand but error prone !
  */
  Eigen::Matrix4f transform_1 = Eigen::Matrix4f::Identity();
  /*
    |  1  0  0  0  |
i = |  0  1  0  0  |
    |  0  0  1  0  |
    |  0  0  0  1  |
*/
  1. 为旋转矩阵赋值,它的3阶是旋转矩阵需要的,值得一提的是,这里对旋转矩阵的构造不止一种,选取一种作为示例,其余请读者据官网自行探索.
// Define a rotation matrix (see https://en.wikipedia.org/wiki/Rotation_matrix)
  float theta = M_PI/4; // The angle of rotation in radians
  transform_1 (0,0) = std::cos (theta);
  transform_1 (0,1) = -sin(theta);
  transform_1 (1,0) = sin (theta);
  transform_1 (1,1) = std::cos (theta);
  //    (row, column)

  // Define a translation of 2.5 meters on the x axis.
  transform_1 (0,3) = 2.5;

  // Print the transformation
  printf ("Method #1: using a Matrix4f\n");
  std::cout << transform_1 << std::endl;
/*
    |  cos(θ) -sin(θ)  0.0 |
R = |  sin(θ)  cos(θ)  0.0 |
    |  0.0     0.0     1.0 |

t = < 2.5, 0.0, 0.0 >
*/
  1. 开始变换
// Executing the transformation
  pcl::PointCloud<pcl::PointXYZ>::Ptr transformed_cloud (new pcl::PointCloud<pcl::PointXYZ> ());
  // You can either apply transform_1 or transform_2; they are the same
  pcl::transformPointCloud (*source_cloud, *transformed_cloud, transform_1);

  1. 然后就可以通过可视化模块PCLVisualizer,可视出来
  2. 最后编译,查看,就可以了,下边是执行效果(记得要带参数即需要变换的点云格式图片执行哦),这里我的点云文件是cube.ply:
./matrix_transform cube.ply 

命令行输出
在这里插入图片描述
效果pcl输出
在这里插入图片描述

源码

CMakeLists.txt

cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
 
project(pcl-matrix_transform)

find_package(PCL 1.7 REQUIRED)

include_directories(${PCL_INCLUDE_DIRS})
link_directories(${PCL_LIBRARY_DIRS})
add_definitions(${PCL_DEFINITIONS})

add_executable (matrix_transform matrix_transform.cpp)
target_link_libraries (matrix_transform ${PCL_LIBRARIES})

matrix_transform.cpp

#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/io/ply_io.h>
#include <pcl/point_cloud.h>
#include <pcl/console/parse.h>
#include <pcl/common/transforms.h>
#include <pcl/visualization/pcl_visualizer.h>

// This function displays the help
void showHelp(char * program_name)
{
  std::cout << std::endl;
  std::cout << "Usage: " << program_name << " cloud_filename.[pcd|ply]" << std::endl;
  std::cout << "-h:  Show this help." << std::endl;
}
// This is the main function
int main (int argc, char** argv)
{

  // Show help
  if (pcl::console::find_switch (argc, argv, "-h") || pcl::console::find_switch (argc, argv, "--help")) 
  {
   showHelp (argv[0]);
    return 0;
  }

  // Fetch point cloud filename in arguments | Works with PCD and PLY files
   std::vector<int> filenames;
   bool file_is_pcd = false;
 
   filenames = pcl::console::parse_file_extension_argument (argc, argv, ".ply");
 
   if (filenames.size () != 1)  
   {
     filenames = pcl::console::parse_file_extension_argument (argc, argv, ".pcd");
 
     if (filenames.size () != 1) 
     {
       showHelp (argv[0]);
       return -1;
     } 
     else 
     {
       file_is_pcd = true;
     }
   }
 
   // Load file | Works with PCD and PLY files
   pcl::PointCloud<pcl::PointXYZ>::Ptr source_cloud (new pcl::PointCloud<pcl::PointXYZ> ());
 
   if (file_is_pcd) 
   {
     if (pcl::io::loadPCDFile (argv[filenames[0]], *source_cloud) < 0)  
     {
       std::cout << "Error loading point cloud " << argv[filenames[0]] << std::endl << std::endl;
       showHelp (argv[0]);
       return -1;
     }
   } 
   else 
   {
     if (pcl::io::loadPLYFile (argv[filenames[0]], *source_cloud) < 0) 
      {
       std::cout << "Error loading point cloud " << argv[filenames[0]] << std::endl << std::endl;
       showHelp (argv[0]);
       return -1;
     }
   }
 
   /* Reminder: how transformation matrices work :
 
            |-------> This column is the translation
     | 1 0 0 x |  \
     | 0 1 0 y |   }-> The identity 3x3 matrix (no rotation) on the left
     | 0 0 1 z |  /
     | 0 0 0 1 |    -> We do not use this line (and it has to stay 0,0,0,1)
 
     METHOD #1: Using a Matrix4f
     This is the "manual" method, perfect to understand but error prone !
   */
   Eigen::Matrix4f transform_1 = Eigen::Matrix4f::Identity();
 
   // Define a rotation matrix (see https://en.wikipedia.org/wiki/Rotation_matrix)
   float theta = M_PI/4; // The angle of rotation in radians
   transform_1 (0,0) = std::cos (theta);
   transform_1 (0,1) = -sin(theta);
   transform_1 (1,0) = sin (theta);
   transform_1 (1,1) = std::cos (theta);
   //    (row, column)
 
   // Define a translation of 2.5 meters on the x axis.
   transform_1 (0,3) = 2.5;
 
   // Print the transformation
   printf ("Method #1: using a Matrix4f\n");
   std::cout << transform_1 << std::endl;
 
   /*  METHOD #2: Using a Affine3f
     This method is easier and less error prone
   */
   Eigen::Affine3f transform_2 = Eigen::Affine3f::Identity();
 
   // Define a translation of 2.5 meters on the x axis.
   transform_2.translation() << 2.5, 0.0, 0.0;
 
  // The same rotation matrix as before; theta radians around Z axis
  transform_2.rotate (Eigen::AngleAxisf (theta, Eigen::Vector3f::UnitZ()));

  // Print the transformation
  printf ("\nMethod #2: using an Affine3f\n");
  std::cout << transform_2.matrix() << std::endl;

 // Executing the transformation
 pcl::PointCloud<pcl::PointXYZ>::Ptr transformed_cloud (new pcl::PointCloud<pcl::PointXYZ> ());
  // You can either apply transform_1 or transform_2; they are the same
  pcl::transformPointCloud (*source_cloud, *transformed_cloud, transform_2);

  // Visualization
  printf(  "\nPoint cloud colors :  white  = original point cloud\n"
      "                        red  = transformed point cloud\n");
  pcl::visualization::PCLVisualizer viewer ("Matrix transformation example");

   // Define R,G,B colors for the point cloud
  pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> source_cloud_color_handler (source_cloud, 255, 255, 255);
  // We add the point cloud to the viewer and pass the color handler
  viewer.addPointCloud (source_cloud, source_cloud_color_handler, "original_cloud");

  pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> transformed_cloud_color_handler (transformed_cloud, 230, 20, 20); // Red
  viewer.addPointCloud (transformed_cloud, transformed_cloud_color_handler, "transformed_cloud");

  viewer.addCoordinateSystem (1.0, "cloud", 0);
  viewer.setBackgroundColor(0.05, 0.05, 0.05, 0); // Setting background to a dark grey
  viewer.setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 2, "original_cloud");
  viewer.setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 2, "transformed_cloud");
  //viewer.setPosition(800, 400); // Setting visualiser window position

  while (!viewer.wasStopped ()) 
  { // Display the visualiser until 'q' key is pressed
    viewer.spinOnce ();
  }

  return 0;
}


### 回答1: 您可以使用以下命令在Ubuntu上安装PointCloud: 1. 打开终端并运行以下命令,以更新软件包列表: ``` sudo apt-get update ``` 2. 然后,运行以下命令以安装PointCloud: ``` sudo apt-get install libpcl-dev ``` 3. 安装完成后,您可以使用以下命令检查PointCloud是否正确安装: ``` pcl-config --version ``` 如果返回版本号,则说明已成功安装PointCloud。 ### 回答2: Ubuntu安装点云pcl的步骤如下: 1. 首先,打开终端,可以使用Ctrl + Alt + T 快捷键。 2. 输入以下命令以更新系统软件包列表:sudo apt update 3. 等待更新完成后,使用以下命令安装pcl及其依赖项:sudo apt install libpcl-dev 4. 在安装过程中,您需要确认是否要继续安装。输入y并按Enter键。 5. 等待安装完成后,您现在可以使用pcl进行开发使用它提供的工具了。 这是安装pcl的基本步骤。如果您需要在特定版本的Ubuntu上安装pcl,可以在第3步中的安装命令中指定版本号。例如,如果您要在Ubuntu 18.04上安装pcl,则可以使用以下命令:sudo apt install libpcl-dev=1.8.1-1build2 另外,如果您希望使用更具体的功能或自定义设置安装pcl,您可以访问pcl官方网站(https://pointclouds.org/)获取更多详细信息。您可以在官方网站上找到安装指南、教程和其他资源,以帮助您使用pcl进行开发。 ### 回答3: 要在Ubuntu上安装点云处理PCL (Point Cloud Library),可以按照以下步骤进行操作: 1. 打开终端窗口。你可以使用快捷键Ctrl+Alt+T来打开终端。 2. 更新系统软件包列表。在终端中输入以下命令并按回车键: sudo apt-get update 3. 安装PCL及其依赖项。在终端中输入以下命令并按回车键: sudo apt-get install libpcl-dev 4. 等待安装完成。安装过程可能需要一些时间,具体时间取决于你的系统配置和网络速度。 5. 检查安装是否成功。在终端中输入以下命令并按回车键: pcl_viewer 如果PCL的点云查看器成功打开,则表示安装成功。 以上是在Ubuntu上安装点云处理PCL的基本步骤。你可以在终端中输入pcl_来查看所有与PCL相关的命令和工具。如果你需要使用进行开发,可以在你的C/C++项目中添加PCL头文件和链接,并参考PCL的文档来使用其功能。 值得一提的是,以上的安装方法适用于较新版本的Ubuntu发行版。如果你使用的是旧版本,或者希望使用编译安装方式,你可以参考PCL官方网站(https://pointclouds.org/downloads/)上的指南进行操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值