点云中绘制各种形状

bool pcl::visualization addCylinder(const pcl::ModelCoefficients & coefficients, const std::string &id="cylinder", int viewport): 从一组给定的系数中添加一个圆柱体;----需要7个值。

bool pcl::visualization addLine(const pcl::ModelCoefficients &coeffficients, const std::string &id="line", int viewport): 通过给定的系数添加一条直线(注意使用该方式添加的是直线而不是线段)。------需要6个值。

bool pcl::visualization addCube(const pcl::ModelCoefficients &coefficients, const std::string &id="cube", int viewport):通过给定的一组系数添加一个立方体。------需要几个10个参数。

bool pcl::visualization addCone(const pcl::ModelCoefficients &coefficients,const std::string &id="cone",int viewport):通过给定的一组系数添加一个圆锥体。------需要7个系数,顶点apex,决定锥体高度的一个点,一个弧度制的角度。

bool pcl::visualization addLine(const pcl::Modelcoefficients &coefficients, const std::string &id="plane",int viewpoit):通过给定的一组系数(4个)确定一个平面。

bool pcl::visualization addCircle(const pcl::Modelcoefficients &coefficients,const std::string &id="circle",int viewport):通过给定系数 x,y,radius(3个系数)绘制圆。

许多绘制形状的函数都会采用pcl::ModelCoefficients结构定义系数的方法来定义形状。关于ModelCoefficients结构的定义位于ModelCoefficients.h头文件中,其定义如下代码所示。成员变量主要是:一个PCLHearer类对象,一个vector对象value用来存储定义形状的系数。

namespace pcl{
......
struct ModelCoefficients
  {
    ModelCoefficients ()
    {
    }

    ::pcl::PCLHeader header;

    std::vector<float> values;

  public:
    using Ptr = shared_ptr< ::pcl::ModelCoefficients>;
    using ConstPtr = shared_ptr<const ::pcl::ModelCoefficients>;
  }; // struct ModelCoefficients
......
}

 在使用ModelCoefficients定义直线系数学习过程遇到的一个问题就是对于如下的两个重载函数,第一个函数addLine输入参数分别是线段的起始点,线段的终点,最终绘制出的效果就是起始点---终点的连线的线段;但是以Modelcoefficients形状系数作为参数的addLine函数如果也使用相同的点作为输入的话,绘制的不是线段而是一条线,具体该线的方向的方向是如何定义的还没有搞明白。综上所述,pcl::visualization::addLine()4个重载函数中,使用两点作为输入参数的是用来绘制线段的,使用pcl::Modelcoefficients来传参数的是用来绘制过某个点沿着某个方向的直线的。验证程序如下:

bool pcl::addLine(const P1& p1,const P2& p2,const std::string & id="line", int viewport);

bool pcl::visualization addLine(const pcl::Modelcoefficients &coefficients, const std::string &id="plane",int viewpoit)

#include<pcl/point_types.h>
#include<pcl/visualization/cloud_viewer.h>
#include<pcl/common/common_headers.h>
#include<pcl/features/normal_3d.h>
#include<iostream>

using namespace std;

int main(int argc, char** argv)
{
	//创建点云
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloudXYZ(new(pcl::PointCloud<pcl::PointXYZ>));
	pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloudXYZRGB(new(pcl::PointCloud<pcl::PointXYZRGB>));

	pcl::PointXYZ point;
	pcl::PointXYZRGB pointrgb;
	uint8_t r(255), g(15), b(15);
	int i = 0;
	for (float z = -1; z <= 1; z += 0.05)
	{
		for (double angle = 0; angle <= 360.0; angle += 5.0)
		{
			point.x = cos(pcl::deg2rad(angle));
			point.y = sin(pcl::deg2rad(angle));
			point.z = z;
			cloudXYZ->points.push_back(point);

			uint32_t rgb = static_cast<uint32_t>(r << 16) | static_cast<uint32_t>(g << 8) | static_cast<uint32_t>(b);
			float k = *reinterpret_cast<float*>(&rgb);
			pointrgb.x = cos(pcl::deg2rad(angle));
			pointrgb.y = sin(pcl::deg2rad(angle));
			pointrgb.z = z;
			pointrgb.rgb = k;
			cloudXYZRGB->points.push_back(pointrgb);
		}
		if (z < 0)
		{
			r -= 12;
			g += 12;
		}
		else
		{
			g -= 12;
			b += 12;
		}
	}

	//局部法线估计
	pcl::PointCloud<pcl::Normal>::Ptr normals(new(pcl::PointCloud<pcl::Normal>));
	pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal>ne;
	pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new(pcl::search::KdTree<pcl::PointXYZ>));
	ne.setSearchMethod(tree);
	ne.setInputCloud(cloudXYZ);
	ne.setKSearch(5);
	ne.compute(*normals);



	pcl::visualization::PCLVisualizer viewer("3D Viewer");
	
	int v1(0);
	viewer.createViewPort(0, 0, 0.5, 1, v1);
	viewer.setBackgroundColor(0, 0, 0, v1);
	viewer.addPointCloud(cloudXYZ, "cloud1", v1);
	//viewer.addPointCloudNormals<pcl::PointXYZ, pcl::Normal>(cloudXYZ, normals, 10, 0.02, "normals", v1);
	viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 4.0, "cloud1", v1);
	viewer.addCoordinateSystem(0.5, 0, 0, 0, "coordinatesystem1", v1);
	viewer.addText("viewer1", 10, 10, "text1", v1);

	//为第一个圆柱添加直线
	viewer.addLine(cloudXYZ->points[0], cloudXYZ->points[cloudXYZ->size() - 1], 1, 0, 0, "line0", v1);
	cout << "第一个视窗圆柱第一个点与最后一个点坐标:" << endl;
	cout << cloudXYZ->points[0] << endl;
	cout << cloudXYZ->points[cloudXYZ->size()-1] << endl;

	int v2(0);
	viewer.createViewPort(0.5, 0, 1, 1, v2);
	viewer.setBackgroundColor(0, 0, 0, v2);
	viewer.addPointCloud(cloudXYZRGB, "cloud2", v2);
	viewer.addCoordinateSystem(0.5,0,0,0, "coordinatesystem2", v2);
	viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 4, "cloud2", v2);
	viewer.addText("viewer2", 10, 10, "text2", v2);

	//为第二个圆柱添加直线
	pcl::ModelCoefficients line1;
	//line.values.resize(6);
	line1.values.push_back(cloudXYZRGB->points[0].x);
	line1.values.push_back(cloudXYZRGB->points[0].y);
	line1.values.push_back(cloudXYZRGB->points[0].z);
	line1.values.push_back(cloudXYZRGB->points[cloudXYZRGB->size() - 1].x);
	line1.values.push_back(cloudXYZRGB->points[cloudXYZRGB->size() - 1].y);
	line1.values.push_back(cloudXYZRGB->points[cloudXYZRGB->size() - 1].z);
	//line.values[0] = cloudXYZRGB->points[0].x;
	//line.values[1] = cloudXYZRGB->points[0].y;
	//line.values[2] = cloudXYZRGB->points[0].z;
	//line.values[3] = cloudXYZRGB->points[cloudXYZRGB->size() - 1].x;
	//line.values[4] = cloudXYZRGB->points[cloudXYZRGB->size() - 1].y;
	//line.values[5] = cloudXYZRGB->points[cloudXYZRGB->size() - 1].z;
	viewer.addLine(line1, "line1", v2);


	cout << "第二个视窗圆柱第一个点与最后一个点坐标:" << endl;
	cout << cloudXYZRGB->points[0] << endl;
	cout << cloudXYZRGB->points[cloudXYZRGB->size() - 1] << endl;
	while (!viewer.wasStopped())
	{
		viewer.spinOnce();
	}
	return 0;
}

结果中显示,使用addLine(point1,point2,......)函数绘制的线就是起始点到终点的连线,而使用addLine(pcl::Modelcoefficients &coefficients,.....)函数绘制出的直线并不是我们所想的 起始点到终点的连线。后续查看内存中的起点,终点坐标确实都是相同的。所以使用Modelcoefficients作为输入参数的函数addLine的作用是干什么的还没有搞清楚。

 

 

 

举例:添加一个立方体形状

bool pcl::visualization addCube(const pcl::ModelCoefficients &coefficients, const std::string &id="cube", int viewport):通过给定的一组系数添加一个立方体。------需要几个10个参数。

bool pcl::visualization addCube(const Eigen::Vector3f translation,const Eigen::Quaternionf & rotation,double width,double height,double depth, const std::string &id="cube", int viewport)

以上两个函数的功能是相同的,只是参数输入方式不同,但是参数所表达的含义也是相同的,transilation是相对于坐标原点(0,0,0)的平移量(平移向量),如果创建一个立方体,中心位置是(1,1,1),Vector3f  translation(1,1,1)。Quaternion:旋转向量,是一个4元组(quaternion)。

实验结果:

......
Eigen::Vector3f center1(0, 1, 0);
Eigen::Quaternionf rotation1(1, 1, 1, 0);
viewer.addCube(center1, rotation1, 0.5, 0.5, 0.5, "cube1", v1);
......
Eigen::Vector3f center(0, 1, 0);
Eigen::Quaternionf rotation(0, 0, 0, 0);
viewer.addCube(center,rotation,0.5,0.5,0.5,"cube",v2);
......

 

 -------------------------------------------------------------------------------------------------------------------------------有不当之处恳请大家批评指正!

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值