PCL法线计算建议

这段时间在计算法线时发现,当kdtree设置有序和无序时,协方差矩阵计算结果不一致,
点云图
点云图如上:
计算法线结果
在这里插入图片描述
法线计算结果(默认情况,不排序)

不排序计算协方差(第一个点)

3.05176e-05            0  4.76837e-06
           0  1.66893e-05 -3.57628e-07
 4.76837e-06 -3.57628e-07    5.126e-06
 法线
 -0.178541
0.0282765
0.983526

排序后协方差(第一个点)

2.28882e-05  1.90735e-06  6.67572e-06
 1.90735e-06   1.7643e-05 -3.57628e-07
 6.67572e-06 -3.57628e-07  4.70877e-06
法线
-0.315286
0.0619243
0.946974

看源码得知,以下代码导致计算结果不一致

    for (std::vector<int>::const_iterator iIt = indices.begin (); iIt != indices.end (); ++iIt)
    {
		std::cout << cloud[*iIt] << std::endl;
      //const PointT& point = cloud[*iIt];
      accu [0] += cloud[*iIt].x * cloud[*iIt].x;
      accu [1] += cloud[*iIt].x * cloud[*iIt].y;
      accu [2] += cloud[*iIt].x * cloud[*iIt].z;
      accu [3] += cloud[*iIt].y * cloud[*iIt].y;
      accu [4] += cloud[*iIt].y * cloud[*iIt].z;
      accu [5] += cloud[*iIt].z * cloud[*iIt].z;
      accu [6] += cloud[*iIt].x;
      accu [7] += cloud[*iIt].y;
      accu [8] += cloud[*iIt].z;
    }

有序accu [0]=5459.22266
无序accu [0]=5459.22412
小数点第三位出现不一致,这对点云估计有很大的影响,因为协方差基本都是在小数点后五位的量级。
对以上结果进行分析,无论是否排序,indices都是内容都是一致的,只是顺序不同,考虑计算过程可能出现问题
改变代码如下:

	float temp = 0;
	for (size_t i = 0; i < indices.size(); i++)
	{
		temp += cloud->points[indices[i]].x * cloud->points[indices[i]].x;
		std::cout << setprecision(10) << cloud->points[indices[i]].x<<'\t'<< temp << "\t"<<indices[i]<<std::endl;
	}

计算出的结果没有变化,依然有差异,由此猜想可能是float精度不够导致的,将float换成double,发现结果一致,为5459.223686.
以上结果表明在进行计算时,最好选择double,防止因为精度问题导致的结果差异。
float保留9位有效数字,其中前六位是准确的,后三位可能出现偏差。针对大尺度数据没有问题,小尺度微小的差异都将对点云法线估计造成比较大的影响。
pcl法线估计不好修改,主要是点云的存储为float,Eigen不能混合不同类型,比较麻烦,可以选择直接继承NormalEstimation。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值