延續前一篇的內容,在相機一座標系下的 點 和在相機二座標系下的 點 之間的關係是:
左右兩邊都同時乘上 ,這裡的 是 的 skew-symmetric matrix:
再將左右兩邊同時乘上 ,由於 與 垂直( 的特性),所以:
將 代入:
這個式子就是出名的對極約束 (Epipolar constraint),這個式子包含了相機的內參 ,外參 ,以及兩個相機的投影點 ,全部放到了一個等式當中,我們可以這樣理解這個式子:
如果我們把 組合成一個 3x3 矩陣 ,這個矩陣就是本質矩陣 (Essential Matrix):
把相機內參 也考慮進去,我們可以得到基礎矩陣 (Fundamental Matrix):
如果我們已知一個像素在相機二的投影點 ,而且不知道 和 的情況下,我們可以用基礎矩陣 和 epipolar constraint 得到一個 的線性方程式,也就是說 會在一條線上,這條線就是對極線 (Epipolar Line),如下圖:
先前計算相機姿態的程式碼,裡面就有利用 opencv 的 cv2.findEssentialMat
得到 essential matrix ,這裡我們可以利用這個 和相機內參得到 fundamental matrix ,並且給定 就可以畫出在另一張圖上的對極線,程式碼如下:
def plot_epipolar_line(image1, image2, point1, point2, E, K):
# Make point1 homogenous
point1 = np.array(point1.tolist() + [1])
# Compute fundamental matrix
F = np.linalg.inv(K).T @ E @ np.linalg.inv(K)
line = F @ point1.T
line /= np.linalg.norm(line[:2])
line = line.ravel()
x = np.array([0, image1.shape[1]])
y = (-line[2] - line[0] * x) / line[1]
# Plot the result
plt.figure()
plt.subplot(121)
plt.axis("off")
plt.imshow(cv2.cvtColor(image1, cv2.COLOR_BGR2RGB))
plt.plot(point1[0], point1[1], "ro")
plt.subplot(122)
plt.axis("off")
plt.imshow(cv2.cvtColor(image2, cv2.COLOR_BGR2RGB))
plt.plot(point2[0], point2[1], "ro")
plt.plot(x, y, c="b")
plt.show()
plot_epipolar_line(rgb1, rgb2, points1[0], points2[0], E, intrinsic)
結果如圖,可以看到對應點 就在對極線上: