PCL学习二:PCL基础应用教程

news2024/11/25 11:41:15

参考引用

  • PCL Basic Usage
  • PCL 点云库官网教程

1. pcl_viewer 基本使用

1.1 pcl_viewer 安装测试

  • pcl_data 源码克隆
    $ git clone https://github.com/PointCloudLibrary/data.git
    
  • 进入 /pcl_data/tutorials(如下图)
    $ cd ~/pcl_data/tutorials  # 此处为重命名后的文件夹 pcl_data
    

在这里插入图片描述

  • 查看 .pcd 文件(以 ism_test_cat.pcd 为例)
    $ pcl_viewer ism_test_cat.pcd
    

在这里插入图片描述

1.2 pcl_viewer 常用操作

  • 基本使用

    • 进入:pcl_viewer xxxxx.pcd
    • 帮助:在界面中输入 h,可以在控制台看到帮助信息
    • 退出:界面中输入 q
    • 放大缩小:鼠标滚轮 或 Alt + [+/-]
    • 平移:Shift + 鼠标拖拽
    • 旋转:Ctrl + 鼠标拖拽
    • 修改点颜色:数字 1,2,3,4,5…9,重复按 1 可切换不同颜色方便观察
    • 修改点大小:放大 Ctrl + Shift + 加号,缩小 Ctrl + 减号
    • 保存截图:j
    • 显示颜色尺寸:u
    • 显示比例尺寸:g
    • 在控制列出所有几何和颜色信息:l
  • 常用指令

    # 1. 修改背景色或前景色
    $ pcl_viewer ism_test_cat.pcd -bc 255,255,255    # 修改背景色为白色
    $ pcl_viewer ism_test_cat.pcd -fc 0xff,0x0,0x0   # 修改前景色为红色
    
    # 2. 设置点大小和不透明度
    $ pcl_viewer ism_test_cat.pcd -ps 4    # 设置点大小为 4
    $ pcl_viewer ism_test_cat.pcd -opaque 0.1    # 设置点透明度为 0.1
    
    # 3. 设置坐标轴显示
    $ pcl_viewer ism_test_cat.pcd -ax 64    # 显示大小为 64 的坐标轴
    $ pcl_viewer ism_test_cat.pcd -ax 64 -ax_pos -64,-64,0    # 显示坐标轴并改变其位置(默认 0,0,0)
    
    # 4. 格式转换命令
    $ pcl_pcd2ply input.pcd output.ply    # 将 PCD 转为 ply 文件
    $ pcl_mesh2pcd input.{ply,obj} output.pcd   # 将 CAD 模型转为 PCD 文件
    $ pcl_mesh2pcd input.{ply,obj} output.pcd -leaf_size 10   # -leaf_size :修改体素网格的 XYZ 大小,用于增减点的密度
    
    # 5. Octrees 八叉树可视化(下图所示)
    $ pcl_octree_viewer ism_test_cat.pcd 0.2    # 0.2 代表分辨率
    

在这里插入图片描述

  • 鼠标选点打印坐标
    • 选点模式进入:pcl_viewer -use_point_picking bunny.pcd
    • 选择指定点:shift + 鼠标左键

2. 在项目中使用 PCL

  • 新建项目工作空间 pcl_demo_ws

    $ mkdir pcl_demo_ws
    
  • 在工作空间新建 pcd_write.cpp 文件

    // pcd_write.cpp
    // 随机生成了 5 个点,并将之以 ASCII 形式保存(序列化)在 test_pcd.pcd 文件中
    #include <iostream>
    #include <pcl/io/pcd_io.h>
    #include <pcl/point_types.h>
    
    int main(int argc, char **argv) {
        pcl::PointCloud<pcl::PointXYZ> cloud;
    
        // Fill in the cloud data
        cloud.width = 5;
        cloud.height = 1;
        cloud.is_dense = false; // 没有无穷值或 NaN 值
        cloud.points.resize(cloud.width * cloud.height);
    
        std::cout << rand() << std::endl;
        std::cout << rand() / (RAND_MAX + 1.0f) << std::endl;
        std::cout << 1024 * rand() / (RAND_MAX + 1.0f) << std::endl;
    
        // 随机生成5个点
        for (size_t i = 0; i < cloud.points.size(); ++i) {
            cloud.points[i].x = 1024 * rand() / (RAND_MAX + 1.0f);
            cloud.points[i].y = 1024 * rand() / (RAND_MAX + 1.0f);
            cloud.points[i].z = 1024 * rand() / (RAND_MAX + 1.0f);
        }
    
        pcl::io::savePCDFileASCII("test_pcd.pcd", cloud);
        std::cerr << "Saved " << cloud.points.size() << " data points to test_pcd.pcd." << std::endl;
    
        for (size_t i = 0; i < cloud.points.size(); ++i)
            std::cerr << "    " << cloud.points[i].x << " " << cloud.points[i].y << " " << cloud.points[i].z << std::endl;
    
        return (0);
    }
    
  • 在工作空间新建 CMakeLists.txt 配置文件

    cmake_minimum_required(VERSION 2.6 FATAL_ERROR)
    project(MY_GRAND_PROJECT)
    find_package(PCL 1.3 REQUIRED COMPONENTS common io)
    include_directories(${PCL_INCLUDE_DIRS})
    link_directories(${PCL_LIBRARY_DIRS})
    add_definitions(${PCL_DEFINITIONS})
    add_executable(pcd_write_test pcd_write.cpp)
    target_link_libraries(pcd_write_test ${PCL_LIBRARIES})
    
  • 编译与执行

    # 编译
    $ mkdir build
    $ cd build
    $ cmake ..
    $ make
    
    # 执行
    $ ./pcd_write_test
    
    // 终端输出结果
    1804289383
    0.394383
    -0.106395
    Saved 5 data points to test_pcd.pcd.
        -0.397406 -0.473106 0.292602
        -0.731898 0.667105 0.441304
        -0.734766 0.854581 -0.0361733
        -0.4607 -0.277468 -0.916762
        0.183749 0.968809 0.512055
    
  • 查看生成的 test_pcd.pcd 文件

    $ pcl_viewer test_pcd.pcd
    
    • 查看 pcd 内容
    $ cat test_pcd.pcd
    
    # .PCD v0.7 - Point Cloud Data file format
    VERSION 0.7
    FIELDS x y z
    SIZE 4 4 4
    TYPE F F F
    COUNT 1 1 1
    WIDTH 5
    HEIGHT 1
    VIEWPOINT 0 0 0 1 0 0 0
    POINTS 5
    DATA ascii
    -0.3974061 -0.47310591 0.29260206
    -0.73189831 0.66710472 0.44130373
    -0.73476553 0.85458088 -0.036173344
    -0.46070004 -0.2774682 -0.91676188
    0.1837492 0.96880913 0.5120554
    

3. 使用矩阵变换点云

  • 新建项目工作空间 pcl_demo_ws02

    $ mkdir pcl_demo_ws02
    
  • 在工作空间新建 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>
    
    int main(int argc, char **argv) {
        // Load file | Works with PCD and PLY files
        pcl::PointCloud<pcl::PointXYZ>::Ptr source_cloud(new pcl::PointCloud<pcl::PointXYZ>());
    
        if (pcl::io::loadPCDFile(argv[1], *source_cloud) < 0) {
            std::cout << "Error loading point cloud " << argv[1] << std::endl << std::endl;
            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 row (and it has to stay 0,0,0,1)
        
            方法一:使用 Matrix4f
            这个方法容易理解但也容易出错
        */
        Eigen::Matrix4f transform_1 = Eigen::Matrix4f::Identity();
        float theta = M_PI / 4; // 旋转角(弧度)
        // 旋转矩阵:沿 z 轴旋转 45°
        transform_1(0, 0) = cos(theta);  // transform_1(row, column)
        transform_1(0, 1) = -sin(theta);
        transform_1(1, 0) = sin(theta);
        transform_1(1, 1) = cos(theta);
        // 平移矩阵:沿 x 轴平移 2.5m
        transform_1(0, 3) = 2.5;    
        /*
                | cos(θ) -sin(θ)  0.0 |
            R = | sin(θ)  cos(θ)  0.0 |    // 旋转矩阵:沿 z 轴旋转 45°(逆时针)
                | 0.0     0.0     1.0 |
            t = < 2.5, 0.0, 0.0 >    // 平移矩阵:沿 x 轴平移 2.5m
        */
        // 打印变换结果
        printf("Method #1: using a Matrix4f\n");
        std::cout << transform_1 << std::endl;
    
        /*  
            方法二: 使用 Affine3f
            这个方法更容易且较少出错
        */
        // 创建仿射变换对象
        Eigen::Affine3f transform_2 = Eigen::Affine3f::Identity();
        // 在 z 轴平移 30m
        transform_2.translation() << 0.0, 0.0, 30.0;
        // 绕 Z 旋转 45 度(逆时针)
        transform_2.rotate(Eigen::AngleAxisf(theta, Eigen::Vector3f::UnitZ()));
        // 打印仿射变换矩阵
        printf("\nMethod #2: using an Affine3f\n");
        std::cout << transform_2.matrix() << std::endl;
    
        // 创建变换后的点云
        pcl::PointCloud<pcl::PointXYZ>::Ptr transformed_cloud(new pcl::PointCloud<pcl::PointXYZ>());
        // 执行变换,source_cloud 为变换前的点云
        pcl::transformPointCloud(*source_cloud, *transformed_cloud, transform_2);
    
        // 可视化操作
        printf("\nPoint cloud colors : white = original point cloud\n" "red = transformed point cloud\n");
        pcl::visualization::PCLVisualizer viewer("Matrix transformation example");
    
        // 定义点云的 RGB 值,并将点云添加到查看器中,并通过颜色处理程序
        pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> source_cloud_color_handler(source_cloud, 255, 255, 255);
        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(0.5, "cloud", 0);
        // 设置背景色为黑灰色
        viewer.setBackgroundColor(0.05, 0.05, 0.05, 0);
        // 设置渲染属性(点大小)
        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
    
        // 当按下 q 之前不断循环可视化操作
        while (!viewer.wasStopped()) { 
            viewer.spinOnce();
        }
        return 0;
    }
    
  • 在工作空间新建 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})
    
  • 编译与执行

    # 编译
    $ mkdir build
    $ cd build
    $ cmake ..
    $ make
    
    # 执行
    $ ./matrix_transform ism_test_cat.pcd  # 后面跟的 .pcd 或 .ply 文件为需要进行矩阵变换的文件
    
    // 终端输出结果
    Method #1: using a Matrix4f
     0.707107 -0.707107         0       2.5
     0.707107  0.707107         0         0
            0         0         1         0
            0         0         0         1
    
    Method #2: using an Affine3f
     0.707107 -0.707107         0         0
     0.707107  0.707107         0         0
            0         0         1        30
            0         0         0         1
    
    Point cloud colors : white  = original point cloud
                           red  = transformed point cloud
    

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/476114.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

IDEA常用提升效率的操作小记

IDEA目前是使用最广泛的Java开发工具之一了&#xff0c;虽然是收费的&#xff0c;但是也提供了免费的社区版&#xff0c;并且收费版也支持使用github的开源项目&#xff0c;使用免费license&#xff0c;虽然每年都要续&#xff0c;我用的就是开源项目申请的免费license。 开发…

【Pytorch基础教程39】torch常用tensor处理函数

note 文章目录 note一、tensor的创建二、tensor的加减乘除三、torch.argmax()函数四、gathter函数小栗子1小栗子2&#xff1a;如果每行需要索引多个元素&#xff1a; 四、针对某一维度的操作五、改变维度、拼接、堆叠等操作Reference 一、tensor的创建 torch.tensor会复制data…

STM32配置ADC2(DMA)进行采集 DAC 输出-2

0.一定要先看上一节&#xff1a;STM32配置ADC2&#xff08;DMA&#xff09;进行采集 DAC 输出-2 1.实验目标 在上一节的基础上&#xff0c;我们把 DAC&#xff08;三角波&#xff09;给集成进来&#xff0c;实现按下按键输出三角波&#xff0c;通过串口发送数据给电脑&#x…

Apache Zeppelin系列教程第二篇——整体架构

Zeppelin 架构&#xff1a; 首先我们来了解下 Zeppelin的架构, Zeppelin 主要分3层。 Web前端 Zeppelin Server Interpreter Zeppelin前端负责前端页面的交互&#xff0c;通过Rest API 和WebSocket的方式与Zeppelin Server进行交互。 Zeppelin Server是一个Web server&…

【python 基础语法一】注释,变量与运算符

一、注释 注释: 就是对代码的解释&#xff0c;方便阅读&#xff0c;被注释的代码不执行 分类 单行注释 # 1.单行注释 以#号开头 &#xff0c;右边的所有东西都被当做说明文字 &#xff0c;程序不进行编译运行。 print(hello world)多行注释 # 2.多行注释 三个单引号 或…

Sentinel源码分析学习

文章目录 前言Sentinel源码分析1.Sentinel的基本概念1.1.ProcessorSlotChain1.2.Node1.3.Entry1.3.1.自定义资源1.3.2.基于注解标记资源 1.4.Context1.4.1.什么是Context1.4.2.Context的初始化1.4.2.1.自动装配1.4.2.2.AbstractSentinelInterceptor1.4.2.3.ContextUtil 2.Proce…

django显示echart图表:柱状图、折线图、饼图、地图、词云

django显示echart图表 效果: 示例demo 点我查看 1、urls.py 其中关键代码: urlpatterns = [path("book_chart/", views.book_chart, name="book_cha

LINUX压缩和解压和磁盘管理与维护命令

文章目录 一、压缩和解压命令二、磁盘管理与维护命令总结 一、压缩和解压命令 Linux zip命令:压缩文件或目录 Linux unzip命令:解压文件或目录 Linux tar命令:归档工具 二、磁盘管理与维护命令 Linux df命令:显示磁盘空间使用情况 Linux mount命令:挂载文件系统 Linux quota命…

APK文件结构

文件结构 assets文件用来存放需要打包到Android 应用程序的静态资源文件&#xff0c;例如图片资源文件&#xff0c;JSON配置文件&#xff0c;渠道配置文件&#xff0c;二进制数据文件&#xff0c;HTML5离线资源文件等 与res/raw目录不同的数&#xff0c;assets目录支持任意深度…

数位dp。

一&#xff0c;思想&#xff1a; 在处理1e9甚至1e18,1e100的问题时&#xff0c;因为在统计情况下有很多重复的计算&#xff0c;数位dp实现了相同状态只计算一次&#xff0c;从而大幅减少运算时间&#xff0c;思想就是对每一位进行dp&#xff0c;计算时记忆化每一位可以有的状态…

HashMap机制

反思 HashMap之前只是面试时会看下面试题&#xff0c;但实际从没有撸过源码&#xff0c;对于工作多年的菜鸟来说&#xff0c;对技术不尊重&#xff0c;整理了篇文档&#xff0c;记忆加深一下 原理 假如让我们来设计HashMap实现&#xff0c;我们如何设计一个key->value键值…

4.7排序(C语言)

1.八大排序 加一个计数排序&#xff08;时间复杂度为O(n)&#xff0c; 空间复杂度为O(max(n, range)&#xff0c;非比较排序&#xff09;。 2.希尔排序 3.三个O(n^2)的排序的比较 4.归并排序和快速排序 非递归&#xff1a; 5.排序比较 注意&#xff1a; 下面4种高效排序中&…

【Git】篇一

文章目录 一、Git概述1、版本控制器的方式2、Git的工作流程图 二、Git的安装与常用命令1、Git环境安装2、Git环境基本配置3、获取本地仓库4、基础操作指令 三、分支 一、Git概述 开发中&#xff0c;代码备份、代码还原回滚、追溯、协同开发等场景必不可少&#xff0c;由此&…

特征可视化技术(CAM)

https://zhuanlan.zhihu.com/p/269702192 CAM技术可以帮助我们理解CNN在图像中寻找目标对象的过程&#xff0c;并且可以用于可视化CNN的中间层特征&#xff0c;以及对图像分类结果的解释和可视化。CAM技术的实现比较简单&#xff0c;可以使用常用的深度学习框架如PyTorch和Te…

【C++】模板进阶——非类型模板参数、模板特化、模板分离编译

目录 1.非类型模板参数array 2.模板的特化2.1概念2.2函数模板特化2.3类模板特化1.全特化2.偏特化3.类模板特化应用示例 3.模拟分离编译3.1什么是分离编译3.2模板的分离编译1.问题&#xff1a;2.原因3.解决方法 4.模板总结 1.非类型模板参数 模板参数分为类型形参 与 非类型形参…

重新思考无边界世界中的网络安全

©网络研究院 在一个越来越不是物理边界而是数字边界的世界里&#xff0c;全球网络安全事件的数量持续上升&#xff0c;公共部门机构面临的挑战也随之增加。 保护组成数据的利害关系比以往任何时候都更加重要。为了抵御这些数字威胁&#xff0c;政府机构正在采用零信任方…

sqlite基础

一.sqlite基础 1.下载与环境配置 从下载地址&#xff0c;点击我 这里下载适合你版本的压缩包 您需要下载 sqlite-tools-win32-*.zip 和 sqlite-dll-win32-*.zip 压缩文件。创建文件夹 C:\sqlite&#xff0c;并在此文件夹下解压上面两个压缩文件&#xff0c;将得到 sqlite3.d…

【模板方法设计模式详解】C/Java/JS/Go/Python/TS不同语言实现

简介 模板方法模式&#xff08;Template Method Pattern&#xff09;也叫模板模式&#xff0c;是一种行为型模式。它定义了一个抽象公开类&#xff0c;包含基本的算法骨架&#xff0c;而将一些步骤延迟到子类中&#xff0c;模板方法使得子类可以不改变算法的结构&#xff0c;只…

ToLua框架

ToLua 是一个用于在 Unity 中为 Lua 提供 C# 语言绑定的框架。通过 ToLua&#xff0c;你可以方便地将 C# 代码暴露给 Lua 脚本&#xff0c;并在 Lua 脚本中调用 C# 类、方法和属性。 更新流程 原理&#xff1a;使用AssetBundle进行资源的更新&#xff0c;而由于lua运行时才编…