public PointCloudVertices FindNearest_BruteForceOld(PointCloudVertices vSource, PointCloudVertices vTarget)
        {
            PointCloudVertices nearestNeighbours = new PointCloudVertices();
            int iMax = 10;
            PointCloudVertices tempTarget = PointCloudVertices.CopyVertices(vTarget);

            for (int i = 0; i < vSource.Count; i++)
            {
                //BuildKDTree_Standard(tempTarget);

                Vertex p = vSource[i];
                // Perform a nearest neighbour search around that point.
                KDTreeRednaxela.NearestNeighbour <EllipseWrapper> pIter = null;
                pIter = KdTree_Rednaxela.FindNearest_EuclidDistance(new float[] { Convert.ToSingle(p.Vector.X), Convert.ToSingle(p.Vector.Y), Convert.ToSingle(p.Vector.Z) }, iMax, -1);
                while (pIter.MoveNext())
                {
                    // Get the ellipse.
                    //var pEllipse = pIter.Current;
                    EllipseWrapper wr = pIter.CurrentPoint;
                    nearestNeighbours.Add(wr.Vertex);
                    tempTarget.RemoveAt(pIter.CurrentIndex);
                    break;
                }
            }
            return(nearestNeighbours);
        }
        private void RemovePointsByAngle(ref PointCloudVertices pointsSource, ref PointCloudVertices pointsTarget, List <List <Neighbours> > listNeighbours)
        {
            if (Normals_RemovePoints)
            {
                //adjust normals - because of Search, the number of PointTarget my be different

                int pointsRemoved = 0;
                for (int i = pointsTarget.Count - 1; i >= 0; i--)
                {
                    Vector3d vT = pointsTarget[i].Vector;
                    Vector3d vS = pointsSource[i].Vector;
                    //float angle = Vector3d.CalculateAngle(vT, vS);
                    int     indexVec = pointsTarget[i].IndexInModel;
                    Vector3 vTNormal = NormalsTarget[pointsTarget[i].IndexInModel];
                    //Vector3d vTNormal = NormalsTarget[i];
                    Vector3 vSNormal = NormalsSource[i];

                    float angle = vTNormal.AngleInDegrees(vSNormal);
                    //float angle = vT.AngleInDegrees(vS);
                    float angleToCheck = 30;// (this.startAngleForNormalsCheck - 5) * (1 - this.NumberOfIterations / this.ICPSettings.MaximumNumberOfIterations) + 5;
                    Debug.WriteLine("Angle: " + i.ToString() + " : " + angle.ToString("0.00"));

                    if (Math.Abs(angle) > angleToCheck)
                    {
                        pointsTarget.RemoveAt(i);
                        pointsSource.RemoveAt(i);
                        pointsRemoved++;
                    }
                }
                Debug.Assert(pointsTarget.Count > 2, "Error after kdtree - checking normals : Should have at least 3 points found");

                Debug.WriteLine("--NormalCheck: Removed a total of: " + pointsRemoved.ToString());
            }
        }
        private void RemovePointsWithDistanceGreaterThanMedian(List <float> listDistances, PointCloudVertices pointsSource, PointCloudVertices pointsTarget)
        {
            float median = GetMedian(listDistances);

            for (int i = listDistances.Count - 1; i >= 0; i--)
            {
                if (listDistances[i] > median)
                {
                    pointsSource.RemoveAt(i);
                    pointsTarget.RemoveAt(i);
                }
            }
        }
        private void RemovePointsWithDistanceGreaterThanAverage(PointCloudVertices pointsSource, PointCloudVertices pointsTarget, List <List <Neighbours> > listNeighbours)
        {
            float median = GetAverage(listNeighbours);

            for (int i = listNeighbours.Count - 1; i >= 0; i--)
            {
                if (listNeighbours[i][0].Distance > median)
                {
                    pointsSource.RemoveAt(i);
                    pointsTarget.RemoveAt(i);
                }
            }
        }
        public PointCloudVertices FindNearest_BruteForce(PointCloudVertices source, PointCloudVertices target)
        {
            PointCloudVertices result             = new PointCloudVertices();
            List <int>         indicesTargetFound = new List <int>();

            PointCloudVertices tempTarget = PointCloudVertices.CopyVertices(target);

            for (int i = source.Count - 1; i >= 0; i--)
            {
                BuildKDTree_Stark(tempTarget);

                int indexNearest = KdTree_Stark.FindNearest(source[i]);
                result.Add(target[indexNearest]);
                tempTarget.RemoveAt(indexNearest);
            }

            return(result);
        }
        public PointCloudVertices FindNearest_Stark(PointCloudVertices source, PointCloudVertices target)
        {
            KdTree_Stark.ResetSearch();
            PointCloudVertices result = new PointCloudVertices();

            List <int>         pointsFound      = new List <int>();
            List <List <int> > searchdoubleList = new List <List <int> >(3);

            for (int i = source.Count - 1; i >= 0; i--)
            //for (int i = 0; i < source.Count ; i ++)
            {
                //int indexNearest = KdTree_Stark.FindNearest(source[i]);
                int indexNearest = KdTree_Stark.FindNearestAdapted(source[i], pointsFound);

                //result.Add(target[indexNearest]);

                if (!pointsFound.Contains(indexNearest))
                {
                    pointsFound.Add(indexNearest);
                    result.Add(target[indexNearest]);
                }
                else
                {
                    bool bfound = false;
                    for (int j = 0; j < KDTree_Stark.LatestSearchResults.Count; j++)
                    {
                        int newIndex = KDTree_Stark.LatestSearchResults[j].Key;
                        if (!pointsFound.Contains(newIndex))
                        {
                            bfound = true;
                            pointsFound.Add(newIndex);
                            result.Add(target[newIndex]);
                            break;
                        }
                    }
                    if (!bfound)
                    {
                        source.RemoveAt(i);
                    }
                }
            }

            return(result);
        }
        public PointCloudVertices FindNearest_Rednaxela_ExcludePoints(PointCloudVertices source, PointCloudVertices target, bool findNormals)
        {
            NumberOfNeighboursToSearch = source.Count;
            FindNearest_NormalsCheck_Rednaxela(source, findNormals);

            PointCloudVertices result = new PointCloudVertices();

            float totalDistance = 0;


            int i       = -1;
            int loopMax = source.Count;

            if (target.Count < loopMax)
            {
                loopMax = target.Count;

                for (i = source.Count - 1; i >= loopMax; i--)
                {
                    source.RemoveAt(i);
                }
            }

            try
            {
                for (i = 0; i < loopMax; i++)
                {
                    totalDistance += source[i].KDTreeSearch[0].Value;
                    result.Add(target[source[i].KDTreeSearch[0].Key]);
                }
            }
            catch
            {
                System.Windows.Forms.MessageBox.Show("Error setting search key at: " + i.ToString());
            }
            MeanDistance = totalDistance / loopMax;



            return(result);
        }
        public PointCloudVertices FindNearest_Rednaxela(ref PointCloudVertices mypointsSource, PointCloudVertices mypointsTarget, float angleThreshold)
        {
            this.pointsSource = mypointsSource;
            this.pointsTarget = mypointsTarget;

            int indexI = -1;

            try
            {
                PointCloudVertices pointsSourceNew = new PointCloudVertices(pointsSource);
                PointCloudVertices pointsResult    = new PointCloudVertices();


                FindNearest_Rednaxela_Helper();



                for (int i = 0; i < listNeighbours.Count; i++)
                {
                    indexI = i;
                    List <Neighbours> mySublist = listNeighbours[i];
                    mySublist.Sort(new NeighboursComparer());
                    Vertex v = pointsTarget[mySublist[0].IndexTarget];
                    pointsResult.Add(v);
                }
                if (Normals_RemovePoints)
                {
                    listNeighbours.Sort(new NeighboursListComparer());
                    int minPoints = Math.Min(10, listNeighbours.Count - 1);


                    for (int i = 0; i < listNeighbours.Count; i++)
                    {
                        List <Neighbours> mySublist = listNeighbours[i];
                        int    indexInsert          = mySublist[0].IndexSource;
                        Vertex vSource = pointsSource[mySublist[0].IndexSource];
                        Vertex vTarget = pointsTarget[mySublist[0].IndexTarget];

                        pointsSourceNew[indexInsert] = vSource;
                        pointsResult[indexInsert]    = vTarget;


                        if (i > minPoints)
                        {
                            if (mySublist[0].Angle > angleThreshold)
                            {
                                pointsSourceNew[indexInsert] = null;
                                pointsResult[indexInsert]    = null;
                            }
                        }
                    }
                    for (int i = pointsSource.Count - 1; i >= 0; i--)
                    {
                        if (pointsSourceNew[i] == null)
                        {
                            pointsSourceNew.RemoveAt(i);
                            pointsResult.RemoveAt(i);
                        }
                    }

                    Debug.WriteLine("Remaining points : " + (pointsResult.Count * 1.0 / pointsTarget.Count * 100).ToString("0.00") + " %");
                }

                this.MeanDistance = PointCloudVertices.MeanDistance(pointsResult, pointsSource);
                pointsSource      = pointsSourceNew;

                if (pointsSource.Count != pointsResult.Count)
                {
                    MessageBox.Show("Error finding neighbours, found " + pointsResult.Count.ToString() + " out of " + pointsSource.Count.ToString());
                    //return false;
                }

                mypointsSource = this.pointsSource;
                return(pointsResult);
            }
            catch (Exception err)
            {
                System.Windows.Forms.MessageBox.Show("Error in Finding neighbors at: " + indexI.ToString() + " : " + err.Message);
                return(null);
            }
        }
Exemple #9
0
        public PointCloudVertices PerformICP_Stitching()
        {
            int iPoint = 0;

            try
            {
                PointCloudVertices pointsTarget = null;
                PointCloudVertices pointsSource = null;

                ICPSolution res = CalculateStartSolution(ref pointsSource, ref pointsTarget, ICPSettings.NumberOfStartTrialPoints, this.LandmarkTransform, this.PTarget, this.PSource, ICPSettings.MaximumNumberOfIterations);
                if (res == null)
                {
                    return(null);
                }

                Matrix4d myMatrix = res.Matrix;



                double oldMeanDistance = 0;
                //now try all points and check if outlier
                for (iPoint = (pointsTarget.Count - 1); iPoint >= 0; iPoint--)
                {
                    double distanceOfNewPoint = CheckNewPointDistance(iPoint, myMatrix, pointsTarget, pointsSource);

                    ////experimental

                    ////--compare this distance to:
                    //pointsTargetTrial.Add[pointsTargetTrial.Count, p1[0], p1[1], p1[2]);
                    //pointsSourceTrial.Add[pointsSourceTrial.Count, p2[0], p2[1], p2[2]);
                    //PointCloud tempPointRotateAll = TransformPoints(pointsSourceTrial, myMatrix, pointsSourceTrial.Count);


                    //dist = CalculateTotalDistance(pointsTargetTrial, tempPointRotateAll);
                    //DebugWriteUtils.WriteTestOutput(myMatrix, pointsSourceTrial, tempPointRotateAll, pointsTargetTrial, pointsTargetTrial.Count);
                    Debug.WriteLine("------>ICP Iteration Trial: " + iPoint.ToString() + " : Mean Distance: " + distanceOfNewPoint.ToString());
                    if (Math.Abs(distanceOfNewPoint - res.MeanDistance) < ICPSettings.ThresholdOutlier)
                    {
                        PointCloudVertices pointsTargetTrial = PointCloudVertices.CopyVertices(res.PointsTarget);
                        PointCloudVertices pointsSourceTrial = PointCloudVertices.CopyVertices(res.PointsSource);


                        myMatrix = TryoutNewPoint(iPoint, pointsTarget, pointsSource, pointsTargetTrial, pointsSourceTrial, this.LandmarkTransform);

                        PointCloudVertices myPointsTransformed = MathUtilsVTK.TransformPoints(pointsSourceTrial, myMatrix);
                        this.MeanDistance = PointCloudVertices.MeanDistance(pointsTargetTrial, myPointsTransformed);
                        // this.MeanDistance = totaldist / Convert.ToSingle(pointsTargetTrial.Count);


                        DebugWriteUtils.WriteTestOutputVertex("Iteration " + iPoint.ToString(), myMatrix, pointsSourceTrial, myPointsTransformed, pointsTargetTrial);

                        //could also remove this check...
                        if (Math.Abs(oldMeanDistance - this.MeanDistance) < ICPSettings.ThresholdOutlier)
                        {
                            res.PointsTarget      = pointsTargetTrial;
                            res.PointsSource      = pointsSourceTrial;
                            res.Matrix            = myMatrix;
                            res.PointsTransformed = myPointsTransformed;
                            oldMeanDistance       = this.MeanDistance;

                            //Debug.WriteLine("************* Point  OK : ");
                            DebugWriteUtils.WriteTestOutputVertex("************* Point  OK :", myMatrix, res.PointsSource, myPointsTransformed, res.PointsTarget);
                        }
                        //remove point from point list
                        pointsTarget.RemoveAt(iPoint);
                        pointsSource.RemoveAt(iPoint);
                    }
                }
                this.Matrix = res.Matrix;
                //System.Diagnostics.Debug.WriteLine("Solution of ICP is : ");
                DebugWriteUtils.WriteTestOutputVertex("Solution of ICP", Matrix, res.PointsSource, res.PointsTransformed, res.PointsTarget);
                pointsTransformed = res.PointsTransformed;

                return(pointsTransformed);
            }
            catch (Exception err)
            {
                System.Windows.Forms.MessageBox.Show("Error in Update ICP at point: " + iPoint.ToString() + " : " + err.Message);
                return(null);
            }
            //Matrix4d newMatrix = accumulate.GetMatrix();
            //this.Matrix = newMatrix;
        }