假设原始图像上特征点坐标为
x
i
=
(
u
i
,
v
i
,
1
)
x_i=(u_i,v_i,1)
xi=(ui,vi,1),目标图像上的坐标为
x
i
′
=
(
u
i
′
,
v
i
′
,
1
)
x_i'=(u_i',v_i',1)
xi′=(ui′,vi′,1)
假设
H
H
H 为两者之间的变换关系。
H
x
i
=
[
h
1
h
2
h
3
h
4
h
5
h
6
h
7
h
8
h
9
]
[
u
i
v
i
1
]
=
[
h
1
T
x
i
h
2
T
x
i
h
3
T
x
i
]
=
[
x
i
T
h
1
x
i
T
h
2
x
i
T
h
3
]
=
[
u
i
′
v
i
′
1
]
Hx_i= \begin{bmatrix} h_1&h_2&h_3\\h_4&h_5&h_6\\h_7&h_8&h_9 \end{bmatrix} \begin{bmatrix} u_i\\v_i\\1 \end{bmatrix} =\begin{bmatrix} h^{1T}x_i\\h^{2T}x_i\\h^{3T}x_i\end{bmatrix}= \begin{bmatrix}x_i^Th^1\\x_i^Th^2\\x_i^Th^3\end{bmatrix}= \begin{bmatrix}u_i'\\v_i'\\1 \end{bmatrix}
Hxi=
h1h4h7h2h5h8h3h6h9
uivi1
=
h1Txih2Txih3Txi
=
xiTh1xiTh2xiTh3
=
ui′vi′1
h i h_i hi代表 H 矩阵第 i 行的列向量表示。
可以通过 x i ′ ⋅ x i x_i'\cdot x_i xi′⋅xi得到三个线性方程:
{ x i T h 3 x i T h 1 = 1 u i ′ x i T h 3 x i T h 2 = 1 v i ′ x i T h 2 x i T h 1 = v i ′ u i ′ → { v i ′ x i h 3 − x i T h 2 = 0 u i ′ x i T h 3 − x i T h 1 = 0 u i ′ x i T h 2 − v i ′ x i T h 1 = 0 → [ 0 3 × 1 T − x i T v i ′ x i T x i T 0 3 × 1 T − u i ′ x i T − v i ′ x i T u i ′ x i T 0 3 × 1 T ] [ h 1 h 2 h 3 ] = 0 \begin{cases} \frac{x_i^Th^3}{x_i^Th_1}=\frac{1}{u_i'}\\ \frac{x_i^Th^3}{x_i^Th_2}=\frac{1}{v_i'}\\ \frac{x_i^Th^2}{x_i^Th_1}=\frac{v_i'}{u_i'} \end{cases} \rightarrow \begin{cases} v_i'x_ih^3-x_i^Th_2=0\\ u_i'x_i^Th_3-x_i^Th_1=0\\ u_i'x_i^Th_2-v_i'x_i^Th_1=0 \end{cases} \rightarrow \begin{bmatrix} 0_{3\times1}^T&-x_i^T&v_i'x_i^T\\x_i^T&0_{3\times1}^T&-u_i'x_i^T\\-v_i'x_i^T&u_i'x_i^T&0_{3\times1}^T \end{bmatrix} \begin{bmatrix} h^1\\h^2\\h^3 \end{bmatrix} =0 ⎩ ⎨ ⎧xiTh1xiTh3=ui′1xiTh2xiTh3=vi′1xiTh1xiTh2=ui′vi′→⎩ ⎨ ⎧vi′xih3−xiTh2=0ui′xiTh3−xiTh1=0ui′xiTh2−vi′xiTh1=0→ 03×1TxiT−vi′xiT−xiT03×1Tui′xiTvi′xiT−ui′xiT03×1T h1h2h3 =0
即有
A
i
(
3
)
h
=
0
A_i^{(3)}h=0
Ai(3)h=0 对于图像片的每一个点。
A
i
A_i
Ai 是一个
3
×
9
3\times9
3×9 矩阵,因为
A
A
A 的最后一行是由另外两行确定,所以只需要计算线性方程
A
^
i
h
^
=
0
\hat A_i \hat h=0
A^ih^=0。这里的
A
^
i
\hat A_i
A^i由
A
i
(
3
)
A_i^{(3)}
Ai(3)的前两行组成。A 的矩阵表示为:
在估计H时,可以使用更多的匹配点信息来减少估计误差。选取前两行组成一个独立的系数矩阵Ai,将所有的匹配点都考虑在内,形成一个2N × 9的系数矩阵a。用最小二乘法,h的解可以表示为
求解上述公式存在两种方式:
- 奇异值求解
通过SVD 求解 A 的最小右奇异向量作为 h的估计结果。 - 转化为非齐次线性最小二乘形式。
假设 h9=1,这时等式可以转换为
如果包含n 个匹配点
第一种方式源码如下:
# Ametrix to solv DLT
def matrix_generate(sample_n, cf1, cf2):
"""
AH=b
生成A
没对样本能生成一行
[[0,0,0,-x,-y,1,xy',yy',y'],[x,y,1,0,0,0,-xx',-yx',-x']]
:param sample_n:
:param cf1: 点1
:param cf2:
:return: A [2N,9]
"""
A = np.zeros([sample_n * 2, 9], dtype=np.float)
for k in range(sample_n):
# 每对点对应量
A[2 * k, 0] = cf1[k, 0]
A[2 * k, 1] = cf1[k, 1]
A[2 * k, 2] = 1
A[2 * k, 6] = (-cf2[k, 0]) * cf1[k, 0]
A[2 * k, 7] = (-cf2[k, 0]) * cf1[k, 1]
A[2 * k, 8] = (-cf2[k, 0])
A[2 * k + 1, 3] = cf1[k, 0]
A[2 * k + 1, 4] = cf1[k, 1]
A[2 * k + 1, 5] = 1
A[2 * k + 1, 6] = (-cf2[k, 1]) * cf1[k, 0]
A[2 * k + 1, 7] = (-cf2[k, 1]) * cf1[k, 1]
A[2 * k + 1, 8] = (-cf2[k, 1])
return A
def compute_H(src_points,dst_points):
A = self.matrix_generate(sample_n, cf1, cf2)
# SVD 奇异值求解
# Singular Value Decomposition
W, U, V = cv2.SVDecomp(A)
# get global-homography
h = V[-1, :]
h = h.reshape((3, 3))
# 反归一化用与还原
h = h / h[2, 2]
return h
第二种方式,以四组点为例,暂未补充