利用PCL處理Realsense點雲數據-顯示點雲法線方向及出現問題的解決

在我們獲得點雲數據後,爲了能夠進行表面重建或者是進行物體的位姿確定,我們都需要確定物體表面的發現方向。

PCL中有現成的計算物體法線的類NormalEstimation,這個類做了以下3件事

1.得到p的最近鄰

2.計算p的表面法線n

3.檢查法線的朝向,然後撥亂反正。

默認的視角是(0,0,0)

計算一個點的法線

computePointNormal (const pcl::PointCloud<PointInT> &cloud, const std::vector<int> &indices, Eigen::Vector4f &plane_parameters, float &curvature);

前面兩個參數很好理解,plane_parameters包含了4個參數,前面三個是法線的(nx,ny,nz)座標,加上一個 nc .p_plane (centroid here) + p的座標,然後最後一個參數是曲率。

#include <iostream>
#include <pcl/visualization/cloud_viewer.h>
#include<pcl/io/pcd_io.h>
#include<pcl/point_types.h>
#include <pcl/conversions.h>
#include <pcl/features/normal_3d.h>
#include <boost/thread/thread.hpp>
#include <pcl/common/common_headers.h>
#include <pcl/filters/voxel_grid.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/console/parse.h>
#include <pcl/filters/statistical_outlier_removal.h>

int main()
{

	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_old(new pcl::PointCloud<pcl::PointXYZ>);
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_downsampled(new pcl::PointCloud<pcl::PointXYZ>);
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
	pcl::io::loadPCDFile("test_pcd.pcd", *cloud_old);

	//Use a voxelSampler to downsample
	pcl::VoxelGrid<pcl::PointXYZ> voxelSampler;
	voxelSampler.setInputCloud(cloud_old);
	voxelSampler.setLeafSize(0.01f, 0.01f, 0.01f);
	voxelSampler.filter(*cloud_downsampled);

	//Use a filter to reduce noise
	pcl::StatisticalOutlierRemoval<pcl::PointXYZ> statFilter;
	statFilter.setInputCloud(cloud_downsampled);
	statFilter.setMeanK(10);
	statFilter.setStddevMulThresh(0.2);
	statFilter.filter(*cloud);

	// Create the normal estimation class, and pass the input dataset to it
	pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> ne;
	ne.setInputCloud(cloud);

	// Create an empty kdtree representation, and pass it to the normal estimation object.
	// Its content will be filled inside the object, based on the given input dataset (as no other search surface is given).
	pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>());
	ne.setSearchMethod(tree);

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

	// Use all neighbors in a sphere of radius 1cm


	ne.setRadiusSearch(0.01);
	// Compute the features
	ne.compute(*normals);

	boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("3D Viewer"));
	viewer->setBackgroundColor(0, 0, 0);

	viewer->addPointCloud<pcl::PointXYZ>(cloud, "sample cloud");
	viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "sample cloud");
	viewer->addPointCloudNormals<pcl::PointXYZ, pcl::Normal>(cloud, normals, 10, 0.2, "normals");
	viewer->addCoordinateSystem(1.0);
	viewer->initCameraParameters();
	while (!viewer->wasStopped())
	{
		viewer->spinOnce(100);
		boost::this_thread::sleep(boost::posix_time::microseconds(100000));
	}
	return 0;
}

但是第一次運行時出現了這樣的問題,no ovverride found for vtkactor,解決這個問題其實很簡單,首先加上#include <vtkAutoInit.h>  

然後在mian的第一行加上VTK_MODULE_INIT(vtkRenderingOpenGL);  就沒有問題了。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章