c#实现SVD奇异值分解求解旋转平移矩阵

本文介绍了如何在C#代码中通过VS工具添加Accord库,并利用Halcon进行矩阵计算,展示了如何使用SVD分解处理数据,包括获取左奇异向量、对角矩阵和右奇异向量,以及计算旋转和平移矩阵的过程。
摘要由CSDN通过智能技术生成

VS->工具->NuGet包添加Accord库,代码使用halcon进行矩阵计算,可以自行使用opencv中Mat进行矩阵计算。

using System;	
using System.Linq;
using Accord.Math.Decompositions;  //  添加方法

namespace SVD
{
    class Program
    {
        static void Main(string[] args)
        {
            //  模拟数据
            List<Point> a = new List<Point>()
            {
                new Point(100, 0),
                new Point(0, 100),
                new Point(0, -100),
                new Point(-100, 0),
             };
             List<Point> b = new List<Point>()
             {
                new Point(100, 10),
                new Point(0, 110),
                new Point(0, -90),
                new Point(-100, 10),
             };

            // 转数组进行运算
            double[] ax = new double[a.Count];
            double[] ay = new double[a.Count];
            double[] bx = new double[a.Count];
            double[] by = new double[a.Count];
            for (int i = 0; i < a.Count; ++i)
            {
                ax[i] = a[i].X;
                ay[i] = a[i].Y;
                bx[i] = b[i].X;
                by[i] = b[i].Y;
            }
            
            // 中心化
            Point centerA = new Point(ax.Average(), ay.Average());
            Point centerB = new Point(bx.Average(), by.Average());
            HOperatorSet.TupleGenConst(4, 0, out HTuple tmp);
            HOperatorSet.TupleSub(ax, centerA.X, out HTuple axx);
            HOperatorSet.TupleSub(ay, centerA.Y, out HTuple ayy);
            HOperatorSet.TupleSub(bx,centerB.X, out HTuple bxx);
            HOperatorSet.TupleSub(by, centerB.Y, out HTuple byy);
            HOperatorSet.VectorToHomMat2d(bxx, byy, axx, ayy, out HTuple mat2D);

            // Create a matrix double[,]  变换矩阵转齐次变换矩阵
            double[,] matrix =
            {
                { mat2D[0], mat2D[1], mat2D[2] }, 
                { mat2D[3], mat2D[4], mat2D[5] }, 
                { 0, 0, 1 }
            };

            // Perform SVD
            SingularValueDecomposition svd = new SingularValueDecomposition(matrix);
            // 获取 u, s, V matrices
            double[,] U = svd.LeftSingularVectors;
            double[,] S = svd.DiagonalMatrix;
            double[,] V = svd.RightSingularVectors;

            int elementCount = U.GetLength(0) * U.GetLength(1);
            double[] matU = new double[elementCount];
            double[] matV = new double[elementCount];
            double[] matS = new double[elementCount];
            for (int i = 0; i < U.GetLength(0); i++)
            {
                for (int j = 0; j < U.GetLength(1); j++)
                {
                    matU[i* U.GetLength(0) + j] = U[i, j];
                    matV[i* V.GetLength(0) + j] = V[i, j];
                    matS[i* S.GetLength(0) + j] = S[i, j];
                }
            }

            // 生成USV矩阵
            HOperatorSet.CreateMatrix(3, 3, 0, out HTuple matrixU);
            HOperatorSet.CreateMatrix(3, 3, 0, out HTuple matrixS);
            HOperatorSet.CreateMatrix(3, 3, 0, out HTuple matrixV);
            HOperatorSet.SetFullMatrix(matrixU, matU);
            HOperatorSet.SetFullMatrix(matrixS, matS);
            HOperatorSet.SetFullMatrix(matrixV, matV);

            //验证USV是否正确  H = U * S * V.T()
            HOperatorSet.MultMatrix(matrixU, matrixS, "AB", out HTuple matrixUS);
            HOperatorSet.MultMatrix(matrixUS, matrixV, "ABT", out HTuple matrixResult);
            HOperatorSet.GetFullMatrix(matrixResult, out HTuple values);

            // 求旋转矩阵   R = V * U.T()
            HOperatorSet.MultMatrix(matrixV, matrixU, "ABT", out HTuple matrixR);
            HOperatorSet.GetFullMatrix(matrixR, out HTuple valuesR);

            // 求平移矩阵 T = B - R * A
            double[] A = { centerA.X, centerA.Y, 1 };
            double[] B = { centerB.X, centerB.Y, 1 };
            HOperatorSet.CreateMatrix(3, 1, A, out HTuple matrixA);
            HOperatorSet.CreateMatrix(3, 1, B, out HTuple matrixB);
            HOperatorSet.MultMatrix(matrixR, matrixA, "AB", out HTuple matrixAB);
            HOperatorSet.SubMatrix(matrixB, matrixAB, out HTuple matrixSub);
            HOperatorSet.GetFullMatrix(matrixSub, out HTuple valueT);

            Console.ReadLine();
        }
    }
}

通过SingularValueDecomposition类进行SVD计算。然后,我们分别获取左奇异向量矩阵U,对角矩阵S和右奇异向量矩阵V,通过奇异矩阵计算旋转矩阵,再通过旋转矩阵和重心计算平移矩阵。

  • 6
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

call我雨雨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值