34 lines
1.3 KiB
C#
34 lines
1.3 KiB
C#
|
using MathNet.Numerics.LinearAlgebra;
|
|||
|
|
|||
|
namespace DispenserCommon.Utils;
|
|||
|
|
|||
|
public class AffineTransformCalculator
|
|||
|
{
|
|||
|
public static Matrix<double> Calculate3x2AffineTransform(List<Tuple<double, double>> acupunctureCoordinates,
|
|||
|
List<Tuple<double, double>> binCoordinates)
|
|||
|
{
|
|||
|
if (acupunctureCoordinates.Count != binCoordinates.Count || acupunctureCoordinates.Count < 3)
|
|||
|
throw new ArgumentException("Both sets must have the same number of points and at least three points.");
|
|||
|
|
|||
|
// 创建矩阵X和Y
|
|||
|
var rowCount = acupunctureCoordinates.Count;
|
|||
|
var matrixX = Matrix<double>.Build.Dense(rowCount, 3);
|
|||
|
var matrixY = Matrix<double>.Build.Dense(rowCount, 2);
|
|||
|
|
|||
|
for (var i = 0; i < rowCount; i++)
|
|||
|
{
|
|||
|
matrixX[i, 0] = acupunctureCoordinates[i].Item1; // x-coordinate
|
|||
|
matrixX[i, 1] = acupunctureCoordinates[i].Item2; // y-coordinate
|
|||
|
matrixX[i, 2] = 1; // homogeneous coordinate
|
|||
|
|
|||
|
matrixY[i, 0] = binCoordinates[i].Item1; // x'-coordinate
|
|||
|
matrixY[i, 1] = binCoordinates[i].Item2; // y'-coordinate
|
|||
|
}
|
|||
|
|
|||
|
// 计算仿射变换矩阵 A = Y * X^(-1)
|
|||
|
var pseudoInverseX = matrixX.PseudoInverse();
|
|||
|
var transformMatrix = matrixY.Transpose() * pseudoInverseX.Transpose();
|
|||
|
|
|||
|
return transformMatrix;
|
|||
|
}
|
|||
|
}
|