make 只显示error_计算点云法向量并显示

一、法向量定向的理解:

1e67d67295c7cc6e41670b14f3fd20d2.png
ee117aaf5a3379f71aef202de87da4a0.png

二、pcl::Normal的定义

compute(*normal)里计算出来的结果是:法向量的x,y,z坐标和表面曲率curvature。其内部结构为:

 /*brief A point structure representing normal coordinates and the surface curvature estimate. (SSE friendly)ingroup common*/

struct Normal : public _Normal
{
    inline Normal (const _Normal &p){
     normal_x = p.normal_x; 
     normal_y = p.normal_y; 
     normal_z = p.normal_z;
     data_n[3] = 0.0f;
     curvature = p.curvature;
    }

    inline Normal (){
     normal_x = normal_y = normal_z = data_n[3] = 0.0f;
     curvature = 0;
    }

    inline Normal (float n_x, float n_y, float n_z){
     normal_x = n_x; normal_y = n_y; normal_z = n_z;
     curvature = 0;
     data_n[3] = 0.0f;
    }

    friend std::ostream& operator <std::ostream& os, const Normal& p);
    EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};

三、pcl::Normal的几种输出方式:

          cout<points[0]<<endl;cout<<"["<points[0].normal_x<<" "
              <points[0].normal_y<<" "
              <points[0].normal_z<<" "
              <points[0].curvature<<"]"<<endl;cout<<"["<points[0].normal[0]<<" "
              <points[0].normal[1]<<" "
              <points[0].normal[2]<<" "
              <points[0].curvature<<"]"<<endl;cout<<"["<points[0].data_n[0]<<" "
              <points[0].data_n[1]<<" "
              <points[0].data_n[2]<<" "
              <points[0].curvature<<"]"<<endl;

四、计算法线并显示:

1、计算输入点云的所有点的法线

#include 
#include 
#include 
//#include 
#include //使用OMP需要添加的头文件
#include 
#include 
using namespace std;
int main(){
    //------------------加载点云数据-------------------
    pcl::PointCloud<:pointxyz>::Ptr cloud(new pcl::PointCloud<:pointxyz>);if (pcl::io::loadPCDFile<:pointxyz>("horse.pcd", *cloud) == -1)
    {
        PCL_ERROR("Could not read file\n");
    }//------------------计算法线----------------------
    pcl::NormalEstimationOMP<:pointxyz> n;//OMP加速
    pcl::PointCloud<:normal>::Ptr normals(new pcl::PointCloud<:normal>);//建立kdtree来进行近邻点集搜索
    pcl::search::KdTree<:pointxyz>::Ptr tree(new pcl::search::KdTree<: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<:visualization::pclvisualizer> viewer(new pcl::visualization::PCLVisualizer("3D viewer"));//viewer->initCameraParameters();//设置照相机参数,使用户从默认的角度和方向观察点云//设置背景颜色
    viewer->setBackgroundColor(0.3, 0.3, 0.3);
    viewer->addText("faxian", 10, 10, "text");//设置点云颜色
    pcl::visualization::PointCloudColorHandlerCustom<:pointxyz> single_color(cloud, 0, 225, 0);//添加坐标系
    viewer->addCoordinateSystem(0.1);
    viewer->addPointCloud<:pointxyz>(cloud, single_color, "sample cloud");
    viewer->addPointCloudNormals<:pointxyz>(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;
}

2、计算输入点云数据中一个子集的法线

#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
int main(){
    //---------------------加载点云数据----------------------
    pcl::PointCloud<:pointxyz>::Ptr cloud(new pcl::PointCloud<:pointxyz>);if (pcl::io::loadPCDFile<:pointxyz>("horse.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[i] = i;   
    }//-------------------传递索引----------------------------
    pcl::IndicesPtr indices(new vector <int>(point_indices));//-------------------计算法线----------------------------
    pcl::NormalEstimationOMP<:pointxyz> n;//OMP加速
    n.setInputCloud(cloud);
    n.setIndices(indices);// 创建一个kd树,方便搜索;并将它传递给上面创建的法线估算类对象
    pcl::search::KdTree<:pointxyz>::Ptr tree(new pcl::search::KdTree<:pointxyz>());
    n.setSearchMethod(tree);
    n.setRadiusSearch(0.01);
    pcl::PointCloud<:normal>::Ptr normals(new pcl::PointCloud<:normal>);//----------------估算特征---------------
    n.compute(*normals);//-------------为方便可视化,将前10%点云提出-------------------------------
    pcl::PointCloud<:pointxyz>::Ptr cloud1(new pcl::PointCloud<:pointxyz>);
    pcl::copyPointCloud(*cloud, point_indices, *cloud1);//------------------可视化-----------------------
    boost::shared_ptr<:visualization::pclvisualizer> viewer(new pcl::visualization::PCLVisualizer("3D viewer"));//设置背景颜色
    viewer->setBackgroundColor(0.3, 0.3, 0.3);
    viewer->addText("faxian", 10, 10, "text");//设置点云颜色
    pcl::visualization::PointCloudColorHandlerCustom<:pointxyz> single_color1(cloud1, 0, 225, 0);
    pcl::visualization::PointCloudColorHandlerCustom<:pointxyz> single_color(cloud, 255, 0, 0);//添加坐标系//viewer->addCoordinateSystem(0.1);
    viewer->addPointCloud<:pointxyz>(cloud, single_color, "sample cloud");
    viewer->addPointCloud<:pointxyz>(cloud1, single_color1, "sample cloud1");
    viewer->addPointCloudNormals<:pointxyz>(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;
}

3、使用另一个数据集(该数据集比较完整)估计其最近邻近点,估算输入数据集(比较稀疏)中所有点的一组曲面法线。该方法适用于(类似)下采样后的点云。

#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
int main(){
    pcl::PointCloud<:pointxyz>::Ptr cloud(new pcl::PointCloud<:pointxyz>);if (pcl::io::loadPCDFile<:pointxyz>("horse.pcd", *cloud) == -1)
    {
        PCL_ERROR("Could not read file\n");
    }//------------下采样----------------
    pcl::PointCloud<:pointxyz>::Ptr cloud_downsampled(new pcl::PointCloud<:pointxyz>);
    pcl::VoxelGrid<:pointxyz> sor;
    sor.setInputCloud(cloud);
    sor.setLeafSize(0.005f, 0.005f, 0.05f);
    sor.filter(*cloud_downsampled);//-------------计算法线-------------
    pcl::search::KdTree<:pointxyz>::Ptr tree(new pcl::search::KdTree<:pointxyz>());
    pcl::NormalEstimationOMP<:pointxyz> ne;
    ne.setInputCloud(cloud_downsampled);
    ne.setSearchSurface(cloud);
    ne.setSearchMethod(tree);
    ne.setRadiusSearch(0.01);
    pcl::PointCloud<:normal>::Ptr normals(new pcl::PointCloud<:normal>);
    ne.compute(*normals);//------------------可视化-----------------------
    boost::shared_ptr<:visualization::pclvisualizer> viewer(new pcl::visualization::PCLVisualizer("3D viewer"));//设置背景颜色
    viewer->setBackgroundColor(0.3, 0.3, 0.3);
    viewer->addText("faxian", 10, 10, "text");//设置点云颜色
    pcl::visualization::PointCloudColorHandlerCustom<:pointxyz> single_color(cloud_downsampled, 255, 0, 0);//添加坐标系//viewer->addCoordinateSystem(0.1);
    viewer->addPointCloud<:pointxyz>(cloud_downsampled, single_color, "sample cloud");
    viewer->addPointCloudNormals<:pointxyz>(cloud_downsampled, normals, 10, 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;
}

五、使用OMP的报错处理

在应用OpenMP,可能会报错“User Error 1001: argument to num_threads clause must be positive”。这是由于设置的线程数必须为正,而程序中可能没有设置,有时候甚至环境变量中设置了,但是依然报错,手动设置如下:

n.setNumberOfThreads(4);  // 手动设置线程数,比源码增加,否则提示错误
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值