/// <summary> /// </summary> /// <param name="cloud"></param> /// <param name="detectionParameters"></param> /// <param name="mergingParameters"></param> /// <returns></returns> public IList <Tree> DetectPotentialTrees(Cloud cloud, DetectionParameters detectionParameters, MergingParameters mergingParameters) { var pointSets = DetectTrunkPointSets(cloud, detectionParameters).SelectMany(group => group.PointSets).ToList(); var pointSetGroup = new PointSetGroup(pointSets); var potentialTrees = pointSetGroup.BuildTrees(mergingParameters); return(FilterTrees(potentialTrees, detectionParameters.TreeFilters)); }
/// <summary> /// Extracts height-based collection of PointSetGroups that are considered as part of tree trunk. /// </summary> /// <param name="cloud"></param> /// <param name="detectionParameters"></param> /// <returns></returns> public IList <PointSetGroup> DetectTrunkPointSets(Cloud cloud, DetectionParameters detectionParameters) { _logger?.LogInformation("Starting cloud slicing..."); var slices = cloud.Slice(detectionParameters.SliceHeight).ToList(); _logger?.LogInformation("Cloud sliced"); _logger?.LogTrace($"Slices count: {slices.Count}"); _logger?.LogInformation("Starting point grouping..."); var groups = slices.Select(slice => slice?.GroupByDistance(detectionParameters.MeshWidth, detectionParameters.MinimalPointsPerMesh) ).Where(slice => slice != null).ToList(); _logger?.LogInformation("Points grouped..."); _logger?.LogInformation("Starting filtering..."); return(groups.Select((group, index) => { ProgressTracker.Progress(EProgressStage.NoiseFiltering, "Filtering Noise", index, groups.Count); return @group.Filter(detectionParameters.PointSetFilters); }).Where(x => x != null).ToList()); }