Exemple #1
0
 /// <summary>
 ///   Detects if three points are colinear.
 /// </summary>
 public static bool Colinear(PointH pt1, PointH pt2, PointH pt3)
 {
     return(System.Math.Abs(
                (pt1.Y * pt2.W - pt1.W * pt2.Y) * pt3.X +
                (pt1.W * pt2.X - pt1.X * pt2.W) * pt3.Y +
                (pt1.X * pt2.Y - pt1.Y * pt2.X) * pt3.W) < Special.SingleEpsilon);
 }
Exemple #2
0
        /// <summary>
        ///   Transforms the given points using this transformation matrix.
        /// </summary>
        ///
        public PointH[] TransformPoints(params PointH[] points)
        {
            PointH[] r = new PointH[points.Length];

            for (int j = 0; j < points.Length; j++)
            {
                r[j].X = elements[0] * points[j].X + elements[1] * points[j].Y + elements[2] * points[j].W;
                r[j].Y = elements[3] * points[j].X + elements[4] * points[j].Y + elements[5] * points[j].W;
                r[j].W = elements[6] * points[j].X + elements[7] * points[j].Y + points[j].W;
            }

            return(r);
        }
Exemple #3
0
        /// <summary>
        ///   Compares two objects for equality.
        /// </summary>
        ///
        public override bool Equals(object obj)
        {
            if (obj is PointH)
            {
                PointH p = (PointH)obj;
                if (px / pw == p.px / p.pw &&
                    py / pw == p.py / p.pw)
                {
                    return(true);
                }
            }

            return(false);
        }
Exemple #4
0
        public void NormalizeTest()
        {
            PointH[] points = new PointH[] 
            {
                new PointH(1, 2),
                new PointH(5, 2),
                new PointH(12, 2),
                new PointH(1, 2),
                new PointH(10, 2),
            };

            MatrixH T;
            PointH[] actual = Tools.Normalize(points, out T);


            // Centroids should be at the origin
            double cx = 0, cy = 0;
            for (int i = 0; i < actual.Length; i++)
            {
                cx += actual[i].X / actual[i].W;
                cy += actual[i].Y / actual[i].W;
            }
            Assert.AreEqual(cx / actual.Length, 0, 0.0000001);
            Assert.AreEqual(cy / actual.Length, 0, 0.0000001);

            // Average distance from the origin should be sqrt(2)
            double d = 0;
            for (int i = 0; i < actual.Length; i++)
            {
                double x = actual[i].X / actual[i].W;
                double y = actual[i].Y / actual[i].W;

                d += System.Math.Sqrt(x * x + y * y);
            }
            Assert.AreEqual(d / actual.Length, System.Math.Sqrt(2), 0.00001);


        }
Exemple #5
0
 /// <summary>
 ///   Converts to a Integer point by rounding the point coordinates.
 /// </summary>
 ///
 public static Point Round(PointH point)
 {
     return(new Point(
                (int)System.Math.Round(point.px / point.pw),
                (int)System.Math.Round(point.py / point.pw)));
 }
Exemple #6
0
 /// <summary>
 ///   Converts to a Integer point by computing the ceiling of the point coordinates.
 /// </summary>
 ///
 public static Point Ceiling(PointH point)
 {
     return(new Point(
                (int)System.Math.Ceiling(point.px / point.pw),
                (int)System.Math.Ceiling(point.py / point.pw)));
 }
Exemple #7
0
 /// <summary>
 ///   Add the values of two points.
 /// </summary>
 ///
 public PointH Add(PointH value)
 {
     return(this + value);
 }
Exemple #8
0
 /// <summary>
 ///   Subtracts the values of two points.
 /// </summary>
 ///
 public PointH Subtract(PointH value)
 {
     return(this - value);
 }
        /// <summary>
        ///   Transforms the given points using this transformation matrix.
        /// </summary>
        /// 
        public PointH[] TransformPoints(params PointH[] points)
        {
            PointH[] r = new PointH[points.Length];

            for (int j = 0; j < points.Length; j++)
            {
                r[j].X = elements[0] * points[j].X + elements[1] * points[j].Y + elements[2] * points[j].W;
                r[j].Y = elements[3] * points[j].X + elements[4] * points[j].Y + elements[5] * points[j].W;
                r[j].W = elements[6] * points[j].X + elements[7] * points[j].Y + points[j].W;
            }

            return r;
        }
Exemple #10
0
        /// <summary>
        ///   Creates an homography matrix matching points
        ///   from a set of points to another.
        /// </summary>
        public static MatrixH Homography(PointH[] points1, PointH[] points2)
        {
            // Initial argument checkings
            if (points1.Length != points2.Length)
            {
                throw new ArgumentException("The number of points should be equal.");
            }

            if (points1.Length < 4)
            {
                throw new ArgumentException("At least four points are required to fit an homography");
            }


            int N = points1.Length;

            MatrixH T1, T2; // Normalize input points

            points1 = Tools.Normalize(points1, out T1);
            points2 = Tools.Normalize(points2, out T2);

            // Create the matrix A
            double[,] A = new double[3 * N, 9];
            for (int i = 0; i < N; i++)
            {
                PointH X = points1[i];
                double x = points2[i].X;
                double y = points2[i].Y;
                double w = points2[i].W;
                int    r = 3 * i;

                A[r, 0] = 0;
                A[r, 1] = 0;
                A[r, 2] = 0;
                A[r, 3] = -w * X.X;
                A[r, 4] = -w * X.Y;
                A[r, 5] = -w * X.W;
                A[r, 6] = y * X.X;
                A[r, 7] = y * X.Y;
                A[r, 8] = y * X.W;

                r++;
                A[r, 0] = w * X.X;
                A[r, 1] = w * X.Y;
                A[r, 2] = w * X.W;
                A[r, 3] = 0;
                A[r, 4] = 0;
                A[r, 5] = 0;
                A[r, 6] = -x * X.X;
                A[r, 7] = -x * X.Y;
                A[r, 8] = -x * X.W;

                r++;
                A[r, 0] = -y * X.X;
                A[r, 1] = -y * X.Y;
                A[r, 2] = -y * X.W;
                A[r, 3] = x * X.X;
                A[r, 4] = x * X.Y;
                A[r, 5] = x * X.W;
                A[r, 6] = 0;
                A[r, 7] = 0;
                A[r, 8] = 0;
            }


            // Create the singular value decomposition
            SingularValueDecomposition svd = new SingularValueDecomposition(A, false, true);

            double[,] V = svd.RightSingularVectors;


            // Extract the homography matrix
            MatrixH H = new MatrixH((float)V[0, 8], (float)V[1, 8], (float)V[2, 8],
                                    (float)V[3, 8], (float)V[4, 8], (float)V[5, 8],
                                    (float)V[6, 8], (float)V[7, 8], (float)V[8, 8]);

            // Denormalize
            H = T2.Inverse().Multiply(H.Multiply(T1));

            return(H);
        }
Exemple #11
0
        public void ColinearTest()
        {
            bool actual;

            PointH p1 = new PointH(0, 1);
            PointH p2 = new PointH(0, 2);
            PointH p3 = new PointH(0, 3);

            bool expected = true;
            actual = Tools.Collinear(p1, p2, p3);
            Assert.AreEqual(expected, actual);


            p1 = new PointH(0, 1);
            p2 = new PointH(1, 0);
            p3 = new PointH(1, 1);

            expected = false;
            actual = Tools.Collinear(p1, p2, p3);
            Assert.AreEqual(expected, actual);
        }
Exemple #12
0
        /// <summary>
        ///   Creates an homography matrix matching points
        ///   from a set of points to another.
        /// </summary>
        public static MatrixH Homography(PointH[] points1, PointH[] points2)
        {
            // Initial argument checks
            if (points1.Length != points2.Length)
                throw new ArgumentException("The number of points should be equal.");

            if (points1.Length < 4)
                throw new ArgumentException("At least four points are required to fit an homography");


            int N = points1.Length;

            MatrixH T1, T2; // Normalize input points
            points1 = Tools.Normalize(points1, out T1);
            points2 = Tools.Normalize(points2, out T2);

            // Create the matrix A
            float[,] A = new float[3 * N, 9];
            for (int i = 0; i < N; i++)
            {
                PointH X = points1[i];
                float x = points2[i].X;
                float y = points2[i].Y;
                float w = points2[i].W;
                int r = 3 * i;

                A[r, 0] = 0;
                A[r, 1] = 0;
                A[r, 2] = 0;
                A[r, 3] = -w * X.X;
                A[r, 4] = -w * X.Y;
                A[r, 5] = -w * X.W;
                A[r, 6] = y * X.X;
                A[r, 7] = y * X.Y;
                A[r, 8] = y * X.W;

                r++;
                A[r, 0] = w * X.X;
                A[r, 1] = w * X.Y;
                A[r, 2] = w * X.W;
                A[r, 3] = 0;
                A[r, 4] = 0;
                A[r, 5] = 0;
                A[r, 6] = -x * X.X;
                A[r, 7] = -x * X.Y;
                A[r, 8] = -x * X.W;

                r++;
                A[r, 0] = -y * X.X;
                A[r, 1] = -y * X.Y;
                A[r, 2] = -y * X.W;
                A[r, 3] = x * X.X;
                A[r, 4] = x * X.Y;
                A[r, 5] = x * X.W;
                A[r, 6] = 0;
                A[r, 7] = 0;
                A[r, 8] = 0;
            }


            // Create the singular value decomposition
            var svd = new SingularValueDecompositionF(A,
                computeLeftSingularVectors: false, computeRightSingularVectors: true,
                autoTranspose: false, inPlace: true);

            float[,] V = svd.RightSingularVectors;


            // Extract the homography matrix
            MatrixH H = new MatrixH(V[0, 8], V[1, 8], V[2, 8],
                                    V[3, 8], V[4, 8], V[5, 8],
                                    V[6, 8], V[7, 8], V[8, 8]);

            // Denormalize
            H = T2.Inverse().Multiply(H.Multiply(T1));

            return H;
        }
Exemple #13
0
 /// <summary>
 ///   Add the values of two points.
 /// </summary>
 /// 
 public PointH Add(PointH value)
 {
     return this + value;
 }
Exemple #14
0
 /// <summary>
 ///   Subtracts the values of two points.
 /// </summary>
 /// 
 public PointH Subtract(PointH value)
 {
     return this - value;
 }
Exemple #15
0
        public void ColinearTest1()
        {
            bool actual;
            PointF pt1, pt2, pt3;

            pt1 = new PointF(0, 0);
            pt2 = new PointF(1, 1);
            pt3 = new PointF(2, 2);

            actual = Tools.Collinear(pt1, pt2, pt3);
            Assert.AreEqual(true, actual);


            pt1 = new PointH(0, 1);
            pt2 = new PointH(1, 1);
            pt3 = new PointH(2, 2);

            actual = Tools.Collinear(pt1, pt2, pt3);
            Assert.AreEqual(false, actual);
        }
Exemple #16
0
        public void HomographyTest()
        {
            PointH[] x1 = 
            {
                new PointH(0, 0),
                new PointH(1, 0),
                new PointH(0, 1),
                new PointH(1, 1),
            };

            PointH[] x2 = 
            {
                new PointH(0, 0),
                new PointH(1, 0),
                new PointH(0, 1),
                new PointH(1, 1),
            };

            double[,] expected = Matrix.Identity(3);

            double[,] actual = (double[,])Tools.Homography(x1, x2);

            for (int i = 0; i < 3; i++)
                for (int j = 0; j < 3; j++)
                    actual[i, j] /= actual[2, 2];

            Assert.IsTrue(Matrix.IsEqual(expected, actual, 1e-4));


            x1 = new PointH[] 
            {
                new PointH(2, 0),
                new PointH(1, 0),
                new PointH(5, 1),
                new PointH(1, 1),
                new PointH(7, 1),
                new PointH(1, 2),
                new PointH(1, 1),
            };

            x2 = new PointH[] 
            {
                new PointH(9, 1),
                new PointH(1, 5),
                new PointH(9, 1),
                new PointH(1, 7),
                new PointH(2, 7),
                new PointH(6, 5),
                new PointH(1, 7),
            };

            expected = new double[,]
            {
              { 0.2225, -3.1727,  1.8023 },
              { 0.3648, -1.7149, -0.2173 },
              { 0.0607, -0.4562,  0.1229 },
            };

            expected = (double[,])(new MatrixH(expected));

            actual = (double[,])Tools.Homography(x1, x2);

            Assert.IsTrue(Matrix.IsEqual(expected, actual, 0.01));

        }
Exemple #17
0
 /// <summary>
 ///   Converts to a Integer point by truncating the point coordinates.
 /// </summary>
 ///
 public static Point Truncate(PointH point)
 {
     return(new Point(
                (int)System.Math.Truncate(point.px / point.pw),
                (int)System.Math.Truncate(point.py / point.pw)));
 }
Exemple #18
0
        /// <summary>
        ///   Creates the fundamental matrix between two
        ///   images from a set of points from each image.
        /// </summary>
        /// 
        public static float[,] Fundamental(PointH[] points1, PointH[] points2)
        {
            int N = points1.Length;

            float[,] T1, T2; // Normalize input points
            points1 = Tools.Normalize(points1, out T1);
            points2 = Tools.Normalize(points2, out T2);


            float[,] A = new float[N, 9];
            for (int i = 0; i < N; i++)
            {
                float x1 = points1[i].X;
                float y1 = points1[i].Y;

                float x2 = points2[i].X;
                float y2 = points2[i].Y;

                A[i, 0] = x2 * x1;
                A[i, 1] = x2 * y1;
                A[i, 2] = x2;

                A[i, 3] = y2 * x1;
                A[i, 4] = y2 * y2;
                A[i, 5] = y2;

                A[i, 6] = x1;
                A[i, 7] = y1;
                A[i, 8] = 1;
            }

            float[,] F = createFundamentalMatrix(A);

            // Denormalize
            F = T2.Transpose().Multiply(F.Multiply(T1));

            return F;
        }
Exemple #19
0
 /// <summary>
 ///   Converts to a Integer point by computing the ceiling of the point coordinates. 
 /// </summary>
 /// 
 public static Point Ceiling(PointH point)
 {
     return new Point(
         (int)System.Math.Ceiling(point.px / point.pw),
         (int)System.Math.Ceiling(point.py / point.pw));
 }
Exemple #20
0
        public void MultiplyTest()
        {
            MatrixH matrix = new MatrixH(Matrix.Identity(3));

            PointH[] points = new PointH[] 
            {
                new PointH(1, 2),
                new PointH(5, 2),
                new PointH(12, 2),
                new PointH(1, 2),
                new PointH(10, 2),
            };


            PointH[] expected = new PointH[] 
            {
                new PointH(1, 2),
                new PointH(5, 2),
                new PointH(12, 2),
                new PointH(1, 2),
                new PointH(10, 2),
            };

            PointH[] actual = (PointH[])points.Clone();
            matrix.TransformPoints(actual);

            Assert.AreEqual(expected[0], actual[0]);
            Assert.AreEqual(expected[1], actual[1]);
            Assert.AreEqual(expected[2], actual[2]);
            Assert.AreEqual(expected[3], actual[3]);
            Assert.AreEqual(expected[4], actual[4]);

        }
Exemple #21
0
        /// <summary>
        ///   Creates the fundamental matrix between two
        ///   images from a set of points from each image.
        /// </summary>
        /// 
        public static float[,] Fundamental(PointH[] points1, PointH[] points2, out PointH[] epipoles)
        {
            var F = Fundamental(points1, points2);

            SingularValueDecompositionF svd = new SingularValueDecompositionF(F,
                computeLeftSingularVectors: true, computeRightSingularVectors: true,
                autoTranspose: true, inPlace: false);

            var U = svd.LeftSingularVectors;
            var V = svd.RightSingularVectors;

            PointH e1 = new PointH(V[0, 2] / V[2, 2], V[1, 2] / V[2, 2], 1);
            PointH e2 = new PointH(U[0, 2] / U[2, 2], U[1, 2] / U[2, 2], 1);

            epipoles = new PointH[] { e1, e2 };

            return F;
        }
Exemple #22
0
 /// <summary>
 ///   Converts to a Integer point by rounding the point coordinates. 
 /// </summary>
 /// 
 public static Point Round(PointH point)
 {
     return new Point(
         (int)System.Math.Round(point.px / point.pw),
         (int)System.Math.Round(point.py / point.pw));
 }
Exemple #23
0
 /// <summary>
 ///   Detects if three points are collinear.
 /// </summary>
 public static bool Collinear(PointH pt1, PointH pt2, PointH pt3)
 {
     return Math.Abs(
      (pt1.Y * pt2.W - pt1.W * pt2.Y) * pt3.X +
      (pt1.W * pt2.X - pt1.X * pt2.W) * pt3.Y +
      (pt1.X * pt2.Y - pt1.Y * pt2.X) * pt3.W) < Constants.SingleEpsilon;
 }
Exemple #24
0
 /// <summary>
 ///   Converts to a Integer point by truncating the point coordinates. 
 /// </summary>
 /// 
 public static Point Truncate(PointH point)
 {
     return new Point(
         (int)System.Math.Truncate(point.px / point.pw),
         (int)System.Math.Truncate(point.py / point.pw));
 }