PclSharp--ExtractIndices滤波器分割子集

10 篇文章 2 订阅

1、使用ExtractIndices滤波器,可以提取出点云中的子集。

2、代码:

using PclSharp;
using PclSharp.Common;
using PclSharp.Filters;
using PclSharp.Helpers;
using PclSharp.IO;
using PclSharp.SampleConsensus;
using PclSharp.Segmentation;
using PclSharp.Std;
using PclSharp.Struct;
using System;
using System.Numerics;
using System.Text;

namespace PclSharpTest
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine($"C#--PclSharp算法库测试:");
            //读取点云文件
            var inCloud = new PointCloudOfXYZ();
            using (var reader = new PCDReader())
                reader.Read(AppDomain.CurrentDomain.BaseDirectory + $"//pcd//table.pcd", inCloud);
           Console.WriteLine($"PointCloud before filtering:{inCloud.Count}data points");

            //采用体素化滤波进行下采样:
            PointCloudOfXYZ cloud_filtered = new PointCloudOfXYZ();//滤波后的点云
            PointXYZ voxelpointXYZ = new PointXYZ { X = 0.01f, Y = 0.01f, Z = 0.01f };
            using (var sor = new PclSharp.Filters.VoxelGridOfXYZ())
            {
                sor.SetInputCloud(inCloud);
                sor.LeafSize = voxelpointXYZ;//体素点的大小
                sor.filter(cloud_filtered);
            }
            //保存下采样后点云
            using (var reader = new PCDWriter())
            {
                reader.Write($"{AppDomain.CurrentDomain.BaseDirectory}pcd\\downsampled.pcd", cloud_filtered, false);
            }
            // 创建分割对象
            var seg = new SACSegmentationOfXYZ();
            seg.OptimizeCoefficients = true;//设置对估计的模型做优化处理
            seg.ModelType = SACModel.Plane;//设置分割的是平面
            seg.MethodType = SACMethod.RANSAC;//设置使用那个随机参数估计方法
            seg.MaxIterations = 1000;//迭代次数
            seg.DistanceThreshold = 0.01;// 需要调的参数,表示离平面多少距离范围内的点会被分到平面上,值越大越有可能将平面上别的物体错误划分到平面上。

            var cloud_p= new PointCloudOfXYZ();
            var cloud_f = new PointCloudOfXYZ();
            var coefficients = new ModelCoefficients();
            var inliers = new PointIndices();
            var extract = new ExtractIndicesOfXYZ();
            int i = 0;
            int nr_points = cloud_filtered.Count;
            while (cloud_filtered.Count > 0.3 * nr_points)
            {
                seg.SetInputCloud(cloud_filtered);
                //存储分割结果到点集合inliers及存储平面模型的系数coefficients
                seg.Segment(inliers, coefficients);
                if (inliers.Indices.Count == 0)
                {
                    Console.WriteLine("Could not estimate a planar model for the given dataset." );
                    break;
                }
                
                extract.SetInputCloud(cloud_filtered);
                extract.SetIndices(inliers.Indices);
                extract.Negative = false;
                extract.filter(cloud_p);

                Console.WriteLine($"cloud_filtered:{cloud_filtered.Count}"  );
                Console.WriteLine("-----------------------------------------" );
                Console.WriteLine($"PointCloud representing the planar compoent: {cloud_p.Count} data points");

                //保存点云
                StringBuilder sb = new StringBuilder();
                sb.Append($"{AppDomain.CurrentDomain.BaseDirectory}pcd\\");
                sb.Append($"plane_{i}" + ".pcd");
                using (var reader = new PCDWriter())
                {
                   reader.Write(sb.ToString(), cloud_p, false);
                }
                extract.Negative=true; //提取外层
                extract.filter(cloud_f); //将外层的提取结果保存到cloud_f中
                cloud_filtered.Swap(cloud_f); //经cloud_filtered与cloud_f进行交换
                i++;
            }

            var cloud_seg1 = new PointCloudOfXYZ();
            var cloud_seg2 = new PointCloudOfXYZ();
            var cloud_voxel = new PointCloudOfXYZ();

            using (var reader = new PCDReader())
                reader.Read(AppDomain.CurrentDomain.BaseDirectory + $"//pcd//plane_0.pcd", cloud_seg1);
            using (var reader = new PCDReader())
                reader.Read(AppDomain.CurrentDomain.BaseDirectory + $"//pcd//plane_1.pcd", cloud_seg2);
            using (var reader = new PCDReader())
                reader.Read(AppDomain.CurrentDomain.BaseDirectory + $"//pcd//downsampled.pcd", cloud_voxel);

            using (var visualizer = new PclSharp.Vis.Visualizer(" visual window"))
            {
                //创建两个观察视点
                int v1 = 0;
                int v2 = 1;
                int v3 = 2;
                int v4 = 3;
                visualizer.CreateViewPort(0.0, 0.0, 0.25, 1.0, v1);
                visualizer.CreateViewPort(0.25, 0.0, 0.5, 1.0, v2);
                visualizer.CreateViewPort(0.5, 0.0, 0.75, 1.0, v3);
                visualizer.CreateViewPort(0.75, 0.0, 1.0, 1.0, v4);
                //设置背景色
                visualizer.SetBackgroundColor_ViewPort(0f,0f,0f,v1);
                visualizer.SetBackgroundColor_ViewPort(0.05f, 0f, 0f,v2);

                //添加点云
                
                //visualizer.AddPointCloud(cloud_filtered, "v1", v1);
                visualizer.AddPointCloud(cloud_seg1, "v1", v1);
                visualizer.AddPointCloud(cloud_seg2, "v2", v2);
                visualizer.AddPointCloud(cloud_filtered, "v3", v3);
                visualizer.AddPointCloud(cloud_voxel, "v4", v4);

                visualizer.SetPointCloudColor(1, 1, 0.5, "v1");//点云附色
                visualizer.SetPointCloudColor(1, 0.5, 1, "v2");//点云附色
                visualizer.SetPointCloudColor(1, 1, 0.5, "v3");//点云附色
                visualizer.SetPointCloudColor(1, 0.5, 1, "v4");//点云附色
                while (!visualizer.WasStopped)
                    visualizer.SpinOnce(100);
            }
            Console.ReadKey();
        }

    }
}
3、编译结果

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

西~风

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值