Table of contents
1.4.1 Steps to add custom points
1.1 Introduction
Source: PCL (Point Cloud Library)_Baidu Encyclopedia
PCL (Point Cloud Library) is a large cross-platform open source C++ programming library built on the basis of previous point cloud-related research. It implements a large number of point cloud-related general algorithms and efficient data structures, involving point cloud acquisition, Filtering, segmentation, registration, retrieval, feature extraction, recognition, tracking, surface reconstruction, visualization, etc. It supports multiple operating system platforms and can run on Windows, Linux, Android, Mac OS X, and some embedded real-time systems. If OpenCV is the crystallization of 2D information acquisition and processing, then PCL has the same status in 3D information acquisition and processing.
As shown in the "PCL Architecture Diagram", for 3D point cloud processing, PCL is a completely modular modern C++ template library. It is based on the following third-party libraries: Boost, Eigen, FLANN, VTK, CUDA, OpenNI, Qhull, and implements point cloud-related acquisition, filtering, segmentation, registration, retrieval, feature extraction, recognition, tracking, surface reconstruction, visualization, etc.
1.2 PCL installation
1.2.1 Installation method
Installation link: Install pcl_ubuntu under ubuntu20.04 Install pcl_Yuannau_jk's blog-CSDN blog
1.2.2 Test procedure
cmake_minimum_required(VERSION 2.6)
project(pcl_test)
find_package(PCL 1.10 REQUIRED)
include_directories(${PCL_INCLUDE_DIRS})
link_directories(${PCL_LIBRARY_DIRS})
add_definitions(${PCL_DEFINITIONS})
add_executable(pcl_test pcl_test.cpp)
target_link_libraries (pcl_test ${PCL_LIBRARIES})
install(TARGETS pcl_test RUNTIME DESTINATION bin)
#include <iostream>
#include <pcl/common/common_headers.h>
#include <pcl/io/pcd_io.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/visualization/cloud_viewer.h>
#include <pcl/console/parse.h>
int main(int argc, char **argv) {
std::cout << "Test PCL !!!" << std::endl;
pcl::PointCloud<pcl::PointXYZRGB>::Ptr point_cloud_ptr (new pcl::PointCloud<pcl::PointXYZRGB>);
uint8_t r(255), g(15), b(15);
for (float z(-1.0); z <= 1.0; z += 0.05)
{
for (float angle(0.0); angle <= 360.0; angle += 5.0)
{
pcl::PointXYZRGB point;
point.x = 0.5 * cosf (pcl::deg2rad(angle));
point.y = sinf (pcl::deg2rad(angle));
point.z = z;
uint32_t rgb = (static_cast<uint32_t>(r) << 16 |
static_cast<uint32_t>(g) << 8 | static_cast<uint32_t>(b));
point.rgb = *reinterpret_cast<float*>(&rgb);
point_cloud_ptr->points.push_back (point);
}
if (z < 0.0)
{
r -= 12;
g += 12;
}
else
{
g -= 12;
b += 12;
}
}
point_cloud_ptr->width = (int) point_cloud_ptr->points.size ();
point_cloud_ptr->height = 1;
pcl::visualization::CloudViewer viewer ("test");
viewer.showCloud(point_cloud_ptr);
while (!viewer.wasStopped()){ };
return 0;
}
1.3 PCL data type
All built-in point cloud types are included in the header file #include <pcl/point_types.h> , some of which are as follows:
namespace pcl
{
/** \brief Members: float x, y, z
* \ingroup common
*/
struct PointXYZ;
/** \brief Members: rgba
* \ingroup common
*/
struct RGB;
/** \brief Members: intensity (float)
* \ingroup common
*/
struct Intensity;
/** \brief Members: intensity (std::uint8_t)
* \ingroup common
*/
struct Intensity8u;
/** \brief Members: intensity (std::uint32_t)
* \ingroup common
*/
struct Intensity32u;
/** \brief Members: float x, y, z, intensity
* \ingroup common
*/
struct PointXYZI;
/** \brief Members: float x, y, z, uin32_t label
* \ingroup common
*/
struct PointXYZL;
/** \brief Members: std::uint32_t label
* \ingroup common
*/
...
}
(1) PointXYZ-member variable: float x, y, z
PointXYZ is the most commonly used point data type because it only contains three-dimensional xyz coordinate information. These three floating point numbers are appended with a floating point number to meet storage alignment. Users can use points[i].data[0], or points [i].xThe x coordinate value of the access point.
(2) PointXYZI-member variable: float x,y,z,intensity
Point is a simple point type with XYZ coordinates plus intensity. xyz and intensity are not in the same structure . Specifically, xyz is located in a structure, memory aligned, and intensity is located in another structure, memory aligned (filled with 3 floating point numbers).
(3) PointXYZRGBA-member variable: float x,y,z,uint32_t rgba
rgba is contained in an integer variable, and the rest is similar to the PointXYZI structure.
(4) PointXYZRGB-member variable: float x,y,z,rgb
The rgb information is contained in a floating point variable, and the rest is similar to the PointXYZI structure.
(5)InterestPoint-float x,y,z,strength
Strength is used to represent the intensity measurement value of the key point, and the rest is similar to the PointXYZI structure.
(6)Normal-float normal[3], curvature
The Norma structure represents the normal direction of the sample surface where a given point is located, and the measurement of the corresponding curvature.
(7)PointNormal-float x,y,z,normal[3], curvature
PointNormal is a point structure that stores XYZ data, and includes the normal and curvature corresponding to the sampling point.
(8)PointXYZRGBNormal-float x,y,z,rgb,normal[3], curvature
PointXYZNormal is a point structure that stores XYZ data and RGB colors, and includes sample point surface normals and curvature.
(9)PointXYZINormal-float x,y,z,intensity,normal[3], curvature
PointXYZNormal is a point structure that stores XYZ data and intensity values, and includes the sampling point surface normal and curvature.
(10)PointWithRange-float x,y,z(union with float point[4], range)
PointWithRange is similar to the PointXYZI structure except that the range contains the distance measurement from the obtained viewpoint to the sample point.
(11)PointWithViewpoint-float x,y,z,vp_x,vp_y,vp_z
PointWithViewpoint has a similar structure to PointXYZI except that vp_x, vp_y, and vp_z represent the obtained viewpoint as three-dimensional points.
(12)MomentInvariantst-float j1,j2,j3
The MomentInvariants field of view also includes the point type of the three invariant moments of the patch on the sampling surface, describing the distribution of the top belt on the patch.
(13)PrincipalRadiiRSD-float r_min,r_max
PrincipalRadiiRSD is a point type containing two RSD radii on the surface patch.
(14)Boundary-uint_8 boundary_point
Boundary is a simple point type that stores whether a point is located on the boundary of the surface.
(15)PrincipalCurvatures-float principal_curvature[3],pc1,pc2
PrincipalCurvatures A simple point type containing the principal curvature of a given point.
(16)PFHSignature125-float pfh[125]
PFHSignature125 A simple point type containing the PFH (Point Feature Histogram) of a given point.
(17)FPFHSignature33-float pfh[33]
FPFHSignature33 A simple point type containing the FPFH (Fast Point Feature Histogram) for a given point.
(18)VFHSignature308-float vfh[308]
VFHSignature308 A simple point type containing the VFH (viewpoint feature histogram) of a given point.
(19)Narf36-float x,y,z,rool,pitch,yaw;fooat descriptor[36]
Narf36 contains a simple point type for a given point NARF (Normalized Alignment Radius Feature).
(20)BorderDescription-int x,y; BorderTraits traits
BorderDescription contains a simple point type for a given point border type.
(21)IntensityGradient-float gradient[3]
IntensityGradient contains the gradient point type for the given point intensity.
(22)Histogram-float histogram[N]
Histogram is used to store general-purpose n-dimensional histograms.
(23)PointWithScale-float x,y,z,scale
PointWithScale is similar to the PointXYZI structure except that scale represents the scale of a certain point for geometric operations.
(24)PointSufel-float x,y,z,normal[3],rgba,radius,confidence,curvature
PointSufel stores XYZ coordinates, surface normals, RGB information, radius, confidence level, and complex point types of surface curvature.
1.4 Custom point type in PCL
1.4.1 Steps to add custom points
(1) First define the structure
// 定义点类型结构
struct EIGEN_ALIGN16 MyPoint
{
PCL_ADD_POINT4D // 点类型有4个元素 XYZ+padding
PCL_ADD_RGB //加颜色
double time_stamp; //时间戳
EIGEN_MAKE_ALIGNED_OPERATOR_NEW // 确保new操作符对齐操作
};
(2) Register in the PCL library
// 注册到PCL库
POINT_CLOUD_REGISTER_POINT_STRUCT(MyPoint, //注册的结构类型
(float, x, x) //坐标
(float, y, y)
(float, z, z)
(uint32_t,rgba,rgba) //颜色
(double, time_stamp, time_stamp) //时间戳
);
1.4.2 Complete code
(1) Customized point cloud type program
cmake_minimum_required(VERSION 2.6)
project(mypoint)
find_package(PCL 1.10 REQUIRED)
include_directories(${PCL_INCLUDE_DIRS})
link_directories(${PCL_LIBRARY_DIRS})
add_definitions(${PCL_DEFINITIONS})
add_executable(pcl_test pcl_test.cpp)
target_link_libraries (pcl_test ${PCL_LIBRARIES})
install(TARGETS pcl_test RUNTIME DESTINATION bin)
// 方式一:直接写在mypoint.cpp中
#define PCL_NO_PRECOMPILE
#include <iostream>
#include <chrono>
#include <pcl/point_cloud.h>
#include <pcl/io/pcd_io.h>
#include <pcl/visualization/cloud_viewer.h>
#include <pcl/PCLPointCloud2.h>
#include <pcl/visualization/pcl_visualizer.h>
using namespace std;
// 定义点类型结构
struct EIGEN_ALIGN16 MyPoint
{
PCL_ADD_POINT4D // 点类型有4个元素 XYZ+padding
PCL_ADD_RGB //加颜色
double time_stamp; //时间戳
EIGEN_MAKE_ALIGNED_OPERATOR_NEW // 确保new操作符对齐操作
};
// 注册到PCL库
POINT_CLOUD_REGISTER_POINT_STRUCT(MyPoint, //注册的结构类型
(float, x, x) //坐标
(float, y, y)
(float, z, z)
(uint32_t,rgba,rgba) //颜色
(double, time_stamp, time_stamp) //时间戳
);
double getTimeStamp()
{
auto timeNow = chrono::duration_cast<chrono::milliseconds>(chrono::system_clock::now().time_since_epoch());
return timeNow.count()/1000.0;
}
int main(int argc, char *argv[])
{
pcl::PointCloud<MyPoint>::Ptr cloud;
cloud.reset(new pcl::PointCloud<MyPoint>);
cloud->width = 100;
cloud->height = 1;
cloud->is_dense = false;
cloud->points.resize(100);
for(auto i = 0; i < 100; i++)
{
// xyz
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);
// rgb
cloud->points[i].r = 1024 * rand() / (256);
cloud->points[i].g = 1024 * rand() / (256);
cloud->points[i].b = 1024 * rand() / (256);
cloud->points[i].time_stamp = getTimeStamp();
}
pcl::io::savePCDFile("mypoint.pcd",*cloud);
// to show
#if 0
pcl::visualization::CloudViewer viewer("Cloud Viewer");
viewer.showCloud<MyPoint>(cloud);
#else
pcl::visualization::PCLVisualizer::Ptr viewer(new pcl::visualization::PCLVisualizer(renderer, renderWindow, "viewer", false));
viewer->addPointCloud<MyPoint>(cloud,color);
viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 4);
while (!viewer.wasStopped ())
{
viewer->spinOnce(100);
}
#endif
return 0;
}
(2) Header file encapsulation
// 方式二:独立的头文件
#ifndef MYPOINT_H
#define MYPOINT_H
#include<pcl/point_types.h>
namespace MYPOINT {
struct EIGEN_ALIGN16 _MYPOINT
{
PCL_ADD_POINT4D
PCL_ADD_RGB
double time_stamp;
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
struct EIGEN_ALIGN16 MYPOINT : public _MYPOINT
{
inline MYPOINT (const _MYPOINT &p)
{
x = p.x; y = p.y; z = p.z; data[3] = 1.0f;
rgba = p.rgba;
a = 0;
time_stamp = p.time_stamp;
}
inline MYPOINT ()
{
x = y = z = 0.0f;
rgba = 0;
data[3] = 1.0f;
time_stamp = 0;
}
inline MYPOINT (float _x, float _y, float _z, uint32_t _rgb,double _time_stamp)
{
x = _x; y = _y; z = _z;
rgba = _rgb;
data[3] = 1.0f;
time_stamp = _time_stamp;
}
friend std::ostream& operator << (std::ostream& os, const MYPOINT& p)
{
os << "(" << p.x << "," << p.y << "," << p.z << "," << p.rgba << ","<< p.time_stamp << ")";
return os;
}
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
}
POINT_CLOUD_REGISTER_POINT_STRUCT(MYPOINT::MYPOINT,
(float, x, x)
(float, y, y)
(float, z, z)
(uint32_t,rgb,rgb)
(double, time_stamp, time_stamp)
);
#endif