使用PCL进行法向量可视化
文章目录
- 1、使用PCL进行法向量可视化
- 2、计算所有点的法线并显示
- 3、计算一个子集的法线
1、使用PCL进行法向量可视化
#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <boost/thread/thread.hpp>
using namespace std;
int
main(int argc, char** argv)
{
pcl::PointCloud<pcl::PointNormal>::Ptr cloud(new pcl::PointCloud<pcl::PointNormal>);
if (pcl::io::loadPCDFile<pcl::PointNormal>("bunny.pcd", *cloud) == -1)
{
PCL_ERROR("Could not read file\n");
}
//---------------------可视化(含法线)-----------------------------
boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("CloudCompare-XYZNormal viewer"));
viewer->setWindowName("CloudCompare-XYZNormal");
viewer->addText("CloudCompare-PointNormal", 50, 50, 0, 1, 0, "v1_text");
viewer->addPointCloud<pcl::PointNormal>(cloud, "CloudCompare-XYZNormal");
viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR, 0, 1, 0, "CloudCompare-XYZNormal");
viewer->addPointCloudNormals<pcl::PointNormal>(cloud, 20, 0.02, "normals");
while (!viewer->wasStopped())
{
viewer->spinOnce(100);
boost::this_thread::sleep(boost::posix_time::microseconds(100000));
}
return 0;
}
2、计算所有点的法线并显示
#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/kdtree/kdtree_flann.h>
//#include <pcl/features/normal_3d.h>
#include <pcl/features/normal_3d_omp.h>//使用OMP需要添加的头文件
#include <pcl/visualization/pcl_visualizer.h>
#include <boost/thread/thread.hpp>
using namespace std;
int main()
{
//------------------加载点云数据-------------------
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
if (pcl::io::loadPCDFile<pcl::PointXYZ>("车载点云.pcd", *cloud) == -1)
{
PCL_ERROR("Could not read file\n");
}
//------------------计算法线----------------------
pcl::NormalEstimationOMP<pcl::PointXYZ, pcl::Normal> n;//OMP加速
pcl::PointCloud<pcl::Normal>::Ptr normals(new pcl::PointCloud<pcl::Normal>);
//建立kdtree来进行近邻点集搜索
pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>());
n.setNumberOfThreads(10);//设置openMP的线程数
//n.setViewPoint(0,0,0);//设置视点,默认为(0,0,0)
n.setInputCloud(cloud);
n.setSearchMethod(tree);
n.setKSearch(10);//点云法向计算时,需要所搜的近邻点大小
//n.setRadiusSearch(0.03);//半径搜素
n.compute(*normals);//开始进行法向计
//----------------可视化--------------
boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("Normal viewer"));
//viewer->initCameraParameters();//设置照相机参数,使用户从默认的角度和方向观察点云
//设置背景颜色
viewer->setBackgroundColor(0.3, 0.3, 0.3);
viewer->addText("faxian", 10, 10, "text");
//设置点云颜色
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> single_color(cloud, 0, 225, 0);
//添加坐标系
viewer->addCoordinateSystem(0.1);
viewer->addPointCloud<pcl::PointXYZ>(cloud, single_color, "sample cloud");
//添加需要显示的点云法向。cloud为原始点云模型,normal为法向信息,20表示需要显示法向的点云间隔,即每20个点显示一次法向,0.02表示法向长度。
viewer->addPointCloudNormals<pcl::PointXYZ, pcl::Normal>(cloud, normals, 20, 0.02, "normals");
//设置点云大小
viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 2, "sample cloud");
while (!viewer->wasStopped())
{
viewer->spinOnce(100);
boost::this_thread::sleep(boost::posix_time::microseconds(100000));
}
return 0;
}
3、计算一个子集的法线
#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/kdtree/kdtree_flann.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <boost/thread/thread.hpp>
#include <pcl/features/normal_3d_omp.h>
using namespace std;
int main()
{
//---------------------加载点云数据----------------------
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
if (pcl::io::loadPCDFile<pcl::PointXYZ>("车载点云.pcd", *cloud) == -1)
{
PCL_ERROR("Could not read file\n");
}
//--------------计算云中前10%的点法线-----------------------
vector<int> point_indices(floor(cloud->points.size() / 10));
for (size_t i = 0; i < point_indices.size(); ++i) {
point_indices[i] = i;
}
//-------------------传递索引----------------------------
pcl::IndicesPtr indices(new vector <int>(point_indices));
//-------------------计算法线----------------------------
pcl::NormalEstimationOMP<pcl::PointXYZ, pcl::Normal> n;//OMP加速
n.setInputCloud(cloud);
n.setIndices(indices);
// 创建一个kd树,方便搜索;并将它传递给上面创建的法线估算类对象
pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>());
n.setSearchMethod(tree);
n.setRadiusSearch(0.01);
pcl::PointCloud<pcl::Normal>::Ptr normals(new pcl::PointCloud<pcl::Normal>);
//----------------估算特征---------------
n.compute(*normals);
//-------------为方便可视化,将前10%点云提出-------------------------------
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud1(new pcl::PointCloud<pcl::PointXYZ>);
pcl::copyPointCloud(*cloud, point_indices, *cloud1);
//------------------可视化-----------------------
boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("Normal viewer"));
//设置背景颜色
viewer->setBackgroundColor(0.3, 0.3, 0.3);
viewer->addText("faxian", 10, 10, "text");
//设置点云颜色
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> single_color1(cloud1, 0, 225, 0);
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> single_color(cloud, 255, 0, 0);
//添加坐标系
//viewer->addCoordinateSystem(0.1);
viewer->addPointCloud<pcl::PointXYZ>(cloud, single_color, "sample cloud");
viewer->addPointCloud<pcl::PointXYZ>(cloud1, single_color1, "sample cloud1");
viewer->addPointCloudNormals<pcl::PointXYZ, pcl::Normal>(cloud1, normals, 20, 0.02, "normals");
//设置点云大小
viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 2, "sample cloud1");
while (!viewer->wasStopped())
{
viewer->spinOnce(100);
boost::this_thread::sleep(boost::posix_time::microseconds(100000));
}
return 0;
}