《Open3D点云库 C++学习笔记 》

几何篇(二)


文章目录

  • 几何篇(二)
  • 前言
  • 一、点云的法线估计
  • 二、离群点去除
    • 1.统计学离群点去除
    • 2.半径离群点去除
  • 三、参考资料
  • 总结


前言

本章节将主要介绍点云的法线估计和离群点去除。


一、点云的法线估计

点云的另一个基本操作是点的法线估计。按N键可以查看点的法线。按键-+可以用来控制法线的长度。计算下采样点云的法线有两种方式,方式一为搜索半径,方式二为搜索最近邻。

代码如下:

// test downsample
    auto downsampled = pointcloud->VoxelDownSample(0.05);

    // test normal estimation
    visualization::DrawGeometriesWithKeyCallbacks(
            {downsampled},
            {{GLFW_KEY_SPACE,
              [&](visualization::Visualizer *vis) {
                    downsampled->EstimateNormals(
                      open3d::geometry::KDTreeSearchParamKNN(30));//最近邻搜索
//                  downsampled->EstimateNormals(
//                    open3d::geometry::KDTreeSearchParamHybrid(0.1, 30));
//                  downsampled->EstimateNormals(
//                    open3d::geometry::KDTreeSearchParamRadius(0.1)); //半径搜索
                  utility::LogInfo("Done.");
                  return true;
              }}},
            "Press Space to Estimate Normal", 1600, 900);

    cout<<downsampled->normals_[0]<<endl;//打印第 0 个点的法线向量

结果如下:

《Open3D点云库 C++学习笔记 》_第1张图片

二、离群点去除

点云异常值去除方法主要包括:统计学离群点去除和半径离群点去除。

1.统计学离群点去除

RemoveStatisticalOutliers(统计学离群点去除方法)与点云的平均值相比,删除离群较远的点。它需要两个输入参数:

  • nb_neighbors,指定使用多少个邻近点来计算给定点的平均距离。

  • std_ratio,根据跨点云平均距离的标准偏差来设置阈值水平。这个数字越低,过滤器就越激进。
    在这里插入图片描述

代码如下:

 // Point cloud outlier removal
      string pointcloud_path ="../data/fragment.pcd";  //读取文件的地址

      std::shared_ptr<geometry::PointCloud> pointcloud = io::CreatePointCloudFromFile(pointcloud_path);

      if (pointcloud == nullptr) {
          utility::LogWarning("Unable to load pointcloud file.");
          return -1;
      }; //检查文件是否为空

      Eigen::Vector3d color(1.0,0,0);//将所有点设置为红色

      pointcloud->open3d::geometry::PointCloud::PaintUniformColor(color);//把整个点云设置为灰色

      auto downsampled = pointcloud->VoxelDownSample(0.03);//对点云进行下采样

      auto inlier =std::get<0>(downsampled->RemoveStatisticalOutliers(30,1.0)); //0返回正常值点云
      auto indices_vec =std::get<1>(downsampled->RemoveStatisticalOutliers(30,1.0));  //1返回正常值的索引vector

      for (size_t i = 0; i < indices_vec.size(); i++) {

              downsampled->colors_[indices_vec[i]] =
                      Eigen::Vector3d(0.5,0.5,0.5);  //正常值设置成灰色
          }

      visualization::DrawGeometries({downsampled}, "outlier removal", 1600, 900);

结果如下,其中显示了离群点(红色)和内部值(灰色:

《Open3D点云库 C++学习笔记 》_第2张图片

2.半径离群点去除

RemoveRadiusOutlier函数,用来删除在它们周围给定球体中几乎没有邻近点的点。可以使用两个参数来调整过滤器以适应不同输入数据:

  • nb_points,用来选择球体应包含的最少点数。

  • radius,定义了用于计算邻近点的球体半径。

代码如下:

//RemoveRadiusOutliers方法

      Eigen::Vector3d color1(0.5,0.5,0.5);//将所有点设置为灰色

      pointcloud->open3d::geometry::PointCloud::PaintUniformColor(color1);//把整个点云设置为灰色

      auto downsampled1 = pointcloud->VoxelDownSample(0.03);//对点云进行下采样

      auto inlier1 =std::get<0>(downsampled1->RemoveRadiusOutliers(16,0.09)); //0返回正常值点云

      visualization::DrawGeometries({inlier1}, "RemoveRadiusOutliers", 1600, 900);

去除离群点结果如下:
《Open3D点云库 C++学习笔记 》_第3张图片


三、参考资料

http://www.open3d.org/docs/latest/tutorial/geometry/pointcloud_outlier_removal.html

总结

以上就是几何篇(二)的全部内容,完整的可执行代码可以在我的github仓库进行下载,文章会持续更新,如果文章中有写的不对的地方,希望大家可以在评论区进行批评和指正,大家一起交流,共同进步!

你可能感兴趣的:(c++,3d)