PCL教程笔记(一)法向量特征

内容主要来自于PCL官方教程、3d特征法向量。
PCL教程大多在linux系统实现,所以在windows下需要改编。
作者认为3D特征,最起码应该有3个特性:
1.刚体变换。也就是说该特征应当具有3D变换不变性。
2.采样密度。不受传感器采样密度限制。
3.抗噪音。

以3D特征中的法向量为例,写了一段程序。
法向量是几何渲染中的重要特征,一般会结合光照方向和视点,达到镜面反射、漫反射等的效果。如果对opengl有所了解,就知道没有法向量就无法完成光照渲染。opengl并没有提供关于法向量的计算,但PCL提供了计算法向量的算法,所以两者通常搭配使用,实现点云光照渲染。

主要方法是结合PCA方法的最小二乘法,也就是主成分分析,是一种降维和降噪方法,主要保留一些协方差较大的分量,并建立另一个相互正交的坐标系,来表示当前特征。
那为什么保留协方差较大的分量呢?测试技术中,通常认为方差小的是噪音,大的是信号。

#include "pch.h"
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
VTK_MODULE_INIT(vtkRenderingOpenGL);

int main()
{
	// load point cloud
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
	pcl::io::loadPCDFile("table_scene_mug_stereo_textured.pcd", *cloud);

	// estimate normals
	pcl::PointCloud<pcl::Normal>::Ptr normals(new pcl::PointCloud<pcl::Normal>);

	pcl::IntegralImageNormalEstimation<pcl::PointXYZ, pcl::Normal> ne;
	ne.setNormalEstimationMethod(ne.AVERAGE_3D_GRADIENT);
	ne.setMaxDepthChangeFactor(0.02f);
	ne.setNormalSmoothingSize(10.0f);
	ne.setInputCloud(cloud);
	ne.compute(*normals);

	pcl::visualization::PointCloudColorHandlerGenericField<pcl::PointXYZ> fildColor(cloud, "z"); // 按照z字段进行渲染
	
	// visualize normals
	pcl::visualization::PCLVisualizer viewer("PCL Viewer");
	viewer.setBackgroundColor(0.0, 0.0, 0.5);
	viewer.addPointCloudNormals<pcl::PointXYZ, pcl::Normal>(cloud, normals);
	//viewer.addPointCloud(cloud, "sample cloud");
	viewer.addPointCloud<pcl::PointXYZ>(cloud, fildColor, "1");
	viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 10, "1");
	
	while (!viewer.wasStopped())
	{
		viewer.spinOnce();
	}
	return 0;
}

PCL教程笔记(一)法向量特征_第1张图片
需要注意三点问题:
第一点是报错问题,需要再源代码基础上加上
#include
VTK_MODULE_INIT(vtkRenderingOpenGL);

第二点是法向计算,只计算有组织点云,也就是height不为1的点云。

第三点是调用函数
addPointCloudpcl::PointXYZ(cloud, fildColor, “1”);
PCL库会在内部为其设置一个名叫1的点云块。
下次调用时,直接调用这个名叫1的点云块就可以。比如:
viewer.addPointCloudpcl::PointXYZ(cloud, fildColor, “1”);
viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 10, “1”);
先存了一个叫做1的点云块,然后调用了函数设置了这块点云的点大小。

其中提及的Z渲染不重要,不过是为点云块赋色,所以没有详细说明。

你可能感兴趣的:(图像处理,激光雷达)