2つの画像があり、ふるい分けを使用して3つの類似した2Dポイントを見つけました。画像間のアフィン変換を計算する必要があります。残念ながら、私は講義を逃しました、そしてそこにある情報は私にとって少し密集しています。この2x3行列を計算するための一般的な方法は何でしょうか?
2x3行列[x1y1; x2 y2; x3 y3]に点の行列がありますが、そこから失われます。助けてくれてありがとう。
通常、2D点のアフィン写像は次のように表現されます。
x' = A*x
ここで、x
は元の2D位置の3つのベクトル[x; y; 1]
であり、x'
は変換された点です。アフィン行列A
は
A = [a11 a12 a13;
a21 a22 a23;
0 0 1]
このフォームは、x
とA
がknownsであり、x'
を回復したい場合に役立ちます。
ただし、この関係は別の方法で表現できます。しましょう
X = [xi yi 1 0 0 0;
0 0 0 xi yi 1 ]
a
は列ベクトルです
a = [a11; a12; a13; a21; a22; a23]
次に
X*a = [xi'; yi']
対応するポイントのすべてのペアx_i, x_i'
を保持します。
この代替形式は、ポイントのペア間の対応がわかっていて、A
のパラメーターを復元したい場合に非常に役立ちます。
すべての点を大きな行列X
(各点に2行)に積み重ねると、2 * n x6の行列X
に6のベクトルを掛けたものになります。未知数a
は、積み重ねられた対応する点の2 * n x 1列ベクトルに等しい(x_prime
で示される):
X*a = x_prime
a
を解く:
a = X \ x_prime
最小二乗の意味でa
のパラメーターを回復します。
頑張って、クラスをスキップするのをやめてください!
Matlabを使用していないことをお詫びしますが、私はPython少しだけ作業しました。このコードが役立つと思います(コードスタイルが悪いのでごめんなさい-私はプログラマーではなく数学者です)
import numpy as np
# input data
ins = [[1, 1], [2, 3], [3, 2]] # <- points
out = [[0, 2], [1, 2], [-2, -1]] # <- mapped to
# calculations
l = len(ins)
B = np.vstack([np.transpose(ins), np.ones(l)])
D = 1.0 / np.linalg.det(B)
entry = lambda r,d: np.linalg.det(np.delete(np.vstack([r, B]), (d+1), axis=0))
M = [[(-1)**i * D * entry(R, i) for i in range(l)] for R in np.transpose(out)]
A, t = np.hsplit(np.array(M), [l-1])
t = np.transpose(t)[0]
# output
print("Affine transformation matrix:\n", A)
print("Affine transformation translation vector:\n", t)
# unittests
print("TESTING:")
for p, P in Zip(np.array(ins), np.array(out)):
image_p = np.dot(A, p) + t
result = "[OK]" if np.allclose(image_p, P) else "[ERROR]"
print(p, " mapped to: ", image_p, " ; expected: ", P, result)
このコードは、アフィン変換を行列およびベクトルとして復元する方法を示し、初期点が必要な場所にマップされていることをテストします。このコードは Google colab でテストできるため、何もインストールする必要はありません。おそらく、それをMatlabに翻訳することができます。
このコードの背後にある理論について:「 シンプレックスをアフィンにマッピングするための初心者向けガイド 」に示されている方程式に基づいています。行列の回復については、「正規表記の回復」のセクションで説明しています。同じ著者が「 シンプレックスのマッピングに関するワークブック 」を公開しました。これには、この種の実用的な例が多数含まれています。