2012-05-23 118 views
5

我需要幫助,如何旋轉和縮放單應

I'm接收來自服務器的單應,所以我想這正常化單應到我的app's座標系,當我嘗試表示對象在座標中,服務器應用生成接下來的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(接收),P(本地)

enter image description here

它看起來像產生的方形旋轉和縮放,所以我會想知道是否有任何方法將此旋轉縮放應用於服務器單應性,以便能夠獲得與我的應用單應相同的單應性。

謝謝,我你需要更多的信息,請問我。


非常感謝您的快速解答,最後我使用其他近似,就這麼簡單從服務器獲取和使用findhomography得到逆單應的點。

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

謝謝!!!

+0

我不明白你想要做什麼。 – Thomash

+0

聽起來像透視轉換?你是否將一個四邊形映射到另一個? – PeskyGnat

+0

我想對單應應用修改,將此單應性轉換爲我的單位/座標系。 – Gustavo

回答

4

我想我明白了這一點。下面是你的兩個單應性的更準確的情節。藍色是'接受'的單應性,紅色是'本地'單應性。

enter image description here

您可以使用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的功能如由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,給予合理的線性代數庫被讀出。