本章节将主要介绍点云的法线估计和离群点去除。
点云的另一个基本操作是点的法线估计。按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 个点的法线向量
结果如下:
点云异常值去除方法主要包括:统计学离群点去除和半径离群点去除。
RemoveStatisticalOutliers(统计学离群点去除方法)与点云的平均值相比,删除离群较远的点。它需要两个输入参数:
代码如下:
// 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);
结果如下,其中显示了离群点(红色)和内部值(灰色:
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);
http://www.open3d.org/docs/latest/tutorial/geometry/pointcloud_outlier_removal.html
以上就是几何篇(二)的全部内容,完整的可执行代码可以在我的github仓库进行下载,文章会持续更新,如果文章中有写的不对的地方,希望大家可以在评论区进行批评和指正,大家一起交流,共同进步!