/// <summary> /// Algorithm based on ignoring points with less neighbours int thresholdNeighboursCount = 10; float thresholdDistance = 15e-5f; /// at given distance. /// </summary> /// <param name="source"></param> /// <param name="threshold"></param> /// <returns></returns> public static PointCloud ByLessNeighbours(PointCloud source, float thresholdDistance, int thresholdNeighboursCount) { PointCloud pcResult = new PointCloud(); KDTreeKennell kdTree = new KDTreeKennell(); kdTree.Build(source); VertexKDTree[] resultArray = new VertexKDTree[source.Count]; try { List <Vector3> listV = new List <Vector3>(); List <Vector3> listC = new List <Vector3>(); System.Threading.Tasks.Parallel.For(0, source.Count, i => { VertexKDTree vSource = new VertexKDTree(source.Vectors[i], source.Colors[i], i); int neighboursCount = 0; kdTree.FindClosestPoints_Radius(vSource, thresholdDistance, ref neighboursCount); if (neighboursCount >= thresholdNeighboursCount) { resultArray[i] = vSource; } }); for (int i = 0; i < source.Count; i++) { if (resultArray[i] != null) { listV.Add(resultArray[i].Vector); listC.Add(resultArray[i].Color); } } pcResult.Vectors = listV.ToArray(); pcResult.Colors = listC.ToArray(); pcResult.SetDefaultIndices(); } catch (Exception err) { System.Windows.Forms.MessageBox.Show("Error in KDTreeKennnellRemoveDuplicates: " + err.Message); } return(pcResult); }
public static PointCloud CreateCube24() { Vector3[] vArray = new Vector3[] { new Vector3(1, 1, -1), new Vector3(-1, 1, -1), new Vector3(-1, 1, 1), new Vector3(1, 1, 1), new Vector3(1, -1, 1), new Vector3(-1, -1, 1), new Vector3(-1, -1, -1), new Vector3(1, -1, -1), new Vector3(1, 1, 1), new Vector3(-1, 1, 1), new Vector3(-1, -1, 1), new Vector3(1, -1, 1), new Vector3(1, -1, -1), new Vector3(-1, -1, -1), new Vector3(-1, 1, -1), new Vector3(1, 1, -1), new Vector3(-1, 1, 1), new Vector3(-1, 1, -1), new Vector3(-1, -1, -1), new Vector3(-1, -1, 1), new Vector3(1, 1, -1), new Vector3(1, 1, 1), new Vector3(1, -1, 1), new Vector3(1, -1, -1) }; PointCloud pc = new PointCloud(vArray, null, null, null, null, null); pc.SetDefaultIndices(); return(pc); }
/// <summary> /// tree.RemoveOutliersByDeviation(PointCloudDirty, 10, 1.3f); /// </summary> /// <param name="source"></param> /// <param name="numberOfNeighbours"></param> /// <param name="stdMultiplier"></param> /// <returns></returns> public static PointCloud ByStandardDeviation(PointCloud source, int numberOfNeighbours, float stdDeviationMultiplier, out PointCloud pcOutliersMarkedRed) { PointCloud pcResult = new PointCloud(); //the outliers are marked red pcOutliersMarkedRed = source.Clone(); float meanDistance, standardDeviation; float[] distances; //1. get standard deviation, meanDistance and array of distances StandardDeviation(source, numberOfNeighbours, out meanDistance, out standardDeviation, out distances); int numberRemoved = 0; VertexKDTree[] resultArray = new VertexKDTree[source.Count]; VertexKDTree[] outliers = new VertexKDTree[source.Count]; try { List <Vector3> listV = new List <Vector3>(); List <Vector3> listC = new List <Vector3>(); //2. distance threshold: deviation plus the overall mean distance float distanceThreshold = meanDistance + standardDeviation; //3. remove all points according to the distance threshold for (int i = 0; i < source.Count; i++) { VertexKDTree vSource = new VertexKDTree(source.Vectors[i], source.Colors[i], i); if (distances[i] > distanceThreshold) { pcOutliersMarkedRed.Colors[i] = new Vector3(1, 0, 0); numberRemoved++; continue; } else { resultArray[i] = vSource; } } List <Vector3> listOutliers = new List <Vector3>(); List <Vector3> listOutliersColors = new List <Vector3>(); //build resulting cloud and outliers for (int i = 0; i < source.Count; i++) { if (resultArray[i] != null) { listV.Add(resultArray[i].Vector); listC.Add(resultArray[i].Color); } } pcResult.Vectors = listV.ToArray(); pcResult.Colors = listC.ToArray(); pcResult.SetDefaultIndices(); System.Diagnostics.Debug.WriteLine("Outliers: Mean distance---" + meanDistance.ToString("G") + " ---- standard deviation ---" + standardDeviation.ToString("G") + "---Number of outliers: " + numberRemoved.ToString()); } catch (Exception err) { System.Windows.Forms.MessageBox.Show("Error in KDTreeKennnellRemoveDuplicates: " + err.Message); } return(pcResult); }