PCL creates a cylindrical point cloud

PCL creates point clouds of various shapes

Chapter 1 PCL Creates Line Segment Point Cloud



foreword

Point Cloud Library (PCL) is an independent, large-scale, open 2D/3D image and point cloud processing project. PCL is powerful, but it does not include the function of creating point clouds, especially some common point clouds, such as: line segments, balls, cubes, cylindrical surfaces, etc., but only includes some common geometric shapes in the visualization class, such as : Line segments, balls, cubes, etc. cannot be passed as point cloud data, so I plan to write it myself. This article is about the creation of cylindrical point clouds.
insert image description here


1. What is a cylindrical surface?

Example: a cylinder is a curved surface formed by parallel movement of a straight line along a fixed curve, that is, a curved surface formed by a moving straight line moving parallelly along a fixed curve. The moving straight line is called the straight generatrix of the cylinder, and the fixed curve is called The alignment of the cylinder. When the directrix is ​​a circle, the resulting cylinder is called 圆柱面, as shown in the figure. When known 圆柱面轴线上的一点、轴线向量和半径(7-dimensional data), a cylindrical surface can be determined, which is also the method of defining a cylindrical surface in PCL.

insert image description here

2. Steps of creating a cylindrical surface point cloud

1. Import library

For PCL environment configuration, please refer to: Configure PCL (debug and release) in 5 minutes under Windows system

code show as below:

#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/common/transforms.h>
#include <pcl/ModelCoefficients.h>

2. Create a cylindrical point cloud

  1. Check whether the input cylindrical surface parameters are legal
  2. First create a cylindrical surface with the center point as the origin and the axis vector as the Z axis
  3. Perform rigid transformation on the cylindrical surface, and transform the rotation and translation to the set parameters
  4. visual verification

The key function code is as follows

//根据圆柱面参数创建空间任意圆柱面点云
//param[in]  pcl::ModelCoefficients::Ptr& coefficients_cylinder://圆柱面参数:系数0、1、2代表圆柱轴线上的原点,3、4、5代表这条轴线的方向向量,系数6就是圆柱的半径。
//param[in] valization:默认可视化
//param[out] cloud:PCD格式的点云文件
void CreatCylinder(pcl::ModelCoefficients::Ptr& coefficients_cylinder, pcl::PointCloud<pcl::PointXYZ>::Ptr& cloud, bool valization = true) {
    
    
	//检查参数
	if (coefficients_cylinder->values.size() != 7) {
    
    
		std::cerr << "参数数目错误。。。" << std::endl;
		system("pause");
	}
	if(coefficients_cylinder->values[6]<=0){
    
    
	    std::cerr << "圆柱面半径不能小于等于0" << std::endl;
		system("pause");
	}
	//先构建轴线为Z轴的圆柱面点云
	int Num = 1200;
	float inter = 2.0 * M_PI / Num;
	Eigen::RowVectorXd vectorx(Num), vectory(Num), vectorz(Num);
	Eigen::RowVector3d axis(coefficients_cylinder->values[3], coefficients_cylinder->values[4], coefficients_cylinder->values[5]);
	float length = axis.norm();
	vectorx.setLinSpaced(Num, 0, Num - 1);
	vectory = vectorx;
	float x0, y0, z0,r0;
	x0 = coefficients_cylinder->values[0];
	y0 = coefficients_cylinder->values[1];
	z0 = coefficients_cylinder->values[2];
	r0 = coefficients_cylinder->values[6];

	pcl::PointCloud<pcl::PointXYZ>::Ptr cylinder(new pcl::PointCloud<pcl::PointXYZ>);

	for (float z(0.0); z <= length; z += 0.05)
	{
    
    
		for (auto i = 0; i < Num; ++i) {
    
    
			pcl::PointXYZ point;
			point.x = r0 * cos(vectorx[i] * inter);
			point.y = r0 * sin(vectory[i] * inter);
			point.z = z;
			cylinder->points.push_back(point);
		}
	}
	
	cylinder->width = (int)cylinder->size();
	cylinder->height = 1;
	cylinder->is_dense = false;


	//点云旋转 Z轴转到axis
	Eigen::RowVector3d  Z(0.0, 0.0, 0.1), T0(0, 0, 0), T(coefficients_cylinder->values[0], coefficients_cylinder->values[1], coefficients_cylinder->values[2]);
	Eigen::Matrix3d R;
	Eigen::Matrix3d E = Eigen::MatrixXd::Identity(3, 3);
	Eigen::Matrix4d Rotate,Translation;
	R = Eigen::Quaterniond::FromTwoVectors(Z, axis).toRotationMatrix();
	Rotate.setIdentity();
	Translation.setIdentity();

	//旋转
	Rotate.block<3, 3>(0, 0) = R;
	Rotate.block<3, 1>(0, 3) = T;
	pcl::transformPointCloud(*cylinder, *cloud, Rotate);
	

	if (valization) {
    
    
		//--------------------------------------可视化--------------------------
		pcl::visualization::PCLVisualizer viewer;
		//创建的点云和直接addcylinder函数创建的圆柱面面片进行必对
		viewer.addPointCloud<pcl::PointXYZ>(cloud, "cloud1");
		viewer.addCylinder(*coefficients_cylinder, "cylinder");
		viewer.addCoordinateSystem();
		while (!viewer.wasStopped())
		{
    
    
			viewer.spinOnce(100);
		}
	}
}

The main function code is as follows

int main()
{
    
    
	pcl::ModelCoefficients::Ptr cylinder(new pcl::ModelCoefficients);
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
	cylinder->values.resize(7);
	//随便设置参数
	cylinder->values[0] = 1;
	cylinder->values[1] = 2;
	cylinder->values[2] = 3;
	cylinder->values[3] = 4;
	cylinder->values[4] = 5;
	cylinder->values[5] = 6;
	cylinder->values[6] = 7;
	CreatCylinder(cylinder, cloud);
	//点云写入磁盘
	//pcl::io::savePCDFile("cylinder.pcd", *cloud);
	return 0;
}

The visualization result is shown in the figure.
insert image description here
It can be seen that the created cylindrical point cloud and the patch created by the addcylinder() function fit perfectly!


Summarize

As long as the parameter information of the cylindrical surface is known, a matching point cloud can be created. Please indicate the source!

The coefficients 0, 1, and 2 represent the origin on the cylinder axis, 3, 4, and 5 represent the direction vector of this axis, and the coefficient 6 is the radius of the cylinder

Guess you like

Origin blog.csdn.net/Dbojuedzw/article/details/127472475