Beispiel #1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="Posit"/> class.
        /// </summary>
        ///
        /// <param name="model">Array of vectors containing coordinates of four real model's point.</param>
        /// <param name="focalLength">Effective focal length of the camera used to capture the model.</param>
        ///
        /// <exception cref="ArgumentException">The model must have 4 points.</exception>
        ///
        public CoplanarPosit(Vector3[] model, float focalLength)
        {
            if (model.Length != 4)
            {
                throw new ArgumentException("The model must have 4 points.");
            }

            this.focalLength = focalLength;
            modelPoints      = (Vector3[])model.Clone( );

            // compute model vectors
            modelVectors = Matrix3x3.CreateFromRows(
                model[1] - model[0],
                model[2] - model[0],
                model[3] - model[0]);

            // compute pseudo inverse of the model matrix
            Matrix3x3 u, v;
            Vector3   e;

            modelVectors.SVD(out u, out e, out v);
            modelPseudoInverse = v * Matrix3x3.CreateDiagonal(e.Inverse( )) * u.Transpose( );

            // computer unit vector normal to the model
            modelNormal = v.GetColumn(e.MinIndex);
        }
        public void CreateFromRowsTest()
        {
            Vector3   row0   = new Vector3(1, 2, 3);
            Vector3   row1   = new Vector3(4, 5, 6);
            Vector3   row2   = new Vector3(7, 8, 9);
            Matrix3x3 matrix = Matrix3x3.CreateFromRows(row0, row1, row2);

            float[] array = matrix.ToArray();

            for (int i = 0; i < 9; i++)
            {
                Assert.AreEqual(array[i], (float)(i + 1));
            }

            Assert.AreEqual(row0, matrix.GetRow(0));
            Assert.AreEqual(row1, matrix.GetRow(1));
            Assert.AreEqual(row2, matrix.GetRow(2));

            Assert.ThrowsException <ArgumentException>(() =>
            {
                matrix.GetRow(-1);
            }
                                                       );

            Assert.ThrowsException <ArgumentException>(() =>
            {
                matrix.GetRow(3);
            }
                                                       );
        }
Beispiel #3
0
        private void POS(Point[] imagePoints, Vector3 eps, out Matrix3x3 rotation1, out Matrix3x3 rotation2, out Vector3 translation1, out Vector3 translation2)
        {
            Vector3 vector  = new Vector3(imagePoints[1].X, imagePoints[2].X, imagePoints[3].X);
            Vector3 vector2 = new Vector3(imagePoints[1].Y, imagePoints[2].Y, imagePoints[3].Y);
            Vector3 vector3 = vector * eps - imagePoints[0].X;
            Vector3 vector4 = vector2 * eps - imagePoints[0].Y;
            Vector3 vector5 = modelPseudoInverse * vector3;
            Vector3 vector6 = modelPseudoInverse * vector4;
            Vector3 vector7 = default(Vector3);
            Vector3 vector8 = default(Vector3);
            Vector3 vector9 = default(Vector3);
            float   num     = vector6.Square - vector5.Square;
            float   num2    = Vector3.Dot(vector5, vector6);
            float   num3    = 0f;
            float   num4    = 0f;

            if (num == 0f)
            {
                num4 = (float)(-System.Math.PI / 2.0 * (double)System.Math.Sign(num2));
                num3 = (float)System.Math.Sqrt(System.Math.Abs(2f * num2));
            }
            else
            {
                num3 = (float)System.Math.Sqrt(System.Math.Sqrt(num * num + 4f * num2 * num2));
                num4 = (float)System.Math.Atan(-2f * num2 / num);
                if (num < 0f)
                {
                    num4 += (float)System.Math.PI;
                }
                num4 /= 2f;
            }
            float factor  = (float)((double)num3 * System.Math.Cos(num4));
            float factor2 = (float)((double)num3 * System.Math.Sin(num4));

            vector7 = vector5 + modelNormal * factor;
            vector8 = vector6 + modelNormal * factor2;
            float num5 = vector7.Normalize();
            float num6 = vector8.Normalize();

            vector9   = Vector3.Cross(vector7, vector8);
            rotation1 = Matrix3x3.CreateFromRows(vector7, vector8, vector9);
            float   num7     = (num5 + num6) / 2f;
            Vector3 vector10 = rotation1 * modelPoints[0];

            translation1 = new Vector3(imagePoints[0].X / num7 - vector10.X, imagePoints[0].Y / num7 - vector10.Y, focalLength / num7);
            vector7      = vector5 - modelNormal * factor;
            vector8      = vector6 - modelNormal * factor2;
            num5         = vector7.Normalize();
            num6         = vector8.Normalize();
            vector9      = Vector3.Cross(vector7, vector8);
            rotation2    = Matrix3x3.CreateFromRows(vector7, vector8, vector9);
            num7         = (num5 + num6) / 2f;
            vector10     = rotation2 * modelPoints[0];
            translation2 = new Vector3(imagePoints[0].X / num7 - vector10.X, imagePoints[0].Y / num7 - vector10.Y, focalLength / num7);
        }
Beispiel #4
0
 public Posit(Vector3[] model, float focalLength)
 {
     if (model.Length != 4)
     {
         throw new ArgumentException("The model must have 4 points.");
     }
     this.focalLength   = focalLength;
     modelPoints        = (Vector3[])model.Clone();
     modelVectors       = Matrix3x3.CreateFromRows(model[1] - model[0], model[2] - model[0], model[3] - model[0]);
     modelPseudoInverse = modelVectors.PseudoInverse();
 }
Beispiel #5
0
        public void EstimatePose(Point[] points, out Matrix3x3 rotation, out Vector3 translation)
        {
            if (points.Length != 4)
            {
                throw new ArgumentException("4 points must be be given for pose estimation.");
            }
            float   num      = 0f;
            float   num2     = 1f;
            Vector3 vector   = new Vector3(points[0].X);
            Vector3 vector2  = new Vector3(points[0].Y);
            Vector3 vector3  = new Vector3(points[1].X, points[2].X, points[3].X);
            Vector3 vector4  = new Vector3(points[1].Y, points[2].Y, points[3].Y);
            int     i        = 0;
            Vector3 vector5  = default(Vector3);
            Vector3 vector6  = default(Vector3);
            Vector3 vector7  = default(Vector3);
            Vector3 vector8  = default(Vector3);
            Vector3 vector9  = default(Vector3);
            Vector3 vector10 = new Vector3(1f);

            for (; i < 100; i++)
            {
                vector8 = vector3 * vector10 - vector;
                vector9 = vector4 * vector10 - vector2;
                vector5 = modelPseudoInverse * vector8;
                vector6 = modelPseudoInverse * vector9;
                float num3 = vector5.Normalize();
                float num4 = vector6.Normalize();
                num2    = (num3 + num4) / 2f;
                vector7 = Vector3.Cross(vector5, vector6);
                num     = focalLength / num2;
                Vector3 vector11 = vector10;
                vector10 = modelVectors * vector7 / num + 1f;
                if ((vector10 - vector11).Abs().Max < 0.0001f)
                {
                    break;
                }
            }
            rotation = Matrix3x3.CreateFromRows(vector5, vector6, vector7);
            Vector3 vector12 = rotation * modelPoints[0];

            translation = new Vector3(points[0].X / num2 - vector12.X, points[0].Y / num2 - vector12.Y, focalLength / num2);
        }
Beispiel #6
0
        // Perform single iteration of POS (pos estimations) algorithm to find possible rotations and translation vectors
        private void POS(Point[] imagePoints, Vector3 eps, out Matrix3x3 rotation1, out Matrix3x3 rotation2, out Vector3 translation1, out Vector3 translation2)
        {
            // create vectors keeping all X and Y coordinates for the 1st, 2nd and 3rd points
            Vector3 XI = new Vector3(imagePoints[1].X, imagePoints[2].X, imagePoints[3].X);
            Vector3 YI = new Vector3(imagePoints[1].Y, imagePoints[2].Y, imagePoints[3].Y);

            // calculate scale orthographic projection (SOP)
            Vector3 imageXs = XI * eps - imagePoints[0].X;
            Vector3 imageYs = YI * eps - imagePoints[0].Y;

            // calculate I0 and J0 vectors
            Vector3 I0Vector = modelPseudoInverse * imageXs;
            Vector3 J0Vector = modelPseudoInverse * imageYs;

            Vector3 iVector = new Vector3( );
            Vector3 jVector = new Vector3( );
            Vector3 kVector = new Vector3( );

            // find roots of complex number C^2
            float j2i2dif = J0Vector.Square - I0Vector.Square;
            float ij      = Vector3.Dot(I0Vector, J0Vector);

            float r = 0, theta = 0;

            if (j2i2dif == 0)
            {
                theta = (float)((-System.Math.PI / 2) * System.Math.Sign(ij));
                r     = (float)System.Math.Sqrt(System.Math.Abs(2 * ij));
            }
            else
            {
                r     = (float)System.Math.Sqrt(System.Math.Sqrt(j2i2dif * j2i2dif + 4 * ij * ij));
                theta = (float)System.Math.Atan(-2 * ij / j2i2dif);

                if (j2i2dif < 0)
                {
                    theta += (float)System.Math.PI;
                }

                theta /= 2;
            }

            float lambda = (float)(r * System.Math.Cos(theta));
            float mu     = (float)(r * System.Math.Sin(theta));

            // first possible rotation
            iVector = I0Vector + (modelNormal * lambda);
            jVector = J0Vector + (modelNormal * mu);

            float iNorm = iVector.Normalize( );
            float jNorm = jVector.Normalize( );

            kVector = Vector3.Cross(iVector, jVector);

            rotation1 = Matrix3x3.CreateFromRows(iVector, jVector, kVector);

            // calculate translation vector
            float scale = (iNorm + jNorm) / 2;

            Vector3 temp = rotation1 * modelPoints[0];

            translation1 = new Vector3(imagePoints[0].X / scale - temp.X, imagePoints[0].Y / scale - temp.Y, focalLength / scale);

            // second possible rotation
            iVector = I0Vector - (modelNormal * lambda);
            jVector = J0Vector - (modelNormal * mu);

            iNorm   = iVector.Normalize( );
            jNorm   = jVector.Normalize( );
            kVector = Vector3.Cross(iVector, jVector);

            rotation2 = Matrix3x3.CreateFromRows(iVector, jVector, kVector);

            scale = (iNorm + jNorm) / 2;

            temp         = rotation2 * modelPoints[0];
            translation2 = new Vector3(imagePoints[0].X / scale - temp.X, imagePoints[0].Y / scale - temp.Y, focalLength / scale);
        }
Beispiel #7
0
        /// <summary>
        /// Estimate pose of a model from it's projected 2D coordinates.
        /// </summary>
        ///
        /// <param name="points">4 2D points of the <see cref="Model">model's</see> projection.</param>
        /// <param name="rotation">Gets object's rotation.</param>
        /// <param name="translation">Gets object's translation.</param>
        ///
        /// <exception cref="ArgumentException">4 points must be be given for pose estimation.</exception>
        ///
        public void EstimatePose(Point[] points, out Matrix3x3 rotation, out Vector3 translation)
        {
            if (points.Length != 4)
            {
                throw new ArgumentException("4 points must be be given for pose estimation.");
            }

            float Z0 = 0, scale = 1;

            var X0 = new Vector3(points[0].X);
            var Y0 = new Vector3(points[0].Y);

            var XI = new Vector3(points[1].X, points[2].X, points[3].X);
            var YI = new Vector3(points[1].Y, points[2].Y, points[3].Y);

            var count = 0;

            var iVector = new Vector3();
            var jVector = new Vector3();
            var kVector = new Vector3();
            var imageXs = new Vector3();
            var imageYs = new Vector3();

            var eps = new Vector3(1);

            for (; count < 100; count++)
            {
                // calculate new scale orthographic projection (SOP)
                imageXs = XI * eps - X0;
                imageYs = YI * eps - Y0;

                // calculate I and J vectors
                iVector = modelPseudoInverse * imageXs;
                jVector = modelPseudoInverse * imageYs;
                // convert them to unit vectors i and j
                var iNorm = iVector.Normalize();
                var jNorm = jVector.Normalize();
                // scale of projection
                scale = (iNorm + jNorm) / 2;
                // calculate n vector k
                kVector = Vector3.Cross(iVector, jVector);
                // z-coordinate Z0 of the translation vector
                Z0 = focalLength / scale;

                // calculate new epsilon values
                var oldEps = eps;
                eps = (modelVectors * kVector) / Z0 + 1;

                // check if it is time to stop
                if ((eps - oldEps).Abs().Max < stop_epsilon)
                {
                    break;
                }
            }

            // create rotation matrix
            rotation = Matrix3x3.CreateFromRows(iVector, jVector, kVector);

            // create translation vector
            var temp = rotation * modelPoints[0];

            translation = new Vector3(
                points[0].X / scale - temp.X,
                points[0].Y / scale - temp.Y,
                focalLength / scale);
        }