Esempio n. 1
0
        /// <summary>Find a solution of the equation f(x)=0.</summary>
        /// <param name="f">The function to find roots from.</param>
        /// <param name="initialGuess">Initial guess of the root.</param>
        /// <param name="accuracy">Desired accuracy. The root will be refined until the accuracy or the maximum number of iterations is reached.</param>
        /// <param name="maxIterations">Maximum number of iterations. Usually 100.</param>
        /// <param name="root">The root that was found, if any. Undefined if the function returns false.</param>
        /// <returns>True if a root with the specified accuracy was found, else false.</returns>
        public static bool TryFindRoot(Func<double[], double[]> f, double[] initialGuess, double accuracy, int maxIterations, out double[] root)
        {
            var x = new DenseVector(initialGuess);

            double[] y0 = f(initialGuess);
            var y = new DenseVector(y0);
            double g = y.L2Norm();

            Matrix<double> B = CalculateApproximateJacobian(f, initialGuess, y0);

            for (int i = 0; i <= maxIterations; i++)
            {
                var dx = (DenseVector) (-B.LU().Solve(y));
                var xnew = x + dx;
                var ynew = new DenseVector(f(xnew.Values));
                double gnew = ynew.L2Norm();

                if (gnew > g)
                {
                    double g2 = g*g;
                    double scale = g2/(g2 + gnew*gnew);
                    if (scale == 0.0)
                    {
                        scale = 1.0e-4;
                    }

                    dx = scale*dx;
                    xnew = x + dx;
                    ynew = new DenseVector(f(xnew.Values));
                    gnew = ynew.L2Norm();
                }

                if (gnew < accuracy)
                {
                    root = xnew.Values;
                    return true;
                }

                // update Jacobian B
                DenseVector dF = ynew - y;
                Matrix<double> dB = (dF - B.Multiply(dx)).ToColumnMatrix() * dx.Multiply(1.0 / Math.Pow(dx.L2Norm(), 2)).ToRowMatrix();
                B = B + dB;

                x = xnew;
                y = ynew;
                g = gnew;
            }

            root = null;
            return false;
        }
Esempio n. 2
0
        private string PrepareResults()
        {
            StringBuilder result = new StringBuilder();
            result.Append("State: ");

            if(Status == AlgorithmStatus.Finished)
                result.Append("Finished");
            else if(Status != AlgorithmStatus.Error)
                result.Append("Not Finished");
            else
                result.Append("Error");

            result.AppendLine();
            result.AppendLine();

            if(_linearEstimationDone)
            {
                if(_inMinimsation)
                {
                    var estimatedParams = _miniAlg.BestResultVector;
                    CameraMatrix[0, 0] = estimatedParams[0];
                    CameraMatrix[0, 1] = estimatedParams[1];
                    CameraMatrix[0, 2] = estimatedParams[2];
                    CameraMatrix[0, 3] = estimatedParams[3];
                    CameraMatrix[1, 0] = estimatedParams[4];
                    CameraMatrix[1, 1] = estimatedParams[5];
                    CameraMatrix[1, 2] = estimatedParams[6];
                    CameraMatrix[1, 3] = estimatedParams[7];
                    CameraMatrix[2, 0] = estimatedParams[8];
                    CameraMatrix[2, 1] = estimatedParams[9];
                    CameraMatrix[2, 2] = estimatedParams[10];
                    CameraMatrix[2, 3] = estimatedParams[11];
                }

                if(_pointsNormalised)
                {
                    DenormaliseCameraMatrix();
                }

                result.AppendLine("Camera Matrix: ");

                result.Append("|" + CameraMatrix[0, 0].ToString("F3"));
                result.Append("; " + CameraMatrix[0, 1].ToString("F3"));
                result.Append("; " + CameraMatrix[0, 2].ToString("F3"));
                result.Append("; " + CameraMatrix[0, 3].ToString("F3"));
                result.AppendLine("|");

                result.Append("|" + CameraMatrix[1, 0].ToString("F3"));
                result.Append("; " + CameraMatrix[1, 1].ToString("F3"));
                result.Append("; " + CameraMatrix[1, 2].ToString("F3"));
                result.Append("; " + CameraMatrix[1, 3].ToString("F3"));
                result.AppendLine("|");

                result.Append("|" + CameraMatrix[2, 0].ToString("F3"));
                result.Append("; " + CameraMatrix[2, 1].ToString("F3"));
                result.Append("; " + CameraMatrix[2, 2].ToString("F3"));
                result.Append("; " + CameraMatrix[2, 3].ToString("F3"));
                result.AppendLine("|");

                DecomposeCameraMatrix();

                result.AppendLine();
                result.AppendLine("Calibration Matrix: ");

                result.Append("|" + CameraInternalMatrix[0, 0].ToString("F3"));
                result.Append("; " + CameraInternalMatrix[0, 1].ToString("F3"));
                result.Append("; " + CameraInternalMatrix[0, 2].ToString("F3"));
                result.AppendLine("|");

                result.Append("|" + CameraInternalMatrix[1, 0].ToString("F3"));
                result.Append("; " + CameraInternalMatrix[1, 1].ToString("F3"));
                result.Append("; " + CameraInternalMatrix[1, 2].ToString("F3"));
                result.AppendLine("|");

                result.Append("|" + CameraInternalMatrix[2, 0].ToString("F3"));
                result.Append("; " + CameraInternalMatrix[2, 1].ToString("F3"));
                result.Append("; " + CameraInternalMatrix[2, 2].ToString("F3"));
                result.AppendLine("|");

                result.AppendLine();
                result.AppendLine("Rotation Matrix: ");

                result.Append("|" + CameraRotationMatrix[0, 0].ToString("F3"));
                result.Append("; " + CameraRotationMatrix[0, 1].ToString("F3"));
                result.Append("; " + CameraRotationMatrix[0, 2].ToString("F3"));
                result.AppendLine("|");

                result.Append("|" + CameraRotationMatrix[1, 0].ToString("F3"));
                result.Append("; " + CameraRotationMatrix[1, 1].ToString("F3"));
                result.Append("; " + CameraRotationMatrix[1, 2].ToString("F3"));
                result.AppendLine("|");

                result.Append("|" + CameraRotationMatrix[2, 0].ToString("F3"));
                result.Append("; " + CameraRotationMatrix[2, 1].ToString("F3"));
                result.Append("; " + CameraRotationMatrix[2, 2].ToString("F3"));
                result.AppendLine("|");

                result.AppendLine();
                result.AppendLine("Translation Vector: ");

                result.Append("|" + CameraTranslation[0].ToString("F3"));
                result.AppendLine("|");
                result.Append("|" + CameraTranslation[1].ToString("F3"));
                result.AppendLine("|");
                result.Append("|" + CameraTranslation[2].ToString("F3"));
                result.AppendLine("|");

                double error = 0.0;
                double relerror = 0.0;
                double rerrx = 0.0;
                double rerry = 0.0;
                for(int p = 0; p < Points.Count; ++p)
                {
                    var cp = Points[p];
                    Vector<double> ip = new DenseVector(new double[] { cp.ImgX, cp.ImgY, 1.0 });
                    Vector<double> rp = new DenseVector(new double[] { cp.RealX, cp.RealY, cp.RealZ, 1.0 });

                    Vector<double> eip = CameraMatrix * rp;
                    eip.DivideThis(eip[2]);

                    var d = (ip - eip);
                    error += d.L2Norm();
                    ip[2] = 0.0;
                    relerror += d.L2Norm() / ip.L2Norm();
                    rerrx += Math.Abs(d[0]) / Math.Abs(ip[0]);
                    rerry += Math.Abs(d[1]) / Math.Abs(ip[1]);
                }

                result.AppendLine();
                result.AppendLine("Projection error ( d(xi, PXr)^2 ): ");
                result.AppendLine("Points count: " + Points.Count.ToString());
                result.AppendLine("Total: " + error.ToString("F4"));
                result.AppendLine("Mean: " + (error / Points.Count).ToString("F4"));
                result.AppendLine("Realtive: " + (relerror).ToString("F4"));
                result.AppendLine("Realtive mean: " + (relerror / Points.Count).ToString("F4"));
                result.AppendLine("Realtive in X: " + (rerrx).ToString("F4"));
                result.AppendLine("Realtive in X mean: " + (rerrx / Points.Count).ToString("F4"));
                result.AppendLine("Realtive in Y: " + (rerry).ToString("F4"));
                result.AppendLine("Realtive in Y mean: " + (rerry / Points.Count).ToString("F4"));

                if(MinimaliseSkew == true)
                {
                    result.AppendLine("SkewMini - base residual: " + _zeroSkewMini.BaseResidiual.ToString("F4"));
                    result.AppendLine("Skewini - best residual: " + _zeroSkewMini.MinimumResidiual.ToString("F4"));
                }

                if(LinearOnly == false)
                {
                    result.AppendLine("GeoMini - base residual: " + _miniAlg.BaseResidiual.ToString("F4"));
                    result.AppendLine("GeoMini - best residual: " + _miniAlg.MinimumResidiual.ToString("F4"));
                }
            }
            else
            {
                result.AppendLine("Camera not yet computed");
                return result.ToString();
            }

            return result.ToString();
        }