PCL点云库——点云法线估计

点云法线估计


  PCL中的所有点云的法线都是指向视点的,视点坐标默认为(0,0,0),对视点进行设置,则可对法线进行定向。如图1与图2所示,分别为斯坦福兔子在视点坐标为(10,10,10)与(-10,-10,-10)时的法线显示情况。
PCL点云库——点云法线估计_第1张图片

图1 视点坐标为(10,10,10)时的法线显示
PCL点云库——点云法线估计_第2张图片
图2 视点坐标为(-10,-10,-10)时的法线显示

  法线估计代码如下:

#include 
#include 
#include 
#include 
#include 
#include //CString头文件
using namespace std;

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

	pcl::NormalEstimationOMP<pcl::PointXYZ, pcl::Normal> ne;//创建法线估计向量
	ne.setNumberOfThreads(omp_get_max_threads());
	ne.setInputCloud(cloud);	
	pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>());//创建一个空的KdTree对象,并把它传递给法线估计向量,基于给出的输入数据集,KdTree将被建立
	ne.setSearchMethod(tree);
	ne.setViewPoint(10, 10, 10);//设置视点,官网上的pcl::flipNormalTowardsViewpoint (const PointT &point, float vp_x, float vp_y, float vp_z, Eigen::Vector4f &normal)是对“一个已知点”的法线进行手动定向
	//ne.setViewPoint(-10, -10, -10);
	pcl::PointCloud<pcl::Normal>::Ptr cloud_normals(new pcl::PointCloud<pcl::Normal>);//存储输出数据
	//ne.setRadiusSearch(1);        //半径单位为毫米
	ne.setKSearch(20);
	ne.compute(*cloud_normals);
	
	//保存具有法线信息的点云文件
	CString strFilePath(_T("D:\\Desktop\\点云法线.pcd"));//将文件保存在电脑桌面上(作者的桌面是在D盘中,这是可以设置的,百度一下就知道了!)
	string saveFileName = CStringA(strFilePath);
	pcl::PCDWriter savePCDFile;
	savePCDFile.write(saveFileName, *cloud_normals);

	//可视化
	boost::shared_ptr<pcl::visualization::PCLVisualizer> m_viewer(new pcl::visualization::PCLVisualizer());

	int v1(0);
	m_viewer->createViewPort(0.0, 0.0, 0.5, 1.0, v1);
	m_viewer->addCoordinateSystem(0.1, v1);
	m_viewer->setBackgroundColor(128.0 / 255.0, 138.0 / 255.0, 135.0 / 255.0, v1);
	pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> color(cloud, 0, 255, 0);
	m_viewer->addPointCloud(cloud, color, "cloud1", v1);

	int v2(0);
	m_viewer->createViewPort(0.5, 0.0, 1.0, 1.0, v2);
	m_viewer->addCoordinateSystem(0.1, v2);
	m_viewer->setBackgroundColor(128.0 / 255.0, 138.0 / 255.0, 135.0 / 255.0, v2);
	//显示点云及其法线
	pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> Cap_Cloud_Point(cloud, 255, 0, 0);
	m_viewer->addPointCloud(cloud, Cap_Cloud_Point, "cloud2", v2);
	m_viewer->addPointCloudNormals<pcl::PointXYZ, pcl::Normal>(cloud, cloud_normals, 2, 0.01, "normals", v2); //显示点云法线,第三个参数是法线显示的个数(每2个点显示1个),第四个参数是法线的长度(此处为0.01)
	while (!m_viewer->wasStopped())
	{
		m_viewer->spinOnce(100);
		boost::this_thread::sleep(boost::posix_time::microseconds(100000));
	}
	return 0;
}

你可能感兴趣的:(PCL,点云,c++)