精华内容
下载资源
问答
  • 点云法向量计算原理
    千次阅读
    2020-12-03 20:46:16

    最近因为项目,需要计算点云的法向量,所以在网上看了一些资料,然后知道pcl库里面有这些功能,pcl的法向量计算的原理:
    pcl里面计算点云(自己的理解
    根据顶点采样最近的局部点云(k个),根据自己的点云拟合出一个局部平面,然后计算平面的法向量。就是顶点的向量。
    计算可以通过PCA那种,可以计算顶点的三个方向的主成分,然后得到最次的主成分对应的法向量,就是平面法向量。
    以下是自己使用PCL计算法向量的过程,因为引用都是PCL库,所以只需要理解这个库的使用就可以了。

    #include<pcl\point_types.h>
    #include<pcl\kdtree\kdtree_flann.h>
    #include<pcl\features\normal_3d.h>
    #include<pcl\point_cloud.h>
    
    	bool CaculateNormals()
    	{
    		if (HasNormal() && vertices_normals_.size() == vertices_.size())
    			return true;
    		std::cout << "start compute normal..." << std::endl;
    
    		pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
    		for (int i = 0; i < vertices_.size(); ++i)	//这是一个类里面的函数,需要自己提供点云
    		{
    			pcl::PointXYZ p(vertices_[i](0), vertices_[i](1), vertices_[i](2));
    			cloud->points.emplace_back(p);
    		}
    		pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> cloud_normals;
    		pcl::PointCloud<pcl::Normal>::Ptr normals(new pcl::PointCloud<pcl::Normal>);
    		//在flann中找到kdtree搜索机制
    		pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>());
    		//为kdtree增加搜索的点云
    		tree->setInputCloud(cloud);
    		cloud_normals.setInputCloud(cloud);
    		cloud_normals.setSearchMethod(tree);
    		cloud_normals.setKSearch(20);
    
    		std::clock_t start_read = std::clock();
    
    		cloud_normals.compute(*normals);
    
    		std::clock_t end_read = std::clock();
    
    		const float parsing_time = static_cast<float>(double(end_read - start_read)) / 1000.f;
    		std::cout << "\t compute normal time parsing " << parsing_time << " seconds " << std::endl;
    
    		std::cout << "normal num is: " << normals->size() << std::endl;
    		std::cout << "end compute the cloud normals." << std::endl;
    
    		//清空
    		vertices_normals_.swap(std::vector<Eigen::Vector3f>());
    		for (int i = 0; i < normals->size(); ++i)
    		{
    			Eigen::Vector3f tmp(normals->points[i].normal_x, 
    				normals->points[i].normal_y, normals->points[i].normal_z);
    			vertices_normals_.emplace_back(tmp);
    		}
    
    		return true;
    	}
    

    这样就得到点云中的法向量。

    更多相关内容
  • 基于matlab对三维点云法向量进行求取,并进行朝向统一。
  • 点云法向量,点云法向量计算原理,matlab源码
  • 点云法向量计算

    2019-02-28 07:06:57
    该代码用于点云数据中每一点的法向量的估算,计算速度较快,带测试数据
  • [PCL] 点云法向量计算NormalEstimation

    千次阅读 2021-07-22 19:56:53
    [PCL] 点云法向量计算NormalEstimation 转载来源 从GitHub的代码版本库下载源代码https://github.com/PointCloudLibrary/pcl,用CMake生成VS项目,查看PCL的源码位于pcl_features项目下 1.Feature类: template <...

    [PCL] 点云法向量计算NormalEstimation

    转载来源
    从GitHub的代码版本库下载源代码https://github.com/PointCloudLibrary/pcl,用CMake生成VS项目,查看PCL的源码位于pcl_features项目下
    1.Feature类:

    template <typename PointInT, typename PointOutT>   class Feature : public PCLBase<PointInT>
    

    注意 Feature是一个泛型类,有一个compute方法。

    `template <typename PointInT, typename PointOutT> void pcl::Feature<PointInT, PointOutT>::compute (PointCloudOut &output)
    {
      if (!initCompute ())
      {
        output.width = output.height = 0;
        output.points.clear ();
        return;
      }
      // Copy the header
      output.header = input_->header;
      // Resize the output dataset
      if (output.points.size () != indices_->size ())
        output.points.resize (indices_->size ());
      // Check if the output will be computed for all points or only a subset
      // If the input width or height are not set, set output width as size
      if (indices_->size () != input_->points.size () || input_->width * input_->height == 0)
      {
        output.width = static_cast<uint32_t> (indices_->size ());
        output.height = 1;
      }
      else
      {
        output.width = input_->width;
        output.height = input_->height;
      }
      output.is_dense = input_->is_dense;
      // Perform the actual feature computation
      computeFeature (output);
      deinitCompute ();
    }`
    

    2.注意computeFeature (output);方法 ,可以知道这是一个私有的虚方法。

    private:
          /** \brief Abstract feature estimation method.
            * \param[out] output the resultant features    */
          virtual void    computeFeature (PointCloudOut &output) = 0;
    

    3.查看Feature的继承关系可以知道

    template <typename PointInT, typename PointOutT>   class NormalEstimation: public Feature<PointInT, PointOutT>
    

    NormalEstimation类是Feature模板类的子类,因此执行的是NormalEstimation类的computeFeature方法。查看computeFeature方法:

    template <typename PointInT, typename PointOutT> void pcl::NormalEstimation<PointInT, PointOutT>::computeFeature (PointCloudOut &output)
    {
      // Allocate enough space to hold the results
      // \note This resize is irrelevant for a radiusSearch ().
      std::vector< int> nn_indices (k_);
      std::vector< float> nn_dists (k_);
      output.is_dense = true;
      // Save a few cycles by not checking every point for NaN/Inf values if the cloud is set to dense
      if (input_->is_dense)
      {
        // Iterating over the entire index vector
        for (size_t idx = 0; idx < indices_->size (); ++idx)
        {
          if (this ->searchForNeighbors ((*indices_)[idx], search_parameter_, nn_indices, nn_dists) == 0 ||
              !computePointNormal (*surface_, nn_indices, output.points[idx].normal[0], output.points[idx].normal[1], output.points[idx].normal[2], output.points[idx].curvature))
          {
            output.points[idx].normal[0] = output.points[idx].normal[1] = output.points[idx].normal[2] = output.points[idx].curvature = std::numeric_limits<float >::quiet_NaN ();
            output.is_dense = false;
            continue;
          }
    
          flipNormalTowardsViewpoint (input_->points[(*indices_)[idx]], vpx_, vpy_, vpz_, output.points[idx].normal[0], output.points[idx].normal[1], output.points[idx].normal[2]);
        }
      }
      else
      {
        // Iterating over the entire index vector
        for (size_t idx = 0; idx < indices_->size (); ++idx)
        {
          if (!isFinite ((*input_)[(*indices_)[idx]]) ||
              this->searchForNeighbors ((*indices_)[idx], search_parameter_, nn_indices, nn_dists) == 0 ||
              !computePointNormal (*surface_, nn_indices, output.points[idx].normal[0], output.points[idx].normal[1], output.points[idx].normal[2], output.points[idx].curvature))
          {
            output.points[idx].normal[0] = output.points[idx].normal[1] = output.points[idx].normal[2] = output.points[idx].curvature = std::numeric_limits<float >::quiet_NaN ();
    
            output.is_dense = false;
            continue;
          }
          flipNormalTowardsViewpoint (input_->points[(*indices_)[idx]], vpx_, vpy_, vpz_,  output.points[idx].normal[0], output.points[idx].normal[1], output.points[idx].normal[2]);
        }
      }
    }
    

    4.因此分析NormalEstimation的算法流程如下:
      (1)进行点云的初始化initCompute
      (2)初始化计算结果输出对象output
      (3)计算点云法向量,具体由子类的computeFeature方法实现。先搜索近邻searchForNeighbors ,然后计算computePointNormal
        采用的方法是PCA主成分分析法。
        参考文献:《Semantic 3D Object Maps for Everyday Manipulation in Human Living Environments》 P45-49
    点云的法向量主要是通过点所在区域的局部拟合的表面进行计算。平面通过一个点和法向量进行表示。对于每一个点Pi,对应的协方差矩阵C
        在这里插入图片描述

    关于主成份分析的基本原理和算法流程参考:http://blog.csdn.net/lming_08/article/details/21335313
      (4)flipNormalTowardsViewpoint 法向量定向,采用方法是:使法向量的方向朝向viewpoint。
    5.NormalEstimation模板类的重载方法computeFeature分析,computePointNormal分析。

    inline bool computePointNormal (const pcl::PointCloud<PointInT> &cloud, const std::vector<int> &indices,
                              float &nx, float &ny, float &nz, float &curvature)
          {
            if (indices.size () < 3 ||
                computeMeanAndCovarianceMatrix (cloud, indices, covariance_matrix_, xyz_centroid_) == 0)
            {
              nx = ny = nz = curvature = std::numeric_limits<float>::quiet_NaN ();
              return false;
            }
    
            // Get the plane normal and surface curvature
            solvePlaneParameters (covariance_matrix_, nx, ny, nz, curvature);
            return true;
          }
    

    computeMeanAndCovarianceMatrix主要是PCA过程中计算平均值和协方差矩阵,在类centroid.hpp中。
    而solvePlaneParameters方法则是为了求解特征值和特征向量。代码见feature.hpp。具体实现时采用了pcl::eigen33方法。

    inline void pcl::solvePlaneParameters (const Eigen::Matrix3f &covariance_matrix,
                               float &nx, float &ny, float &nz, float &curvature)
    {
      // Avoid getting hung on Eigen's optimizers
    //  for (int i = 0; i < 9; ++i)
    //    if (!pcl_isfinite (covariance_matrix.coeff (i)))
    //    {
    //      //PCL_WARN ("[pcl::solvePlaneParameteres] Covariance matrix has NaN/Inf values!\n");
    //      nx = ny = nz = curvature = std::numeric_limits<float>::quiet_NaN ();
    //      return;
    //    }
      // Extract the smallest eigenvalue and its eigenvector
      EIGEN_ALIGN16 Eigen::Vector3f::Scalar eigen_value;
      EIGEN_ALIGN16 Eigen::Vector3f eigen_vector;
      pcl::eigen33 (covariance_matrix, eigen_value, eigen_vector);
    
      nx = eigen_vector [0];
      ny = eigen_vector [1];
      nz = eigen_vector [2];
    
      // Compute the curvature surface change
      float eig_sum = covariance_matrix.coeff (0) + covariance_matrix.coeff (4) + covariance_matrix.coeff (8);
      if (eig_sum != 0)
        curvature = fabsf (eigen_value / eig_sum);
      else
        curvature = 0;
    }
    

    6.法向量定向

    见normal_3d.h文件中,有多个覆写方法。摘其一:

    /** \brief Flip (in place) the estimated normal of a point towards a given viewpoint
        * \param point a given point
        * \param vp_x the X coordinate of the viewpoint
        * \param vp_y the X coordinate of the viewpoint
        * \param vp_z the X coordinate of the viewpoint
        * \param nx the resultant X component of the plane normal
        * \param ny the resultant Y component of the plane normal
        * \param nz the resultant Z component of the plane normal
        * \ingroup features
        */
      template <typename PointT> inline void
      flipNormalTowardsViewpoint (const PointT &point, float vp_x, float vp_y, float vp_z,
                                  float &nx, float &ny, float &nz)
      {
        // See if we need to flip any plane normals
        vp_x -= point.x;
        vp_y -= point.y;
        vp_z -= point.z;
    
        // Dot product between the (viewpoint - point) and the plane normal
        float cos_theta = (vp_x * nx + vp_y * ny + vp_z * nz);
    
        // Flip the plane normal
        if (cos_theta < 0)
        {
          nx *= -1;
          ny *= -1;
          nz *= -1;
        }
      }
    

    运行的实例结果:
    在这里插入图片描述在这里插入图片描述

    展开全文
  • PCA主成分分析估计点云法向量(原理)

    千次阅读 2020-04-15 14:23:39
    Output:主成分向量 ,principle vectors ,仅仅是一个向量,代表一个方向。主成分的个数k<=原始空间维度数d Q&A 什么是最主要的成分? 点的投影后分布的方差最大的方向。(在该方向上的点云分布的最分散) ...

    PCA用到的矩阵知识

    • svd奇异值分解
    • 瑞利熵
    • 谱定理

    PCA

    • input:n*d,n代表个数,d代表维度
    • Output:主成分向量 ,principle vectors ,仅仅是一个向量,代表一个方向。主成分的个数k<=原始空间维度数d

    Q&A

    • 什么是最主要的成分?
      点的投影后分布的方差最大的方向。(在该方向上的点云分布的最分散)
    • 怎么获取第二个主成分
      去掉第一个主成分之后分布方差最大的方向

    法向量估计

    1. 原理

    所谓法线估计实质上就是对每一个点,在其邻域内估计出一个平面。

    我们知道,估计一个平面需要一个点和一个法向量,这个法向量就是我们要估计的法向量。这个点就是这一群邻域点(与该点自身)的平均值。

    设平均点为c,法向量为n,问题就可以转换到寻求一个方向n使得所有邻域点在方向n上的投影点的分布最为集中,这样一个优化问题,

    在这里插入图片描述

    很显然,根据PCA分析可以知道,寻求一个方向n使得所有邻域点在方向n上的投影点的分布最为集中,也是就意味着点在该方向上的投影的方差最小。这就是PCA中最不重要的那个方向向量,因为点云在三维空间所以,n就是第三个PCA向量。

    我们选择c为这一群点的平均值,所以xi-c就是就是去中心化后的点。所以该问题变为了如下问题,

    在这里插入图片描述

    把括号展开,化简就可以得到

    在这里插入图片描述

    根据PCA可知,我们要求的n就是XXT最小特征值对应的特征向量。

    2. 步骤

    1. 选择P
    2. 发现所选点的最近邻点
    3. PCA分析
    4. 法线:对应主成分中的最不重要的那一个方向(代表在该方向上的投影点分布最密集,方差最小)
    5. 曲率->最小特征值所占的比例
    展开全文
  • 激光点云法向量估计原理及数学推导

    激光点云法向量估计原理及数学推导

    激光点云法向量估计原理及数学推导

    简述

    点云法向量估计这个问题,相信很多人在点云处理,曲面重建的过程中遇到过。表面法线是几何体面的重要属性。而点云数据集在真实物体的表面表现为一组定点样本。对点云数据集的每个点的法线估计,可以看作是对表面法线的近似推断。在开源库提供我们调用便利的同时,了解其实现原理也有利于我们对问题的深刻认识!格物要致知:)
    在这里插入图片描述

    原理

    确定表面一点法线的问题近似于估计表面的一个相切面法线的问题,因此转换过来以后就变成一个最小二乘法平面拟合估计问题。

    • 平面方程
      c o s α ⋅ x + c o s β ⋅ y + c o s γ ⋅ z + p = 0 cos\alpha·x+cos\beta·y+cos\gamma·z+p=0 cosαx+cosβy+cosγz+p=0
      c o s α , c o s β , c o s γ cos\alpha,cos\beta,cos\gamma cosα,cosβ,cosγ为平面上点 ( x , y , z ) (x,y,z) (x,y,z)处法向量的方向余弦, ∣ p ∣ |p| p为原点到平面的距离。
      a x + b y + c z = d ( d ≥ 0 ) , a 2 + b 2 + c 2 = 1 ax+by+cz=d(d\geq0),a^{2}+b^{2}+c^{2}=1 ax+by+cz=d(d0),a2+b2+c2=1
      求平面方程即转化为求 a , b , c , d a,b,c,d a,b,c,d四个参数。

    • 求解过程

    1. 待拟合平面点集 ( x i , y i , z i ) , i = 1 , 2 , . . . , n (x_i,y_i,z_i),i=1,2,...,n (xi,yi,zi),i=1,2,...,n

    待拟合的平面方程:
    a x + b y + c z = d ( d ≥ 0 ) , a 2 + b 2 + c 2 = 1 ax+by+cz=d(d\geq0),a^{2}+b^{2}+c^{2}=1 ax+by+cz=d(d0),a2+b2+c2=1
    任意点到平面的距离:
    d i = ∣ a x + b y + c z − d ∣ d_i=|ax+by+cz-d| di=ax+by+czd

    2. 要获得最佳拟合平面,则需要满足:

    e = ∑ i = 1 n d i 2 → m i n e=\sum^n_{i=1} d_i^2\to min e=i=1ndi2min

    因此,转化为求解极值的问题,
    f = ∑ i = 1 n d i 2   − λ ( a 2 + b 2 + c 2 − 1 ) f=\sum^n_{i=1} d_i^2\space-\lambda(a^{2}+b^{2}+c^{2}-1) f=i=1ndi2 λ(a2+b2+c21)

    3. 分别对 d , a , b , c d,a,b,c d,a,b,c求偏导
    ∂ f ∂ d = − 2 ∑ i = 1 n ( a x i + b y i + c z i − d ) = 0 \frac{\partial f}{\partial d}=-2\sum^n_{i=1} (ax_i+by_i+cz_i-d)=0 df=2i=1n(axi+byi+czid)=0
    d = ∑ i = 1 n x i n a + ∑ i = 1 n y i n b + ∑ i = 1 n z i n c d=\frac{\sum ^{n}_{i=1}x_i}{n}a+\frac{\sum^{n}_{i=1}y_i}{n}b+\frac{\sum^{n}_{i=1}z_i}{n}c d=ni=1nxia+ni=1nyib+ni=1nzic
    d d d带入任意点到平面的距离公式:

    d i = ∣ a ( x i − ∑ i = 1 n x i n ) + b ( y i − ∑ i = 1 n y i n ) + c ( z i − ∑ i = 1 n z i n ) ∣ = ∣ a ( x i − x ‾ ) + b ( y i − y ‾ ) + c ( z i − z ‾ ) ∣ \begin{equation}\begin{split} d_i&=|a(x_i-\frac{\sum ^{n}_{i=1}x_i}{n})+b(y_i-\frac{\sum ^{n}_{i=1}y_i}{n})+c(z_i-\frac{\sum ^{n}_{i=1}z_i}{n})|\\ &=|a(x_i-\overline x)+b(y_i-\overline y)+c(z_i-\overline z)|\\ \end{split}\end{equation} di=a(xini=1nxi)+b(yini=1nyi)+c(zini=1nzi)=a(xix)+b(yiy)+c(ziz)

    继续求偏导
    ∂ f ∂ a = 2 ∑ i = 1 n ( a ( x i − x ‾ ) + b ( y i − y ‾ ) + c ( z i − z ‾ ) ) ( x i − x ‾ ) − 2 λ a = 0 \frac{\partial f}{\partial a}=2\sum^n_{i=1} (a(x_i-\overline x)+b(y_i-\overline y)+c(z_i-\overline z))(x_i-\overline x)-2\lambda a=0 af=2i=1n(a(xix)+b(yiy)+c(ziz))(xix)2λa=0
    Δ x i = x i − x ‾ , Δ y i = y i − y ‾ , Δ z i = z i − z ‾ \Delta x_i=x_i-\overline x,\Delta y_i=y_i-\overline y,\Delta z_i=z_i-\overline z Δxi=xix,Δyi=yiy,Δzi=ziz
    则:
    ∂ f ∂ a = 2 ∑ i = 1 n ( a Δ x i + b Δ y i + c Δ z i ) Δ x i − 2 λ a = 0 \frac{\partial f}{\partial a}=2\sum^n_{i=1} (a\Delta x_i+b\Delta y_i+c\Delta z_i)\Delta x_i-2\lambda a=0 af=2i=1n(aΔxi+bΔyi+cΔzi)Δxi2λa=0
    同理:
    ∂ f ∂ b = 2 ∑ i = 1 n ( a Δ x i + b Δ y i + c Δ z i ) Δ y i − 2 λ b = 0 \frac{\partial f}{\partial b}=2\sum^n_{i=1} (a\Delta x_i+b\Delta y_i+c\Delta z_i)\Delta y_i-2\lambda b=0 bf=2i=1n(aΔxi+bΔyi+cΔzi)Δyi2λb=0
    ∂ f ∂ c = 2 ∑ i = 1 n ( a Δ x i + b Δ y i + c Δ z i ) Δ z i − 2 λ c = 0 \frac{\partial f}{\partial c}=2\sum^n_{i=1} (a\Delta x_i+b\Delta y_i+c\Delta z_i)\Delta z_i-2\lambda c=0 cf=2i=1n(aΔxi+bΔyi+cΔzi)Δzi2λc=0

    将上述三式统一:
    ( ∑ Δ x i Δ x i ∑ Δ x i Δ y i ∑ Δ x i Δ z i ∑ Δ x i Δ y i ∑ Δ y i Δ y i ∑ Δ y i Δ z i ∑ Δ x i Δ z i ∑ Δ y i Δ z i ∑ Δ z i Δ z i ) ( a b c ) = λ ( a b c ) \begin{pmatrix}\sum \Delta x_i\Delta x_i & \sum \Delta x_i\Delta y_i &\sum \Delta x_i\Delta z_i\\ \sum \Delta x_i\Delta y_i & \sum \Delta y_i\Delta y_i &\sum \Delta y_i\Delta z_i\\\sum \Delta x_i\Delta z_i & \sum \Delta y_i\Delta z_i &\sum \Delta z_i\Delta z_i \end{pmatrix}\begin{pmatrix}a \\ b \\c \end{pmatrix}=\lambda\begin{pmatrix}a\\b\\c \end{pmatrix} ΔxiΔxiΔxiΔyiΔxiΔziΔxiΔyiΔyiΔyiΔyiΔziΔxiΔziΔyiΔziΔziΔzi abc =λ abc
    易得:
    A x = λ x Ax=\lambda x Ax=λx

    即转化到了求解矩阵A的特征值与特征向量的问题,矩阵A即为n个点的协方差矩阵。 ( a , b , c ) T (a,b,c)^T (a,b,c)T即为该矩阵的一个特征向量。

    4. 求最小特征向量
    如上所示,求得的特征向量可能不止一个,那么如何来选取特征向量,使得求得法向量为最佳拟合平面的法向量呢?

    a 2 + b 2 + c 2 = 1 , ⇒ ( x , x ) = 1 a^2+b^2+c^2=1,\Rightarrow(x,x)=1 a2+b2+c2=1,(x,x)=1(内积形式),
    A x = λ x , ⇒ ( A x , x ) = ( λ x , x ) , ⇒ λ = ( A x , x ) , Ax=\lambda x,\Rightarrow (Ax,x)=(\lambda x ,x),\Rightarrow \lambda=(Ax,x), Ax=λx,(Ax,x)=(λx,x),λ=(Ax,x),
    ⇒ λ = ∑ i = 0 n ( a Δ x i + b Δ y i + c Δ z i ) 2 , \Rightarrow \lambda=\sum_{i=0}^{n}(a\Delta x_i+b\Delta y_i+c\Delta z_i)^2, λ=i=0n(aΔxi+bΔyi+cΔzi)2,
    ⇒ λ = ∑ i = 0 n d i 2 \Rightarrow \lambda=\sum_{i=0}^{n}d_i^2 λ=i=0ndi2

    e = ∑ i = 1 n d i 2 → m i n , λ → m i n e=\sum^n_{i=1} d_i^2\to min,\lambda \to min e=i=1ndi2min,λmin

    因此,最小特征值对应的特征向量即为法向量

    程序应用

    • PCL中的NormalEstimation
        #include <pcl/point_types.h>
        #include <pcl/features/normal_3d.h>
    
    {
      pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);
    
      ... read, pass in or create a point 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 cloud_normals (new pcl::PointCloud<pcl::Normal>);
    
      // Use all neighbors in a sphere of radius 3cm
      ne.setRadiusSearch (0.03);
    
      // Compute the features
      ne.compute (*cloud_normals);
    
      // cloud_normals->points.size () should have the same size as the input cloud->points.size ()*
    }
    
    • OpenMP加速法线估计
      PCL提供了表面法线估计的加速实现,基于OpenMP使用多核/多线程来加速计算。 该类的名称是pcl :: NormalEstimationOMP,其API与单线程pcl :: NormalEstimation 100%兼容。 在具有8个内核的系统上,一般计算时间可以加快6-8倍。
    include <pcl/point_types.h>
    #include <pcl/features/normal_3d_omp.h>
    
    {
      pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);
    
      ... read, pass in or create a point cloud ...
    
      // Create the normal estimation class, and pass the input dataset to it
      pcl::NormalEstimationOMP<pcl::PointXYZ, pcl::Normal> ne;
      ne.setNumberOfThreads(12);  // 手动设置线程数,否则提示错误
      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 cloud_normals (new pcl::PointCloud<pcl::Normal>);
    
      // Use all neighbors in a sphere of radius 3cm
      ne.setRadiusSearch (0.03);
    
      // Compute the features
      ne.compute (*cloud_normals);
    
      // cloud_normals->points.size () should have the same size as the input cloud->points.size ()*
    }
    

    作者:codehory
    链接:https://www.jianshu.com/p/faa9953213dd
    来源:简书
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    展开全文
  • 点云法向量

    万次阅读 多人点赞 2019-07-30 09:58:00
    一、点云法向量 法向量是点云中各点的重要属性之一。众多点云算法的实施都基于精确的法向量估计,例如许多表面重建算法、点云分割算法、点云去噪算法以及特征描述算法等。 由空间变换可知,点云中每一点的法向量...
  • 最小二乘计算点云法向量原理 对于任意一点 p(x,y,z)p(x, y, z)p(x,y,z)查找其一定领域内的点{pi}\{{p_i}\}{pi​}; 求得一个平面 ∏:a0x+a1y+a2z+1=0\prod: a_0x + a_1y+a_2z + 1 = 0∏:a0​x+a1​y+a2​z+1=0使得其...
  • 点云学习【1.2】法向量计算

    千次阅读 2020-09-29 10:19:52
    法向量为投影到某方向后,信息量最小的方向,因此需要PCA变换,将点云投影到特征值最小的方向。由于需要PCA算法,因此先把昨天的PCA算法拷贝过来。` import open3d as o3d import numpy as np from pyntcloud ...
  • MATLAB点云处理:2点云最近点查询和法向量计算、通过索引提取点云 这次主要是点云法向量计算和最近点查询 法向量计算 MATLAB提供了函数pcnormals用于计算点云的法向量,下面用经典的兔子展示一下 clc,clear rabbit...
  • PCL教程指南-Estimating Surface Normals in a PointCloud(估计点云法向量) 官方原文档 点云法向指每个点的法向量,它是基于各点所在邻域范围内估计而出,常用方法如最小二乘估计邻域平面进而求出法向量,PCA求解...
  • PCL 计算点云法向量并显示

    万次阅读 多人点赞 2020-04-16 16:11:27
    PCL计算法向量并显示,用OMP进行计算加速以及法线定向的深层次理解、操作。
  • [PCL]2 点云法向量计算NormalEstimation

    千次阅读 2018-10-15 20:56:59
     (3)计算点云法向量,具体由子类的computeFeature方法实现。先搜索近邻searchForNeighbors ,然后计算computePointNormal  采用的方法是PCA主成分分析法。  参考文献:《Semantic 3D Object Maps for ...
  • Meshlab是一个强大的三维模型处理的软件,在三维点云的处理方面也十分强大,不仅仅可以用三维点云重构出三维模型,还可以...
  • 点云法向量与点云平面拟合的关系(PCA) Estimating Surface Normals in a PointCloud 3D【24】PCA点云法向量估计 利用PCA计算点云的法线 3D点云法向量估计(最小二乘拟合平面) 为什么用PCA做点云法线估计? ...
  • PCL 计算点云法向量的夹角

    千次阅读 2021-09-09 07:16:00
    计算点云法向量的夹角
  • 目前网上能找到的所有关于“使用积分图计算点云法相”的资料都是来自PCL的,只有code,没有原理 这篇笔记来自论文Adaptive neighborhood selection for real-time surface normal estimation from organized point ...
  • 本文介绍了MATLAB计算点云法向量的方法,并进行法线一致性定向。
  • 点云表面法向量的估计

    千次阅读 2020-01-21 19:38:55
    点云表面法向量是一种重要几何表面特性,在计算机图像学中有很广的应用,例如在进行光照渲染和其他可视化效果时确定一个合理的光源位置。通过已知的确定几何表面来估计表面法向量通常并没有什么难度。但通过一组实际...
  • NormalEstimationOMP计算点云法向量的python—pclpy代码实现
  • 法向量点云旋转

    千次阅读 2022-07-01 09:07:48
    点云处理过程中,我们有时需要根据法向量点云旋转到指定方向。例如,我们需要把激光雷达点云中地面旋转到与xoy平面平行。本节将详细介绍其中原理和python代码。 平面方程可以用如下公式表示:则(A, B, C)为...
  • Open3D 点云法向量重定向(基于参考方向)
  • PCL估计点云的表面法向量

    万次阅读 多人点赞 2019-06-26 10:37:18
    PCL估计点云的表面法向量估计点云表面法向量的方法理论基础法线确定方法法线方向确定选择合适的邻域尺度PCL估计表面法线代码...PCL中点云表面法向量的实现是基于后者的,即在给定点云数据集的情况下,直接计算点云中...
  • 核心是把局部点当作一个平面,利用平面的法向量与平行于平面的法向量乘机为零,来计算法向量的方向是不确定的,可能朝平面上,也可能是朝平面下,因此,如果需要统一法向量的方向,需要设置视点,原理是求取...
  • 点云NormalEstimation】python-pcl:法向量估计并存储

    千次阅读 热门讨论 2020-09-13 21:42:48
    1. 估算PointCloud的表面法线(Surface Normals) 2. 打印点云法向量结果; 3. 存储点云法向量结果;
  • 点云法向量是3D点云一个极其重要的几何表面特征,众多的点云处理算法都依赖精确的法向量估计,例如点云分割,点云去噪等。在自动驾驶领域,面对特殊场景我们主要依赖点云法向量进行场景分割。估计点云法向量需要得到...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,572
精华内容 628
关键字:

点云法向量计算原理