private static ICPSolution IterateStartPoints(List <Vertex> pointsTarget, List <Vertex> pointsSource, int myNumberPoints, LandmarkTransform myLandmarkTransform, int maxNumberOfIterations)
        {
            int maxIterationPoints = pointsSource.Count;
            int currentIteration   = 0;

            try
            {
                if (myNumberPoints > pointsSource.Count)
                {
                    myNumberPoints = pointsSource.Count;
                }

                List <ICPSolution> solutionList = new List <ICPSolution>();

                for (currentIteration = 0; currentIteration < maxNumberOfIterations; currentIteration++)
                {
                    ICPSolution res = ICPSolution.SetRandomIndices(myNumberPoints, maxIterationPoints, solutionList);


                    res.Matrix            = TryoutPoints(pointsTarget, pointsSource, res, myLandmarkTransform);//, accumulate);
                    res.PointsTransformed = MathUtils.TransformPoints(res.PointsSource, res.Matrix);

                    double totaldist = PointUtils.CalculateTotalDistance(res.PointsTarget, res.PointsTransformed);
                    res.MeanDistance = totaldist / Convert.ToDouble(res.PointsSource.Count);

                    solutionList.Add(res);
                }


                if (solutionList.Count > 0)
                {
                    solutionList.Sort(new ICPSolutionComparer());
                    RemoveSolutionIfMatrixContainsNaN(solutionList);
                    if (solutionList.Count == 0)
                    {
                        System.Windows.Forms.MessageBox.Show("No start solution could be found !");
                    }


                    Debug.WriteLine("Solutions found after: " + currentIteration.ToString() + " iterations, number of solution " + solutionList.Count.ToString());

                    if (solutionList.Count > 0)
                    {
                        ICPSolution result = solutionList[0];
                        //write solution to debug ouput
                        //System.Diagnostics.Debug.WriteLine("Solution of start sequence is: ");
                        DebugWriteUtils.WriteTestOutputVertex("Solution of start sequence", result.Matrix, result.PointsSource, result.PointsTransformed, result.PointsTarget);
                        return(result);
                    }
                }
                return(null);
            }
            catch (Exception err)
            {
                System.Windows.Forms.MessageBox.Show("Error in IterateStartPoints of ICP at: " + currentIteration.ToString() + " : " + err.Message);
                return(null);
            }
        }
        private List <Vertex> ICPOnPoints_WithSubset(List <Vertex> myVerticesTarget, List <Vertex> myVerticesToBeMatched, List <Vertex> myPointsTargetSubset, List <Vertex> mypointsSourceSubset)
        {
            List <Vector3d> myVectorsTransformed  = null;
            List <Vertex>   myVerticesTransformed = null;

            try
            {
                Matrix4d m;


                PerformICP(myPointsTargetSubset, mypointsSourceSubset);
                myVectorsTransformed = Vertices.ConvertToVector3dList(PTransformed);
                m = Matrix;

                //DebugWriteUtils.WriteTestOutput(m, mypointsSourceSubset, myPointsTransformed, myPointsTargetSubset);
                //extend points:
                //myPointsTransformed = icpSharp.TransformPointsToPointsData(mypointsSourceSubset, m);
                //-----------------------------
                //DebugWriteUtils.WriteTestOutput(m, mypointsSourceSubset, myPointsTransformed, myPointsTargetSubset);

                //now with all other points as well...
                myVectorsTransformed = new List <Vector3d>();

                myVectorsTransformed  = MathUtils.TransformPoints(Vertices.ConvertToVector3dList(myVerticesToBeMatched), m);
                myVerticesTransformed = Vertices.ConvertVector3DListToVertexList(myVectorsTransformed);
                //write all results in debug output
                DebugWriteUtils.WriteTestOutputVertex("Soluation of Points With Subset", m, myVerticesToBeMatched, myVerticesTransformed, myVerticesTarget);
            }
            catch (Exception err)
            {
                System.Diagnostics.Debug.WriteLine("Error in ICP : " + err.Message);
                return(null);
            }
            //for output:


            return(myVerticesTransformed);
        }
Beispiel #3
0
        public List <Vertex> PerformICP()
        {
            List <Vertex> PT       = Vertices.CopyVertices(PTarget);
            List <Vertex> PS       = Vertices.CopyVertices(PSource);
            Vertex        pSOrigin = null;
            Vertex        pTOrigin = null;

            if (ResetVertexToOrigin)
            {
                pTOrigin = Vertices.ResetVertexToOrigin(PT);
                pSOrigin = Vertices.ResetVertexToOrigin(PS);
            }

            int keepOnlyPoints = 0;

            if (DistanceOptimization)
            {
                keepOnlyPoints = 3;
            }
            int iter = 0;

            try
            {
                if (!CheckSourceTarget(PT, PS))
                {
                    return(null);
                }

                List <Vertex> pointsTarget = Vertices.CopyVertices(PT);
                List <Vertex> pointsSource = Vertices.CopyVertices(PS);

                this.Matrix = Matrix4d.Identity;
                double oldMeanDistance = 0;

                KDTreeVertex kdTreee = Helper_CreateTree(pointsTarget);

                for (iter = 0; iter < MaximumNumberOfIterations; iter++)
                {
                    if (NormalsCheck)
                    {
                        CalculateNormals(pointsSource, pointsTarget);
                    }
                    if (SimulatedAnnealing)
                    {
                        if (Helper_ICP_Iteration_SA(PT, PS, kdTreee, keepOnlyPoints))
                        {
                            break;
                        }
                    }
                    else
                    {
                        if (Helper_ICP_Iteration(ref pointsTarget, ref pointsSource, PT, PS, kdTreee, keepOnlyPoints))
                        {
                            break;
                        }
                    }
                    oldMeanDistance = MeanDistance;
                    Debug.WriteLine("--------------Iteration: " + iter.ToString() + " : Mean Distance: " + MeanDistance.ToString("0.00000000000"));
                }

                Debug.WriteLine("--------****** Solution of ICP after : " + iter.ToString() + " iterations, and Mean Distance: " + MeanDistance.ToString("0.00000000000"));

                PTransformed = MathUtils.TransformPoints(PS, Matrix);
                //re-reset vector
                if (ResetVertexToOrigin)
                {
                    Vertices.AddVector(PTransformed, pTOrigin);
                    //Vertices.AddVector(PSource, pSOrigin);
                }

                DebugWriteUtils.WriteTestOutputVertex("Solution of ICP", Matrix, this.PSource, PTransformed, PTarget);

                return(PTransformed);
            }
            catch (Exception err)
            {
                System.Windows.Forms.MessageBox.Show("Error in Update ICP at iteration: " + iter.ToString() + " : " + err.Message);
                return(null);
            }
        }
Beispiel #4
0
        /// <summary>
        /// a simulated annealing like technique
        /// </summary>
        /// <param name="pointsTarget"></param>
        /// <param name="pointsSource"></param>
        /// <param name="myNumberPoints"></param>
        /// <param name="myLandmarkTransform"></param>
        /// <param name="maxSolutions"></param>
        /// <returns></returns>
        private static ICPSolution IterateSA(PointCloudVertices pointsSource, PointCloudVertices pointsTarget, int myNumberPoints, int maxSolutions)
        {
            int i = 0;

            //int currentIteration = 0;
            try
            {
                if (myNumberPoints > pointsTarget.Count)
                {
                    myNumberPoints = pointsTarget.Count;
                }

                List <ICPSolution> solutionList = new List <ICPSolution>();


                for (i = 0; i < maxSolutions; i++)
                {
                    ICPSolution myTrial = ICPSolution.SetRandomIndices(myNumberPoints, pointsSource.Count, solutionList);

                    //myTrial.PointsTargetTrial = RandomUtils.ExtractPoints(pointsTarget, myTrial.RandomIndices);
                    myTrial.PointsSource = RandomUtils.ExtractPoints(pointsSource, myTrial.RandomIndices);

                    //myTrial.Matrix = TryoutPointsSA(pointsTarget, pointsSource, myTrial, myLandmarkTransform);//, accumulate);

                    myTrial.PointsTransformed = MathUtilsVTK.TransformPoints(myTrial.PointsSource, myTrial.Matrix);

                    myTrial.MeanDistance = PointCloudVertices.MeanDistance(myTrial.PointsTarget, myTrial.PointsTransformed);
                    // myTrial.MeanDistance = totaldist / Convert.ToSingle(myTrial.PointsSource.Count);

                    solutionList.Add(myTrial);
                }

                if (solutionList.Count > 0)
                {
                    solutionList.Sort(new ICPSolutionComparer());
                    RemoveSolutionIfMatrixContainsNaN(solutionList);
                    if (solutionList.Count == 0)
                    {
                        System.Windows.Forms.MessageBox.Show("No start solution could be found !");
                    }


                    Debug.WriteLine("Solutions found after: " + i.ToString() + " iterations, number of solution " + solutionList.Count.ToString());

                    if (solutionList.Count > 0)
                    {
                        ICPSolution result = solutionList[0];
                        //write solution to debug ouput
                        //System.Diagnostics.Debug.WriteLine("Solution of start sequence is: ");
                        DebugWriteUtils.WriteTestOutputVertex("Solution of start sequence", result.Matrix, result.PointsSource, result.PointsTransformed, result.PointsTarget);
                        return(result);
                    }
                }
                return(null);
            }
            catch (Exception err)
            {
                System.Windows.Forms.MessageBox.Show("Error in IterateStartPoints of ICP at: " + i.ToString() + " : " + err.Message);
                return(null);
            }
        }
Beispiel #5
0
        public PointCloudVertices PerformICP()
        {
            double convergenceThreshold = PTarget.BoundingBoxMaxFloat * ICPSettings.ConvergenceThreshold;

            PointCloudVertices PT                  = PointCloudVertices.CopyVertices(PTarget);
            PointCloudVertices PS                  = PointCloudVertices.CopyVertices(PSource);
            Vertex             pSOrigin            = new Vertex(0, new Vector3d(0, 0, 0));
            Vertex             pTOrigin            = new Vertex(0, new Vector3d(0, 0, 0));
            PointCloudVertices myPointsTransformed = null;

            ICPSettings.ResetVertexToOrigin = false;
            if (ICPSettings.ResetVertexToOrigin)
            {
                pTOrigin = PointCloudVertices.ResetCentroid(PT, true);
                pSOrigin = PointCloudVertices.ResetCentroid(PS, true);
            }

            KDTreeVertex kdTreee = Helper_CreateTree(PT);

            kdTreee.DistanceOptimization = this.ICPSettings.DistanceOptimization;
            CalculateNormals(PS.ToPointCloud(), PT.ToPointCloud(), kdTreee);


            try
            {
                if (!CheckSourceTarget(PT, PS))
                {
                    return(null);
                }

                PointCloudVertices pointsTarget = PointCloudVertices.CopyVertices(PT);
                PointCloudVertices pointsSource = PointCloudVertices.CopyVertices(PS);

                this.Matrix = Matrix4d.Identity;
                double oldMeanDistance = 0;



                for (NumberOfIterations = 0; NumberOfIterations < ICPSettings.MaximumNumberOfIterations; NumberOfIterations++)
                {
                    kdTreee.NormalsSource = this.normalsSource;
                    float angleThreshold = Convert.ToSingle(this.startAngleForNormalsCheck - 5) * (1.0f - this.NumberOfIterations * 1.0f / this.ICPSettings.MaximumNumberOfIterations) + 5;

                    if (ICPSettings.SimulatedAnnealing)
                    {
                        if (Helper_ICP_Iteration_SA(PS, PT, kdTreee, angleThreshold))
                        {
                            break;
                        }
                    }
                    else
                    {
                        myPointsTransformed = Helper_ICP_Iteration(ref pointsSource, ref pointsTarget, PT, PS, kdTreee, angleThreshold);
                        if (myPointsTransformed != null)
                        {
                            break;
                        }
                    }

                    Debug.WriteLine("--------------Iteration: " + NumberOfIterations.ToString() + " : Mean Distance: " + MeanDistance.ToString("0.00000000000") + ": duration: " + GlobalVariables.TimeSpanString());
                    if (Math.Abs(oldMeanDistance - MeanDistance) < convergenceThreshold)
                    {
                        Debug.WriteLine("Convergence reached - changes under: " + convergenceThreshold.ToString());
                        break;
                    }
                    oldMeanDistance = MeanDistance;
                }

                Debug.WriteLine("--------****** Solution of ICP after : " + NumberOfIterations.ToString() + " iterations, and Mean Distance: " + MeanDistance.ToString("0.00000000000"));
                //if number of Iteration
                if (myPointsTransformed == null)
                {
                    myPointsTransformed = pointsTransformed;
                }

                if (this.ICPSettings.ShuffleEffect)
                {
                    PT           = pointsTarget;
                    PTransformed = myPointsTransformed;
                }
                else
                {
                    PTransformed = MathUtilsVTK.TransformPoints(PS, Matrix);
                }

                //re-reset vector
                if (ICPSettings.ResetVertexToOrigin)
                {
                    PointCloudVertices.AddVertex(PTransformed, pTOrigin);
                }

                //DebugWriteUtils.WriteTestOutputVertex("Solution of ICP", Matrix, this.PSource, PTransformed, PTarget);
                if (myPointsTransformed != null)
                {
                    DebugWriteUtils.WriteTestOutputVertex("Solution of ICP", Matrix, pointsSource, myPointsTransformed, pointsTarget);
                }
                else
                {
                    //no convergence - write matrix
                    this.Matrix.Print("Cumulated Matrix ");
                }


                PMerged = CalculateMergedPoints(PTransformed, PT);

                return(PTransformed);
            }
            catch (Exception err)
            {
                System.Windows.Forms.MessageBox.Show("Error in Update ICP at iteration: " + NumberOfIterations.ToString() + " : " + err.Message);
                return(null);
            }
        }
        public List <Vertex> PerformICP_Stitching()
        {
            int iPoint = 0;

            try
            {
                List <Vertex> pointsTarget = null;
                List <Vertex> pointsSource = null;

                ICPSolution res = CalculateStartSolution(ref pointsTarget, ref pointsSource, NumberOfStartTrialPoints, this.LandmarkTransform, this.PTarget, this.PSource, 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]);
                    //List<Vertex> 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) < ThresholdOutlier)
                    {
                        List <Vertex> pointsTargetTrial = PointUtils.CopyVertices(res.PointsTarget);
                        List <Vertex> pointsSourceTrial = PointUtils.CopyVertices(res.PointsSource);


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

                        List <Vertex> myPointsTransformed = MathUtils.TransformPoints(pointsSourceTrial, myMatrix);
                        double        totaldist           = PointUtils.CalculateTotalDistance(pointsTargetTrial, myPointsTransformed);
                        this.MeanDistance = totaldist / Convert.ToDouble(pointsTargetTrial.Count);


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

                        //could also remove this check...
                        if (Math.Abs(oldMeanDistance - this.MeanDistance) < 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;
        }