1、给予颜色的区域生长分割算法与区域生长算法一样,是基于同一策略之上的,其基本思想可参考区域生长算法相关章节。与区域生长算法相比,该算法主要有两个不同之处。第一,该算法用颜色测试代替了法线测试。第二,利用合并算法来控制过分割或欠分割。分割过程中,若两个相邻聚类的平均颜色相差较少,则将这两个聚类合并。然后进行第二步合并,在此步骤中,检查每一个聚类所包含的点的数量,如果这个数量小于用户定义的值,则当前这个聚类与其最近邻聚类合并在一起。
2、代码:
using PclSharp;
using PclSharp.Common;
using PclSharp.Features;
using PclSharp.Filters;
using PclSharp.IO;
using PclSharp.SampleConsensus;
using PclSharp.Search;
using PclSharp.Segmentation;
using PclSharp.Std;
using PclSharp.Struct;
using System;
using System.Numerics;
namespace PclSharpTest
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine($"C#--PclSharp算法库测试:");
bool Bool_cutting = false;
bool bn = true;
//1、读取点云数据
var src_cloud = new PointCloudOfXYZRGB();
using (var reader = new PCDReader())
reader.Read(AppDomain.CurrentDomain.BaseDirectory + $"//pcd//two_human.pcd", src_cloud);
//Console.WriteLine($"src_cloud has {src_cloud.Count} data points");
//2、点云进行法线估计
var normals = new PointCloudOfNormal();//法线点云
var tree = new KdTreeOfXYZRGB();
using (var ne = new NormalEstimationOfPointXYZRGBAndNormal())//法线估计对象
{
ne.SetSearchMethod(tree);//设置搜索方式
ne.SetInputCloud(src_cloud);//设置输入点云
ne.KSearch = 50; //设置k近邻点的个数
ne.Compute(normals);//执行法线估计
}
//3、直通滤波
var indices = new VectorOfInt();//声明一个索引
if (Bool_cutting)
{
using (var pass = new PclSharp.Filters.PassThroughOfXYZRGB())
{
pass.SetInputCloud(src_cloud);
pass.SetIndices(indices);
pass.FilterFieldName = "z";//指定进行过滤的字段
pass.FilterLimits = (0, 10f);//设置在过滤字段上的范围
pass.filter(indices);
}
}
//4、区域生长的分割
var reg = new RegionGrowingRGBOfXYZRGB();//进行基于颜色生长的分割
reg.SetInputCloud(src_cloud);//设置输入点云
if (Bool_cutting) reg.SetIndices(indices);//通过输入参数设置,确定是否输入点云的索引
reg.SetSearchMethod(tree);//设置搜索方式
reg.DistanceThreshold = 10.0f;
reg.PointColorThreshold = 6.0f;
reg.RegionColorThreshold = 5.0f;
reg.MinClusterSize = 600;//设置聚类所需要的最小点数
if (bn)
{
reg.SmoothModeFlag = true;
reg.CurvatureTestFlag = true;
reg.SetInputNormals(normals);//输入点云的法向量
reg.SmoothnessThreshold = (float)(30.0 / 180.0 * Math.PI);//设置平滑阈值
reg.CurvatureThreshold = 0.05f;//设置曲率阈值
}
//获取聚类的结果,将分割结果保存在点云索引的向量中
var clusters = new VectorOfPointIndices();//用动态数组保存聚类的结果
reg.Extract(clusters);
//对于不同的聚类分割结果,随机 赋予颜色(不能保证不同的聚类颜色一定不同)
PointCloudOfXYZRGB colored_cloud = reg.ColoredCloud;
using (var viewer = new PclSharp.Vis.CloudViewer("基于颜色的区域生长分割"))
{
viewer.ShowCloud(colored_cloud);
while (!viewer.WasStopped);
}
Console.ReadKey();
}
}
}
3、编译结果