【问题标题】:How to rotate and scale an homography如何旋转和缩放单应性
【发布时间】:2012-05-23 13:46:13
【问题描述】:

我需要帮助,

我正在从服务器接收单应性,因此我想将此单应性标准化为我的应用程序的坐标系,当我尝试在坐标中表示对象时,服务器应用程序会生成接下来的 4 个点:

收到 [96.629539, 217.31934; 97.289948、167.21941; 145.69249、168.28044; 145.69638、219.84604]

我的应用会生成接下来的 4 个点:

本地 [126.0098, 55.600437; 262.39163、53.98035; 259.41382、195.34763; 121.48138、184.95235]

我用图形表示这个点,R(received), P(local)

看起来生成的正方形是旋转和缩放的,所以我想知道是否有任何方法可以将此旋转缩放应用到服务器单应性,以便能够具有与我的应用程序单应性相同的单应性.

谢谢,我需要更多信息请询问我。


非常感谢您的快速回答,最后我使用其他近似值,就像从服务器获取点并使用 findhomography 获得逆单应性一样简单。

homography=findHomography(srcPoints, dstPoints, match_mask, RANSAC, 10);

谢谢!!!

【问题讨论】:

  • 我不明白你想做什么。
  • 听起来像是透视变换?您是否将一个四边形映射到另一个?
  • 我想对单应性进行修改,以将此单应性转换为我的单位/坐标系。

标签: c algorithm math opencv augmented-reality


【解决方案1】:

我想我想通了。下面是你的两个单应性的更准确的图。其中蓝色是“接收”单应性,红色是“本地”单应性。

您可以使用 OpenCV 函数 getAffineTransform 来计算与 3 个点对相关的仿射变换(我不得不重新组织您的点对,因为它们的顺序错误)。我在 numpy 中运行如下:

r = array([[97.289948, 167.21941], [96.629539, 217.31934], [145.69638, 219.84604]], np.float32)
l = array([[126.0098, 55.600437], [121.48138, 184.95235], [259.41382, 195.34763]], np.float32)
A = cv2.getAffineTransform(r, l)

这给了我们以下仿射关系:

array([[  2.81385763e+00,  -5.32961421e-02,  -1.38838108e+02],
       [  7.88519054e-02,   2.58291747e+00,  -3.83984986e+02]])

我将此应用回r,看看是否可以得到l,以确保它像这样工作:

# split affine warp into rotation, scale, and/or shear + translation matrix
T = mat(A[:, 2]).T
matrix([[-138.83810801],
        [-383.98498637]])

A = mat(A[:, 0:2])
matrix([[ 2.81385763, -0.05329614],
        [ 0.07885191,  2.58291747]])

# apply warp to r to get l
r = mat(r).T
A*r + T
# gives
matrix([[ 126.00980377,  121.48137665,  259.41381836],
        [  55.60043716,  184.9523468 ,  195.34762573]])
# which equals
l = mat(l).T
matrix([[ 126.00980377,  121.48137665,  259.41381836],
        [  55.60043716,  184.9523468 ,  195.34762573]], dtype=float32)

另外值得注意的是,您可以使用 OpenCV 函数 getPerspectiveTransform 生成如 Markus Jarderot 所示的透视变换。

希望有帮助!

【讨论】:

    【解决方案2】:

    如果你将点和变换插入 Maple,你可以很快得到结果。

    > with(LinearAlgebra);
    
    > # The server coordinates
      pa := [[96.629539, 217.31934], [97.289948, 167.21941], [145.69249, 168.28044],
             [145.69638, 219.84604]]:
    
    > # The local coordiantes
      pb := [[126.0098, 55.600437], [262.39163, 53.98035], [259.41382, 195.34763],
             [121.48138, 184.95235]]:
    
    > # The placeholder variables for the transformation (last one is '1', because it
      # is scale-invariant)
      T := [seq]([seq](`if`(i = 3 and j = 3, 1, t[i, j]), j = 1 .. 3), i = 1 .. 3):
      V := convert(map(op, T)[1 .. -2], set):
    
    > # Transformation function (Matrix multiplication + divide with 3rd coordinate)
      trans := (p, T) -> [
          (T[1, 1]*p[1]+T[1, 2]*p[2]+T[1, 3])/(T[3, 1]*p[1]+T[3, 2]*p[2]+T[3, 3]),
          (T[2, 1]*p[1]+T[2, 2]*p[2]+T[2, 3])/(T[3, 1]*p[1]+T[3, 2]*p[2]+T[3, 3])
      ]:
    
    > # Transform pa, and construct the equation system
      pat := map(trans, pa, T):
      eqs := {op}(zip((p1, p2) -> op(zip(`=`, p1, p2)), pat, pb)):
    
    > # Solve for the transform variables
      sol := solve(eqs, V):
    
    > # Populate the transform
      eval(T, sol);
    

    输出:

    [[  .1076044020,   -3.957029830,    1074.517140  ],
     [ 4.795375318,      .3064507355,   -430.7044862 ],
     [ 0.3875626264e-3, 0.3441632491e-2,   1         ]]
    

    要使用它,请将其与服务器点相乘为T * <x, y, 1>


    void ServerToLocal(double serverX, double serverY, double *localX, double *localY)
    {
        double w;
        w = 0.3875626264e-3 * serverX + 0.3441632491e-2 * serverY + 1.0;
        *localX = (.1076044020 * serverX - 3.957029830 * serverY + 1074.517140) / w;
        *localY = (4.795375318 * serverX + .3064507355 * serverY - 430.7044862) / w;
    }
    

    另一种方法可以在http://alumni.media.mit.edu/~cwren/interpolator/阅读

    给定一个合理的线性代数库,这个可以用 C 语言编写。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-03-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-09
      • 2018-02-05
      • 1970-01-01
      相关资源
      最近更新 更多