【问题标题】:Closed form solution for affine transformation matrix between 2 set of 2D points2组二维点间仿射变换矩阵的闭式解
【发布时间】:2020-08-23 01:17:48
【问题描述】:

给定具有6个未知变量a_11, a_12, a_21, a_22, b_1, b_2和对应的3对点x1, y1, x2, y2, x3, y3, u1, v1, u2, v2, u3, v3的仿射变换方程:

u = a_11 * x + a_12 * y + b_1
v = a_21 * x + a_22 * y + b_2

是否有可能以这种形式获得a_11, a_12, a_21, a_22, b_1, b_2的解决方案?

a_11 = f1(x1, y1, x2, y2, x3, y3, u1, v1, u2, v2, u3, v3)
a_12 = f2(x1, y1, x2, y2, x3, y3, u1, v1, u2, v2, u3, v3)
a_21 = f3(x1, y1, x2, y2, x3, y3, u1, v1, u2, v2, u3, v3)
a_22 = f4(x1, y1, x2, y2, x3, y3, u1, v1, u2, v2, u3, v3)
b_1 = f5(x1, y1, x2, y2, x3, y3, u1, v1, u2, v2, u3, v3)
b_2 = f6(x1, y1, x2, y2, x3, y3, u1, v1, u2, v2, u3, v3)

我知道这个系统可以通过像numpy.linalg.solve 这样的线性系统求解器来求解,但是我不能使用它,我需要f1, f2, f3, f4, f5, f6 来包含常见的数学运算。

一般情况下可以吗?哪些工具可用于求解此类方程组?似乎maplemathematica 有方程求解器,它适合这个任务吗?有没有其他选择?

【问题讨论】:

  • 如果你把所有 6 个方程都写出来,这不就是线性代数吗?像行减少未知数来得到你的答案。我会试一试的。

标签: wolfram-mathematica linear-algebra sympy maple affinetransform


【解决方案1】:

我假设您的意思是点 (x1,y1,u1,v1)、(x2,y2,u2,v2) 和 (x3,y3,u3,v3) 满足方程。在这种情况下,将它们代入,会产生六个具有六个未知数的方程。许多系数为零或一。因此,只需稍作取消,我们就能得到您要求的解决方案。

您的解决方案(假设您具有线性独立性)是:

a11 = ((u1-u2)(y2-y3)-(u2-u3)(y1-y2))/((x1-x2)(y2-y3)-((x2-x3)(y1-y2))
a12 = ((u1-u2)(x2-x3)-(u2-u3)(x1-x2))/((y1-y2)(x2-x3)-((y2-y3)(x1-x2))
a21 = ((v1-v2)(y2-y3)-(v2-v3)(y1-y2))/((x1-x2)(y2-y3)-((x2-x3)(y1-y2))
a22 = ((v1-v2)(x2-x3)-(v2-v3)(x1-x2))/((y1-y2)(x2-x3)-((y2-y3)(x1-x2))
b1 = u1-a11×x1-a12×y2
b2 = v1-a21×x1-a22×y2

我应该指出。这个问题更适合mathoverflow。真的和编程无关。

【讨论】:

    【解决方案2】:

    最后我用sympy 解决了这个方程组:

    from sympy.solvers.solveset import linsolve
    from sympy import *
    
        #u1 = a_11 * x1 + a_12 * y1 + b_1
        #v1 = a_21 * x1 + a_22 * y1 + b_2
        #u2 = a_11 * x2 + a_12 * y2 + b_1
        #v2 = a_21 * x2 + a_22 * y2 + b_2
        #u3 = a_11 * x3 + a_12 * y3 + b_1
        #v3 = a_21 * x3 + a_22 * y3 + b_2
    
        a_11, a_12, a_21, a_22, b_1, b_2, x1, y1, x2, y2, x3, y3, u1, v1, u2, v2, u3, v3 = \
            symbols('a_11, a_12, a_21, a_22, b_1, b_2, x1, y1, x2, y2, x3, y3, u1, v1, u2, v2, u3, v3')
    
        s = linsolve([a_11 * x1 + a_12 * y1 + b_1-u1,
                      a_21 * x1 + a_22 * y1 + b_2-v1,
                      a_11 * x2 + a_12 * y2 + b_1-u2,
                      a_21 * x2 + a_22 * y2 + b_2-v2,
                      a_11 * x3 + a_12 * y3 + b_1-u3,
                      a_21 * x3 + a_22 * y3 + b_2-v3], (a_11, a_12, a_21, a_22, b_1, b_2))
    
        print(s)
    

    答案是:

    a_11 = (u1 * y2 - u1 * y3 - u2 * y1 + u2 * y3 + u3 * y1 - u3 * y2) / (
                 x1 * y2 - x1 * y3 - x2 * y1 + x2 * y3 + x3 * y1 - x3 * y2)
    
    a_12 = (-u1 * x2 + u1 * x3 + u2 * x1 - u2 * x3 - u3 * x1 + u3 * x2) / (
                x1 * y2 - x1 * y3 - x2 * y1 + x2 * y3 + x3 * y1 - x3 * y2)
    
    a_21 = (v1 * y2 - v1 * y3 - v2 * y1 + v2 * y3 + v3 * y1 - v3 * y2) / (
                x1 * y2 - x1 * y3 - x2 * y1 + x2 * y3 + x3 * y1 - x3 * y2)
    
    a_22 = (-v1 * x2 + v1 * x3 + v2 * x1 - v2 * x3 - v3 * x1 + v3 * x2) / (
                x1 * y2 - x1 * y3 - x2 * y1 + x2 * y3 + x3 * y1 - x3 * y2)
    
    b_1 = (u1 * x2 * y3 - u1 * x3 * y2 - u2 * x1 * y3 + u2 * x3 * y1 + u3 * x1 * y2 - u3 * x2 * y1) / (
                x1 * y2 - x1 * y3 - x2 * y1 + x2 * y3 + x3 * y1 - x3 * y2)
    
    b_2 = (v1 * x2 * y3 - v1 * x3 * y2 - v2 * x1 * y3 + v2 * x3 * y1 + v3 * x1 * y2 - v3 * x2 * y1) / (
                x1 * y2 - x1 * y3 - x2 * y1 + x2 * y3 + x3 * y1 - x3 * y2)
    

    但看起来可以简化。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-12-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-06
      • 1970-01-01
      • 2011-02-07
      相关资源
      最近更新 更多