点云中点法向量,点拟合的直线,点拟合的平面

这篇具有很好参考价值的文章主要介绍了点云中点法向量,点拟合的直线,点拟合的平面。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

点云中点法向量

计算步骤:

找到点pi相邻点集合S所有点Vi,然后去中心化,并构造协方差矩阵,公式如下:

点云中点法向量,点拟合的直线,点拟合的平面

二维点云该点曲率计算方法:

点云中点法向量,点拟合的直线,点拟合的平面

三维点云该点曲率计算方法:

点云中点法向量,点拟合的直线,点拟合的平面

最小特征值对应的特征向量就是点的法向量

Eigen::Vector2d ComputeNormal(std::vector<Eigen::Vector2d> &nearPoints)
{
    Eigen::Vector2d normal;

    //计算激光点法向量,NICP计算法向量的方法
    Eigen::Vector2d average;//周围点的几何中心
    average.setZero();//置0
    for(auto v : nearPoints)//遍历每个点
    {
        average += v / nearPoints.size();//求其周围点的几何中心
    }

    Eigen::Matrix2d covariance;//协方差矩阵
    covariance.setZero();//置0
    for(auto v : nearPoints)//遍历每个点
    {
        covariance += (v - average) * (v - average).transpose() / nearPoints.size();//求协方差矩阵
    }

    Eigen::EigenSolver<Eigen::Matrix2d> eigen_solver(covariance);//转化为对角线矩阵
    Eigen::Vector2d eigenValues = eigen_solver.pseudoEigenvalueMatrix().diagonal();//特征值,协方差所有特征值构成向量
    Eigen::Matrix2d eigenVectors = eigen_solver.pseudoEigenvectors();//特征向量,协方差所有特征向量构成矩阵
    normal = eigenValues(0) < eigenValues(1) ? eigenVectors.col(0) : eigenVectors.col(1);//计算法向量

    return normal;
}

点拟合的直线

相邻点集合S拟合成一条直线。

计算步骤:

计算出点集合协方差矩阵M(也就是上面的计算公式),特征向量为E,特征值为V,那么中一个特征值就会明显比其他两个大,最大特征值所对应特征向量就是直线的方向。(特征值:两小一大,大方向)

Eigen::Vector3d ComputeLineNormal(std::vector<Eigen::Vector3d> &nearPoints)
{
    //计算激光点直线法向量
    Eigen::Vector3d center;//周围点的几何中心
    center.setZero();//置0
    for(auto v : nearPoints)//遍历每个点
    {
        center += v / nearPoints.size();//求其周围点的几何中心
    }

    Eigen::Matrix3d covMat;//协方差矩阵
    covMat.setZero();//置0
    for(auto v : nearPoints)//遍历每个点
    {
        Eigen::Matrix<double, 3, 1> tmpZeroMean = v - center;
        covariance += tmpZeroMean * tmpZeroMean.transpose();//求协方差矩阵
    }

    Eigen::SelfAdjointEigenSolver<Eigen::Matrix3d> saes(covMat);
    Eigen::Vector3d unit_direction = saes.eigenvectors().col(2); //最大特征值对应的特征向量->边缘线方向
    // 最大特征值大于次大特征值的3倍认为是线特征
    if (saes.eigenvalues()[2] > 3 * saes.eigenvalues()[1])
    {
        Eigen::Vector3d point_on_line = center;
        Eigen::Vector3d point_a, point_b;
        // 根据拟合出来的线特征方向,以平均点为中心构建两个虚拟点,代替一条直线
        point_a = 0.1 * unit_direction + point_on_line;
        point_b = -0.1 * unit_direction + point_on_line;
    }

    return unit_direction; //返回线的法向量
}

点拟合平面

如果点集合S在一块平面上,

计算步骤:

计算出点集合协方差矩阵M(也就是上面的计算公式),特征向量为E,特征值为V,那么其中一个特征值就会明显比其他两个小,最小特征值所对应特征向量就是平面法向量。(特征值:两大一小,小方向)

//假设传进来的nearPoints有五个点
void  ComputePlaneNormal(std::vector<Eigen::Vector3d> &nearPoints)
{
    //平面方程 Ax + By + Cz + 1 =0 平面法向量(A,B,C)[待求] 已知5个点求解3个未知数,构建超定方程AX = b求解平面法向量;
    Eigen::Matrix<double, 5, 3> matA0; //A = 5 * 3 系数矩阵方程
    Eigen::Matrix<double, 5, 1> matB0 = -1 * Eigen::Matrix<double, 5, 1>::Ones();
    
    for (int j = 0; j < 5; j++)
    {
        matA0(j, 0) = nearPoints[j][0];
        matA0(j, 1) = nearPoints[j][1];
        matA0(j, 2) = nearPoints[j][2];
    }
    Eigen::Vector3d norm = matA0.colPivHouseholderQr().solve(matB0);//平面法向量求解
    double negative_OA_dot_norm = 1 / norm.norm();
    norm.normalize(); //法向量单位化 B.normalize() = B / B.norm() B 是个向量

    // Here n(pa, pb, pc) is unit norm of plane
    bool planeValid = true;
    // 根据求出来的平面方程进行校验,看看是不是符合平面约束
    for (int j = 0; j < 5; j++)
    {
        // if OX * n > 0.2, then plane is not fit well
        //点到平面的距离公式: Ax + By + Cz + D = 0 的距离公式 = fabs(Ax0 + By0 + Cz0 + D) / sqrt(A^2 + B^2 + C^2) 
        //由于前面已经进行归一化,将系数除以分母,所以可以直接代点进去求距离
        if (fabs(norm(0) * nearPoints[j][0] +norm(1) * nearPoints[j][1] + norm(2) * nearPoints[j][2] + negative_OA_dot_norm) > 0.2)
	{
	    planeValid = false;
	    break;
	}
    }
}

参考:点云配准方法---ICP升级版本NICP(Normal ICP) - 古月居

 GitHub - HKUST-Aerial-Robotics/A-LOAM: Advanced implementation of LOAM文章来源地址https://www.toymoban.com/news/detail-419003.html

到了这里,关于点云中点法向量,点拟合的直线,点拟合的平面的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 3D点云处理:圆柱侧面点云展开为平面 凹凸缺陷检测(附源码)

    订阅说明:如果要订阅,先看链接内容 看链接内容 看链接内容:订阅先看此内容 文章目录: 3D视觉个人学习目录 目标:对采集的圆柱面点云展开为平面; 应用:可用于检测圆柱侧面的凹凸缺陷;       圆柱的侧面展开原理是将一个圆柱体(或柱体)的侧面展开成一个矩

    2024年02月09日
    浏览(100)
  • OpenCV 笔记(17):轮廓的椭圆拟合、直线拟合

    轮廓的 椭圆拟合 是指用椭圆来近似轮廓的形状。当这个椭圆的长轴和短轴相等时,它就是一个圆。 椭圆拟合的基本思路是:对于给定平面上的一组样本点,寻找一个椭圆,使其尽可能接近这些样本点。也就是说,将图像中的一组数据以椭圆方程为模型进行拟合,使某一椭圆

    2024年01月19日
    浏览(31)
  • 使用RANSAC算法在点云中拟合原始3D形状:pyRANSAC-3D的介绍和应用

    随机样本共识(RANSAC)是一种强大的算法,用于从数据集中估计数学模型的参数,特别是在数据包含大量异常值时。在3D计算机视觉中,RANSAC常用于从点云数据中拟合原始形状,例如平面、长方体和圆柱体。本文将介绍一个名为pyRANSAC-3D的开源库,它提供了RANSAC算法的Python实现

    2024年02月13日
    浏览(24)
  • Matlab 最小二乘法 拟合平面 (PCL PCA拟合平面)

    最小二乘法 拟合平面是我们最常用的拟合平面的方法,但是有特殊的情况是用这种方法是不能拟合的,后续会加上这种拟合方法(RANSAC)。 matlab 最小二乘拟合平面(方法一) - 灰信网(软件开发博客聚合) 平面方程:Ax+By+Cz+D=0;   1、随机出来一些离散的点    2、将其写成

    2024年02月16日
    浏览(32)
  • 点云数据做简单的平面的分割 三维场景中有平面,杯子,和其他物体 实现欧式聚类提取 对三维点云组成的场景进行分割

    点云分割是根据空间,几何和纹理等特征对点云进行划分,使得同一划分内的点云拥有相似的特征,点云的有效分割往往是许多应用的前提,例如逆向工作,CAD领域对零件的不同扫描表面进行分割,然后才能更好的进行空洞修复曲面重建,特征描述和提取,进而进行基于3D内

    2024年02月10日
    浏览(36)
  • opencv(38) 图像轮廓之七:椭圆拟合和直线拟合

    椭圆拟合法的基本思路是:对于给定平面上的一组样本点,寻找一个椭圆,使其尽可能接近这些样本点。也就是说,将图像中的一组数据以椭圆方程为模型进行拟合,使某一椭圆方程尽量满足这些数据,并求出该椭圆方程的各个参数。 就椭圆拟合而言,就是先假设椭圆参数,

    2024年02月04日
    浏览(30)
  • 1.5 空间中的平面与直线

    1.平面的法向量与法式 定义1 若向量n 垂直与平面N,则称向量n为平面N的法向量。 设一平面通过一直点 M 0 ( x 0 , y 0 , z 0 ) M_0(x_0,y_0,z_0) M 0 ​ ( x 0 ​ , y 0 ​ , z 0 ​ ) 求垂直于非零向量 n ⃗ vec{n} n = (A,B,C),求改平面N的方程。 任意点 M ( x , y , z ) ∈ N M(x,y,z) in N M ( x , y , z ) ∈

    2024年02月09日
    浏览(35)
  • halcon脚本-找直线并拟合

    本文主要是实现halcon脚本找直线,并根据两条拟合直线计算交点坐标,并得出其位置角度。 本文主要针对一下图片进行检测: 图1: 图2: 从图上标明可知,本次检测就是我画的蓝色的线条部分 根据现场照片来说,本次的实验的工件存在各种角度,不单单是摆着那么正的,因

    2024年02月04日
    浏览(23)
  • 自留-Python:线性拟合(直线+曲线)

    使用最小二乘法的线性拟合,自留代码 读取数据  

    2024年02月12日
    浏览(28)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包