(学习笔记)PCL点云库的基本使用

这篇具有很好参考价值的文章主要介绍了(学习笔记)PCL点云库的基本使用。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

前言

1、理解点云库

1.1、不同的点云类型

1.2、PCL中的算法

1.3、ROS的PCL接口

2、创建第一个PCL程序

2.1、创建点云

2.2、加载点云文件

2.3、创建点云文件

2.4、点云可视化

2.5、点云滤波和下采样

2.5.1、点云滤波

 2.5.2、点云下采样

2.6、点云配准与匹配


前言

        点云是一种能够直观地表示和操作3D传感器所提供数据的方式,这类传感器包括深度摄像头和激光雷达。该类传感器在三维坐标参考系下对空间进行有限点集采样构成点云。通俗的来说,点云就是分布在三维空间的有限个点,这些点具体化的表示了三维传感器所采集到的数据,我们可以很容易的通过点云来查看空间中物体的位置。

下面是一张固态激光雷达扫描的树林中的一栋房屋点云图:

(学习笔记)PCL点云库的基本使用

        点云库(Point Cloud Library)提供了大量的数据类型和数据结构,不仅能够方便的表示采样空间中的点,而且可以表示采样空间的不同属性,比如颜色、法向量等。PCL同样提供了许多最先进的算法对数据样本进行处理,比如滤波、模型估计、表面重建等。ROS提供了一种基于消息的接口(PCL点云可以通过该接口进行有效的通信),还有一组将本地的PCL类型转换到ROS消息的转换函数,这和处理OpenCV图像一样。上面的图片就是调用PCL来处理过的点云图像。

        本文主要介绍PCL库的背景、相关数据类型以及ROS接口消息,然后演示如何使用PCL处理数据以及如何通过ROS发送和接收数据的技术。

1、理解点云库

点云库和ROS的PCL接口的基本概念:

点云库:处理三维数据提供了一组数据结构和算法;

ROS的PCL接口:提供一组消息以及消息与PCL数据结构之间的转换函数。

从C++的角度来说,PCL包含了一个非常重要的数据结构,那就是点云。这个数据结构被设计成一个 模板类,它把点的类型当做模板类的参数,点云类实际上是一个容器,这个容器里包含了所有点云需要的公共信息,而不管点是什么类型。下面是点云中最重要的公共字段:

header:这个字段是pcl:PCLHeader类型。指定了点云的获取时间。

points:这个字段是std::vector<PointT…>类型,它是储存所有点的容器。vector定义中的PointT对 应于类的模板参数,即点的类型。

width:这个字段指定了点云组织成一种图像时的宽度,否则它包含的是云中点的数量。

height:这个字段指定了点云组织成一种图像时的高度,否则它总是1。

is_dense:这个字段指定了点云中是否有无效值(无穷大或NaN值)。

sensor origin:这个字段是Eigen::Vector4f类型,并且定义了传感器根据相对于原点的平移所得到的位姿。

sensororientation:这个字段是Eigen::Ouaternionf类型,并且定义了传感器旋转所得到的位姿。

PCL算法利用这些字段来处理数据,并且用户可以利用它们来创造自己的算法。一但明白了点云的结构,下一步就是理解一个点云可以包含不同的点类型、PCL如何工作以及ROS中的PCL 接口。

1.1、不同的点云类型

        正如前面描述的一样,pcl::PointCloud包含了一个字段,它作为一个容器为点提供服务。这个字段就是PointT类型,它是pcl:PointCloud类的模板参数,并且定义了云所要储存的点类型。PCL定义了许多不同类型的点,下面是一些最常用到的类型:

pcl::PointXYZ: 这是最简单也可能是最常用到的点类型;它只储存了3D xyz的信息。

pcl::PointXYZI: 这种类型非常类似于上面的那种,但它还包含了一个描述点亮度(intensity)的字段。当想要获取传感器返回的亮度高于一定级别的点时非常有用。还有与此相似的其他两种标准的点数据类型:一是pcl:InterestPoint,它有一个字段储存强度(streneth);二是pcl::PointWithRange:它有一个字段储存距离(视点到采样点)。

pcl::PointXYZRGBA: 这种点类型储存3D信息,也储存颜色(RGB=Red,Green, Blue)和透明度(A=Alpha)。

pcl::PointXYZRGB: 这种点类型与前面的点类型相似,但是它没有透明度字段。

pcl:Normal: 这是最常用的点类型,表示曲面上给定点处的法线以及测量的曲率。

pcl::PointNormal: 这种点类型跟前一个点类型一样;它包含了给定点所在曲面法线以及曲率信息,但是它也包含了点的3Dxyz坐标。这种点类型的变异类型是 PointXYZRGBNormal和PointXYZINormal,正如名字所提示,它们包含了颜色(前者)和亮度(后者)。

        除了这些常用的点类型外,还有许多标准的PCL类型,比如PointWithViewpointMomentInvariants(具有视点力矩不变量的点)、BoundaryPrincipalCurvatures(边界主曲率)、Histogram(直方图)等。更重要的是,PCL算法都是模板化的,所以这样不仅可以使用已经可用的类型,理论上还可以使用用户定义的语法正确的类型。

1.2、PCL中的算法

        整个PCL函数库都使用了非常具体的设计模式,该设计模式定义了点云处理算法。通常来说,这些类型算法的问题是它们高度可配置,为了完全发挥它们的潜能,这个库必须为用户提供一个可以指定所有要求的参数的机制以及常用的默认值。

        为了解决这个问题,PCL的开发者决定把每个算法做成一个类,这个类属于一个有着特定共性的继承类。这个方法允许PCL开发者通过获取已经存在的算法并加上新算法所需要的参数,以重用这些算法,并且它允许用户通过存取器轻松地为算法提供它所需要的参数值,而其余的参数都取默认值。下面的代码展示了通常是如何使用PCL算法的:                

pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
pcl::PointCloud<pcl::PointXYZ>::Ptr result(new pcl::PointCloud<pcl::PointXYZ>);
pcl::Algorithm<pcl::PointXYZ> algorithm; 
algorithm.setInputCloud(cloud); 
algorithmsetParameter(1.0);
algorithm.setAnotherParameter(033); 
algorithmprocess(*result)

1.3、ROS的PCL接口

通过ROS自带的基于消息的通信系统,ROS的PCL接口提供了与PCL数据结构进行通信所需要的方法。为此,这里定义了不同的消息类型去处理点云和其他PCL算法中产生的数据。结合这些消息类型,也提供了一组将本地PCL数据类型转换为消息的函数。其中一些最重要的消息类型如下所示:

std_msgs::Header: 这不是真的消息类型。但它通常是每一个ROS消息的一部分。它包含消息发送时间、序列号和坐标系名称等信息。这个PCL类型等价于pcl::Header type。

sensor_msgs::PointCloud2: 这也许是最重要的消息类型。这个消息用来转换pcl::PointCloud类型。然而必须考虑的是,在未来支持pcl::PCLPointCloud2的PCL版本中这个消息类型将会弃用。

pcl_msgs::PointIndices: 这个消息类型储存了一个点云中点的索引,等价的PCL类型是pcl::PointIndices。(PointIndices:点索引)

pcl_msgs::PolygonMesh: 这个消息类型保存了描绘网格、顶点和多边形的信息。等价的PCL类型是pcl::PolygonMesh。(PolygonMesh:多边形网格)

pcl_msgs::Vertices: 这个消息类型将一组顶点的索引保存在一个数组中,例如描述一个多边形。等价的 PCL类型是pcl:Vertices。(Vertices:顶点)

pcl_msgs::ModelCoefficients: 这个消息类型储存了一个模型的不同系数,例如描述一个平面需要的四个参数。等价的PCL类型是pcl::ModelCoefficients。(ModelCoefficients:模型系数)

通过ROS的PCL功能包提供的转换函数可以将前面的消息转换为PCL类型或者从PCL类型转换为消息。所有这些函数都有一个相似签名(signature),这意味着一旦我们知道如何转换一个类型,就知道如何转换所有的类型了。下面的函数量由pclconversions命名空间提供的:

void fromPCL(const<PCL Type>&ROS Message types&); 
void MoveFromPCL(<PCL Type>&ROS Mesage type>&); 
void toPCL(const R0S Message types &, <PCL Type> &); 
void moveToPCL(<ROS Message type> &, <PCL Type>&);

这里,PCL Type必须用一个预先指定的PCL类型替代,ROS Message type必须用消息替代。sensormsgs::PointCloud2指定了一组函数执行这些转换:

void toROSMsg(const pcl:PointCloud<T>&, sensor_msgs::Pointcloud2 &);
void fromROSMsg(const sensor_msgs::PointCloud2 &, pcl:PointCloud<T>&);
void moveFromROSMsg(sensor_msgs::PointCloud2 &, pcl:PointCloud<T>&);

你也许会好奇每个函数和它的move版本之间的区别。答案很简单,标准版本执行对数据的深复制。而move 版本执行浅复制并注销源数据容器。这称为“移动语义”(movesemantic)。

2、创建第一个PCL程序

        本节将学习如何集成PCL和ROS。非常有必要知道并理解ROS软件如何布局以及编译,尽管这些步骤是简单的重复。在第一个PCL程序中用到的示例除了能够成功编译一个有效的ROS节点之外没有任何其他作用。

在工作空间中创建一个ROS软件包。这个软件包依赖于pcl_conversions、pcl_ros、pcl_msgs和sensors_msgs包:

mkdir -p pclstudy_ws/src
cd pclstudy_ws/src
catkin_create_pkg chapter6_tutorials pcl_ros roscpp rospy sensor_msgs std_msgs 
cd ..
catkin_make 

在/pclstudy_ws/src/chapter6_tutorials内的CMakeList.txt添加如下内容:

catkin_package()
find_package(PCL REQUIRED) 
include_directories(include${PCL_INCLUDE_DIRS})
link_directories(${PCL_LIBRARY_DIRS}) 
add_executable(pcl_create src/pcl_create.cpp)
target_link_libraries(pcl_create ${catkin_LIBRARIES} ${PCL_LIBRARIES})

2.1、创建点云

pcl_create.cpp:

#include <ros/ros.h>
#include <pcl/point_cloud.h>
#include <pcl_conversions/pcl_conversions.h>
#include <sensor_msgs/PointCloud2.h>

int main(int argc, char **argv)
{
    ros::init(argc, argv, "pcl_create");

    ros::NodeHandle nh;
    ros::Publisher pcl_pub = nh.advertise<sensor_msgs::PointCloud2>("pcl_output",1);
    pcl::PointCloud<pcl::PointXYZ> cloud;
    sensor_msgs::PointCloud2 output;

    cloud.width = 100;
    cloud.height  = 1;
    cloud.points.resize(cloud.width*cloud.height);

    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::toROSMsg(cloud,output);
    output.header.frame_id = "odm";

    ros::Rate loop_rate(1);
    while(ros::ok()){
        pcl_pub.publish(output);
        ros::spinOnce();
        loop_rate.sleep();
    }
    return 0;
}

编译:

cd ~/pclstudy_ws | catkin_make 

刷新环境:

source devel/setup.bash

运行和在RVIZ中显示:

#分三个终端输入
roscore
rosrun chapter6_tutorials pcl_create
rosrun rviz rviz

在rviz中增加PointCloud2、topic选择pcl_output、fixed Frame输入odom,结果如图:

(学习笔记)PCL点云库的基本使用

2.2、加载点云文件

PCL提供了一些标准的文件格式加载和存储点云到磁盘,研究者常用这种方法将有趣的数据集分享给其他人去试验。这种格式叫做PCD,经过设计它可以支持PCL指定的扩展。

PCD文件格式:

# .PCD v.5 - Point Cloud Data file format
FIELDS x y z intensity distance sid
SIZE 4 4 4 4 4 4
TYPE F F F F F F
COUNT 1 1 1 1 1 1
WIDTH 460400
HEIGHT 1
POINTS 460400
DATA ascii
-0.93387 -0.6825 -1.1865 12 1.485 7
-0.93173 -0.68323 -1.1878 10 1.485 8
-0.92185 -0.68054 -1.1831 10 1.475 10

加载程序:

将下面的代码复制到新建的pcl_read.cpp文件中,pcl_read.cpp放在chapter6_tutorials/src文件夹下,目前该目录下有两个cpp文件,另一个是pcl_create.cpp。

#include <ros/ros.h>
#include <pcl/point_cloud.h>
#include <pcl_conversions/pcl_conversions.h>
#include <sensor_msgs/PointCloud2.h>
#include <pcl/io/pcd_io.h>

int main(int argc, char **argv)
{
	ros::init(argc, argv, "pcl_read");

	ros::NodeHandle nh;
	ros::Publisher pcl_pub = nh.advertise<sensor_msgs::PointCloud2>("pcl_output", 1);

	pcl::PointCloud<pcl::PointXYZ> cloud;
	sensor_msgs::PointCloud2 output;

	pcl::io::loadPCDFile("test_pcd.pcd",cloud);

	pcl::toROSMsg(cloud,output);// pcl格式转为ROS格式
	output.header.frame_id = "odom";
	ros::Rate loop_rate(1);

	while(ros::ok()){
		pcl_pub.publish(output);
		ros::spinOnce();
		loop_rate.sleep();
	}

	return 0;
}

我们在chapter6_tutorials目录下新建一个data文件夹,用来存放pcd文件,我找了一个之前跑算法保存好的pcd文件放在其中。

和上面创建点云一样,我们在/pclstudy_ws/src/chapter6_tutorials内的CMakeList.txt添加如下内容:

add_executable(pcl_read src/pcl_read.cpp)
target_link_libraries(pcl_read ${catkin_LIBRARIES} ${PCL_LIBRARIES})

编译:

cd ~/pclstudy_ws | catkin_make 

刷新环境:

source devel/setup.bash

运行和在RVIZ中显示:

#分三个终端输入,第二行和第三行在一个终端里
roscore
roscd chapter6_tutorials/data
rosrun chapter6_tutorials pcl_read
rosrun rviz rviz

在rviz中增加PointCloud2、topic选择pcl_output、fixed Frame输入odom,结果如图:

(学习笔记)PCL点云库的基本使用

2.3、创建点云文件

 通过下面的程序,我们可以将接收到的点云储存为文件,它订阅了一个sensor_msgs/PointCloud2主题。此文件命名为pcl_write.cpp,放在和pcl_read.cpp相同的目录下。

#include <ros/ros.h>
#include <pcl/point_cloud.h>
#include <pcl_conversions/pcl_conversions.h>
#include <sensor_msgs/PointCloud2.h>
#include <pcl/io/pcd_io.h>

void cloudCB(const sensor_msgs::PointCloud2 &input){
	pcl::PointCloud<pcl::PointXYZ> cloud;
	pcl::fromROSMsg(input,cloud);
	pcl::io::savePCDFileASCII("write_pcd_test.pcd",cloud);
}

int main(int argc, char **argv)
{
	ros::init(argc,argv,"pcl_write");
	ros::NodeHandle nh;
	ros::Subscriber bat_sub = nh.subscribe("pcl_output",10,cloudCB);

	ros::spin();

	return 0;
}

和上面创建点云一样,我们在/pclstudy_ws/src/chapter6_tutorials内的CMakeList.txt添加如下内容:

add_executable(pcl_write src/pcl_write.cpp)
target_link_libraries(pcl_write ${catkin_LIBRARIES} ${PCL_LIBRARIES})

 编译:

cd ~/pclstudy_ws | catkin_make 

刷新环境:

source devel/setup.bash

运行和在RVIZ中显示:

#分三个终端输入,第二行和第三行在一个终端输入,
第四行在哪个目录下,pcd文件就会保存在哪个目录下
roscore
roscd chapter6_tutorials/data
rosrun chapter6_tutorials pcl_read
rosrun chapter6_tutorials pcl_write

这样我们可以看到在上述第四行命令所在文件夹下多了一个write_pcd_test.pcd文件。

(学习笔记)PCL点云库的基本使用

2.4、点云可视化

PCL提供了几种方法将点云可视化,第一种也是最简单的一种是通过点云查看器,例如Cloudcompare和pcl_viewer,可以直接打开pcd文件。第二种是写一个像上面所写的pcl_read.cpp程序,通过运行这个程序使pcd文件在rviz中显示。第三种是创建一个节点订阅sensor_msgs/PointCloud2,这个节点会使用PCL中的cloud_reviewer显示主题中的点云数据。

在src目录下创建pcl_visualize.cpp:

#include <ros/ros.h>
#include <iostream>
#include <pcl/visualization/cloud_viewer.h>
#include <sensor_msgs/PointCloud2.h>
#include <pcl_conversions/pcl_conversions.h>
class cloudHandler
{
public:
    cloudHandler()
    : viewer("Cloud Viewer")
    {
        pcl_sub = nh.subscribe("pcl_output", 10, &cloudHandler::cloudCB, this);
        viewer_timer = nh.createTimer(ros::Duration(0.1), &cloudHandler::timerCB, this);
    }
    void cloudCB(const sensor_msgs::PointCloud2 &input)
    {
        pcl::PointCloud<pcl::PointXYZ> cloud;
        pcl::fromROSMsg(input, cloud);
        viewer.showCloud(cloud.makeShared());
    }
    void timerCB(const ros::TimerEvent&)
    {
        if (viewer.wasStopped())
        {
            ros::shutdown();
        }
    }
protected:
    ros::NodeHandle nh;
    ros::Subscriber pcl_sub;
    pcl::visualization::CloudViewer viewer;
    ros::Timer viewer_timer;
};
main (int argc, char **argv)
{
    ros::init (argc, argv, "pcl_visualize");
    cloudHandler handler;
    ros::spin();
    return 0;
}

跟之前的一样在CMakeLists.txt文件中加入:

add_executable(pcl_visualize src/pcl_visualize.cpp)
target_link_libraries(pcl_visualize ${catkin_LIBRARIES}  ${PCL_LIBRARIES})

编译、source完成后按以下步骤运行:

roscore
roscd chapter6_tutorials/data
rosrun chapter6_tutorials pcl_read
rosrun chapter6_tutorials pcl_visualize

 (学习笔记)PCL点云库的基本使用

2.5、点云滤波和下采样

2.5.1、点云滤波

当处理点云时,可能会遇到两个问题,过大的噪声和过大的密度。此时我们需要进行滤波,过滤掉无用的噪声和降低点云密度。

在src目录下创建pcl_filtered.cpp文件:

#include <ros/ros.h>
#include <pcl/point_cloud.h>
#include <pcl_conversions/pcl_conversions.h>
#include <sensor_msgs/PointCloud2.h>
#include <pcl/filters/statistical_outlier_removal.h>

class cloudHandler
{
public:
    cloudHandler()
    {
        pcl_sub = nh.subscribe("pcl_output", 10, &cloudHandler::cloudCB, this);
        pcl_pub = nh.advertise<sensor_msgs::PointCloud2>("pcl_filtered", 1);
    }

    void cloudCB(const sensor_msgs::PointCloud2& input)
    {
        pcl::PointCloud<pcl::PointXYZ> cloud;
        pcl::PointCloud<pcl::PointXYZ> cloud_filtered;
        sensor_msgs::PointCloud2 output;

        pcl::fromROSMsg(input, cloud);

        pcl::StatisticalOutlierRemoval<pcl::PointXYZ> statFilter;
        statFilter.setInputCloud(cloud.makeShared());
        statFilter.setMeanK(10);
        statFilter.setStddevMulThresh(0.2);
        statFilter.filter(cloud_filtered);

        pcl::toROSMsg(cloud_filtered, output);
        pcl_pub.publish(output);
    }

protected:
    ros::NodeHandle nh;
    ros::Subscriber pcl_sub;
    ros::Publisher pcl_pub;
};

main(int argc, char** argv)
{
    ros::init(argc, argv, "pcl_filter");

    cloudHandler handler;

    ros::spin();

    return 0;
}

跟之前的一样在CMakeLists.txt文件中加入:

add_executable(pcl_filtered src/pcl_filtered.cpp)
target_link_libraries(pcl_filtered ${catkin_LIBRARIES}  ${PCL_LIBRARIES})

编译、source完成后按以下步骤运行:

roscore
roscd chapter6_tutorials/data
rosrun chapter6_tutorials pcl_read
rosrun chapter6_tutorials pcl_filtered
rosrun rviz rviz

(学习笔记)PCL点云库的基本使用

 2.5.2、点云下采样

在src目录下创建pcl_downsampled.cpp文件:

#include <ros/ros.h>
#include <pcl/point_cloud.h>
#include <pcl_conversions/pcl_conversions.h>
#include <sensor_msgs/PointCloud2.h>
#include <pcl/filters/voxel_grid.h>

class cloudHandler
{
public:
    cloudHandler()
    {
        pcl_sub = nh.subscribe("pcl_filtered", 10, &cloudHandler::cloudCB, this);
        pcl_pub = nh.advertise<sensor_msgs::PointCloud2>("pcl_downsampled", 1);
    }

    void cloudCB(const sensor_msgs::PointCloud2 &input)
    {
        pcl::PointCloud<pcl::PointXYZ> cloud;
        pcl::PointCloud<pcl::PointXYZ> cloud_downsampled;
        sensor_msgs::PointCloud2 output;

        pcl::fromROSMsg(input, cloud);

        pcl::VoxelGrid<pcl::PointXYZ> voxelSampler;
        voxelSampler.setInputCloud(cloud.makeShared());
        voxelSampler.setLeafSize(0.0001f, 0.0001f, 0.0001f);
        voxelSampler.filter(cloud_downsampled);

        pcl::toROSMsg(cloud_downsampled, output);
        pcl_pub.publish(output);

    }
protected:
    ros::NodeHandle nh;
    ros::Subscriber pcl_sub;
    ros::Publisher pcl_pub;
};

main(int argc, char **argv)
{
    ros::init(argc, argv, "pcl_downsampling");

    cloudHandler handler;

    ros::spin();

    return 0;
}

跟之前的一样在CMakeLists.txt文件中加入:

add_executable(pcl_downsampled src/pcl_downsampled.cpp)
target_link_libraries(pcl_downsampled ${catkin_LIBRARIES}  ${PCL_LIBRARIES})

编译、source完成后按以下步骤运行:

roscore
roscd chapter6_tutorials/data
rosrun chapter6_tutorials pcl_read
rosrun chapter6_tutorials pcl_filtered
rosrun chapter6_tutorials pcl_downsampled
rosrun rviz rviz

(学习笔记)PCL点云库的基本使用

2.6、点云配准与匹配

配准和匹配时一种在很多场景中经常使用的技术,这个应用场景中包括在两个数据集中寻找共同的结构或特征,然后利用他们将数据集拼接在一起。当一个高速移动的源中获取一个点云时这个技术很有用,并且我们会得到对源运动的一个估计。有了这个算法,我们可以将这些云集拼接在一起并降低估计传感器时的不确定性。PCL提供了一个成为迭代最近点(Iterative Closest Point)算法执行配准和匹配。

在src目录下创建pcl_matching.cpp文件:

#include <ros/ros.h>
#include <pcl/point_cloud.h>
#include <pcl/registration/icp.h>
#include <pcl_conversions/pcl_conversions.h>
#include <sensor_msgs/PointCloud2.h>

class cloudHandler
{
public:
    cloudHandler()
    {
        pcl_sub = nh.subscribe("pcl_downsampled", 10, &cloudHandler::cloudCB, this);
        pcl_pub = nh.advertise<sensor_msgs::PointCloud2>("pcl_matched", 1);
    }

    void cloudCB(const sensor_msgs::PointCloud2 &input)
    {
        pcl::PointCloud<pcl::PointXYZ> cloud_in;
        pcl::PointCloud<pcl::PointXYZ> cloud_out;
        pcl::PointCloud<pcl::PointXYZ> cloud_aligned;
        sensor_msgs::PointCloud2 output;

        pcl::fromROSMsg(input, cloud_in);

        cloud_out = cloud_in;

        for (size_t i = 0; i < cloud_in.points.size (); ++i)
        {
            cloud_out.points[i].x = cloud_in.points[i].x + 0.7f;
        }

        pcl::IterativeClosestPoint<pcl::PointXYZ, pcl::PointXYZ> icp;
        icp.setInputSource(cloud_in.makeShared());
        icp.setInputTarget(cloud_out.makeShared());

        icp.setMaxCorrespondenceDistance(5);
        icp.setMaximumIterations(100);
        icp.setTransformationEpsilon (1e-12);
        icp.setEuclideanFitnessEpsilon(0.1);

        icp.align(cloud_aligned);

        pcl::toROSMsg(cloud_aligned, output);
        pcl_pub.publish(output);
    }

protected:
    ros::NodeHandle nh;
    ros::Subscriber pcl_sub;
    ros::Publisher pcl_pub;
};

main(int argc, char **argv)
{
    ros::init(argc, argv, "pcl_matching");

    cloudHandler handler;

    ros::spin();

    return 0;
}

(学习笔记)PCL点云库的基本使用文章来源地址https://www.toymoban.com/news/detail-400034.html

到了这里,关于(学习笔记)PCL点云库的基本使用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 常见的点云下载地址/点云集合/点云库30个

    1、pcl库自带教程所需的点云数据下载地址 Point Cloud Library - Browse /PCD datasets at SourceForge.net 另外一个地址 https://github.com/PointCloudLibrary/data 31、新增:VTK库的点云数据下载地址,包含.vtkplypdbvtptifstl等格式的点云数据 https://github.com/pyvista/vtk-data/tree/master/Data 2、Princeton ModelNet

    2024年02月13日
    浏览(54)
  • 『点云处理任务 』用PCL库 还是 深度学习模型?

    1、点云滤波 :用于去除噪音、下采样和平滑等操作,入统计滤波、体素滤波和高斯滤波等。 2、特征提取和描述 :用于捕获地点云数据的表面特征,入法线估计、曲率计算、局部特征描述子(如FPFH、SHOT)等。 3、点云配准 :,用于将不同视角或不同时间的点云数据对齐,如

    2024年02月13日
    浏览(40)
  • PCL 使用LCCP算法进行点云分割

      LCCP是Locally Convex Connected Patches的缩写,算法大致可以分成两个部分: 基于超体聚类的过分割。 在超体聚类的基础上再聚类。 /

    2024年02月12日
    浏览(50)
  • 使用PCL滤波器实现点云裁剪

    点云裁剪是根据提取划分或者说标注出来的点云区域(ROI区域),对点云进行区域分离(点云裁剪和点云分割还是有区别的,所以这里用分离而不是分割)。根据已知的ROI区域,对点云进行裁剪。要么留下点云ROI区域,要么去除。 ROI区域一般都是一个矩形,即(x,y,width,

    2024年02月15日
    浏览(43)
  • 学习PCL库:基于LOD的大规模点云可视化

    公众号致力于点云处理,SLAM,三维视觉,高精地图等领域相关内容的干货分享,欢迎各位加入,有兴趣的可联系dianyunpcl@163.com。未经作者允许请勿转载,欢迎各位同学积极分享和交流。 什么是LOD(Level of Detail)? LOD(Level of Detail)是一种在计算机图形学中用于优化渲染性能

    2024年02月08日
    浏览(39)
  • Ubuntu 20.04.06 PCL C++学习记录(二十七)【附所用点云】

    @[TOC]PCL中点云配准模块的学习 参考书籍:《点云库PCL从入门到精通》以及官方代码PCL官方代码链接,,PCL版本为1.10.0,CMake版本为3.16,可用点云下载地址 使用正态分布算法来确定两个大型点云之间的刚体变换,正态分布变换算法是一个配准算法,它应用于三维点的统计模型,

    2024年04月27日
    浏览(88)
  • PCL 使用点云创建数字高程模型DEM

       数字高程模型(Digital Elevation Model),简称DEM,是通过有限的地形高程数据实现对地面地形的数字化模拟(即地形表面形态的数字化表达),它是用一组有序数值阵列形式表示地面高程的一种实体地面模型,是数字地形模型(Digital Terrain Model,简称DTM)的一个分支,其它各种

    2024年02月13日
    浏览(41)
  • 点云配准--gicp原理与其在pcl中的使用

    总结:gicp引入了概率信息(使用协方差阵),提出了icp的统一模型,既可以解释点到点和点到面的icp,也在新模型理论的基础上,提出了一种面到面的icp。 论文原文:《Generalized-ICP》 在概率模型中假设存在配准中两个点集, A ^ = { a i ^ } hat{A}=left{hat{a_{i}}right} A ^ = { a i ​

    2024年01月19日
    浏览(54)
  • 使用PCL库中PPF+ICP进行点云目标识别

    在使用过程中踩到的坑:    (1):PointCloudPPFSignature::Ptr cloud_model_ppf(new PointCloudPPFSignature());     PPFEstimationPointNormal, PointNormal, PPFSignature ppf_estimator;     ppf_estimator.setInputCloud(cloud_model_input);     ppf_estimator.setInputNormals(cloud_model_input);     ppf_estimator.compute(*cloud_model_ppf); 运行到

    2024年02月15日
    浏览(70)
  • Open3D点云库(0.16.0)安装配置(Python版本)

    Open3D是一个开源的点云和网格处理库,它支持快速开发处理3D数据的软件。Open3D前端在c++和Python中公开了一组精心挑选的数据结构和算法;后端则是经过高度优化,并设置为并行化。它只需要很少的工作就可以在不同的平台上进行布置,并从源代码编译。它的优秀毋庸置疑,

    2024年02月14日
    浏览(49)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包