public void MultiplyTest() { MatrixH A = new MatrixH(); MatrixH B = new MatrixH(); MatrixH expected = new MatrixH(); MatrixH actual = A.Multiply(B); Assert.IsTrue(Accord.Math.Matrix.IsEqual( expected.Elements, actual.Elements)); double[,] a = { { 2, 3, 1 }, { 2, 1, 7 }, { 1, 2, 2 } }; double[,] b = { { 1, 3, 1 }, { -2, 1, -4 }, { 1, -1, 3 } }; A = new MatrixH(a); B = new MatrixH(b); actual = A.Multiply(B); expected = new MatrixH(Accord.Math.Matrix.Multiply(a, b)); Assert.IsTrue(Accord.Math.Matrix.IsEqual( (double[,])actual, (double[,])expected, 0.001)); }
/// <summary> /// Creates an homography matrix matching points /// from a set of points to another. /// </summary> /// public static MatrixH Homography(PointF[] points1, PointF[] 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 var A = new float[3 * N, 9]; for (int i = 0; i < N; i++) { PointF X = points1[i]; float x = points2[i].X; float y = points2[i].Y; int r = 3 * i; A[r, 0] = 0; A[r, 1] = 0; A[r, 2] = 0; A[r, 3] = -X.X; A[r, 4] = -X.Y; A[r, 5] = -1; A[r, 6] = y * X.X; A[r, 7] = y * X.Y; A[r, 8] = y; r++; A[r, 0] = X.X; A[r, 1] = X.Y; A[r, 2] = 1; 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; r++; A[r, 0] = -y * X.X; A[r, 1] = -y * X.Y; A[r, 2] = -y; A[r, 3] = x * X.X; A[r, 4] = x * X.Y; A[r, 5] = x; A[r, 6] = 0; A[r, 7] = 0; A[r, 8] = 0; } // Create the singular value decomposition SingularValueDecompositionF 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; }
/// <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); }