PCL point cloud library (1) — Introduction and data types

Table of contents

1.1 Introduction

1.2 PCL installation

1.2.1 Installation method

1.2.2 Test procedure 

1.3 PCL data type

1.4 Custom point type in PCL

1.4.1 Steps to add custom points

1.4.2 Complete code


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

Guess you like

Origin blog.csdn.net/qq_41921826/article/details/130061851