예제 #1
0
파일: ICP.cs 프로젝트: whigg/PointClouds
        public PointCloud PerformICP()
        {
            //float convergenceThreshold = PTarget.BoundingBoxMaxFloat * ICPSettings.ConvergenceThreshold;
            //if (ICPSettings.ResetVector3ToOrigin)
            //{
            //}
            if (ICPSettings.LogLevel > 0)
            {
                GlobalVariables.ShowLastTimeSpan("Before build");
            }

            KDTree.Build(this.PTarget);

            if (ICPSettings.LogLevel > 0)
            {
                GlobalVariables.ShowLastTimeSpan("Build Tree");
            }

            try
            {
                if (!CheckSourceTarget(PTarget, this.PSource))
                {
                    return(null);
                }

                pointsTarget = PointCloud.CloneAll(PTarget);
                pointsSource = PointCloud.CloneAll(PSource);

                this.Matrix = Matrix4.Identity;
                float oldMeanDistance = 0;

                if (ICPSettings.LogLevel > 0)
                {
                    GlobalVariables.ShowLastTimeSpan("Start ICP");
                }


                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;

                    Single_ICP_Iteration(angleThreshold);

                    //Debug.WriteLine("--------------Iteration: " + NumberOfIterations.ToString() + " : Mean Distance: " + MeanDistance.ToString("0.00000000000") );
                    if (ICPSettings.LogLevel > 0)
                    {
                        GlobalVariables.ShowLastTimeSpan("Iteration ");
                    }
                    if (MeanDistance < ICPSettings.ThresholdConvergence)
                    //if (Math.Abs(oldMeanDistance - MeanDistance) < convergenceThreshold)
                    {
                        Debug.WriteLine("Convergence reached - changes under: " + ICPSettings.ThresholdConvergence.ToString());
                        break;
                    }
                    oldMeanDistance = MeanDistance;
                }



                //shuffle effect - set points source to other order
                //PS = pointsSource;//reordered for shuffle effect
                //this.PSource = pointsSource;

                if (this.ICPSettings.ShuffleEffect)
                {
                    PTarget = pointsTarget;
                    //PS = pointsSource;//reordered for shuffle effect
                    //this.PSource = pointsSource;
                    PointsTransformed = this.pointsTransformed;
                }
                else
                {
                    PointsTransformed = MathUtilsVTK.TransformPoints(this.PSource, Matrix);
                }

                //ignore ICP result if the convergence results is bad
                if (MeanDistance > ICPSettings.ThresholdIgnoreICP)
                {
                    Debug.WriteLine("ICP RESULT IGNORED - TOO BAD " + this.MeanDistance.ToString("0.0000"));
                    return(this.PTarget);
                }

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

                pointsTarget = PTarget;
                float thresh = this.MeanDistance;
                if (ICPSettings.SingleSourceTargetMatching)
                {
                    PointsTransformed = this.PointsResultKDTree;// this.pointsTransformed;
                    PointCloud.AddVector3(PointsTransformed, centroidSource);
                }
                else
                {
                    PointsTransformed = PointCloud.CalculateMergedPoints(this.pointsTransformed, this.pointsTarget, this.KDTree, ICPSettings.ThresholdMergedPoints, out PointsAdded, this.ICPSettings.ChangeColorsOfMergedPoints);
                    PointCloud.AddVector3(PointsTransformed, centroidSource);
                }
                Debug.WriteLine("--------****** Solution of ICP after : " + NumberOfIterations.ToString() + " iterations, Mean Distance: " + MeanDistance.ToString("0.00000000000") + " Matrix trace : " + this.Matrix.Trace.ToString("0.00") + " - points added : " + PointsAdded.ToString());

                //not the best solution but ...
                PointsTransformed.SetDefaultIndices();

                PointsTransformed.Name         = "Result Cloud";
                PointsTransformed.FileNameLong = "ResultCloud.obj";


                return(PointsTransformed);
            }
            catch (Exception err)
            {
                System.Windows.Forms.MessageBox.Show("Error in Update ICP at iteration: " + NumberOfIterations.ToString() + " : " + err.Message);
                return(null);
            }
        }