Input Image | Annotated parallel lines on input image | Affine-Rectified Image |
---|---|---|
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
Before | After |
---|---|
0.8964 | 0.9999 |
0.9574 | 0.9999 |
First of all, identify pairs of parallel lines. Then calculate the vanishing line.
l1 = np.cross(points[0], points[1])
l2 = np.cross(points[2], points[3])
l3 = np.cross(points[4], points[5])
l4 = np.cross(points[6], points[7])
temp1 = np.cross(l1, l2)
temp2 = np.cross(l3, l4)
temp1 = temp1 / temp1[2]
temp2 = temp2 / temp2[2]
vanishing_line = np.cross(temp1, temp2)
\[ l^{'}_{\infty} = H^{-T}_A \cdot l_{\infty} \]
Therefore:
\[ H_A = \begin{bmatrix} 1 & 0 & 0\\ 0 & 1 & 0\\ \frac{l_1}{l_3} & \frac{l_2}{l_3} & 1 \end{bmatrix} \]
Input Image | Annotated perpendicular lines on input image | Annotated perpendicular lines on Affine-Rectified Image | Rectified Image |
---|---|---|---|
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
Before | After |
---|---|
-0.2527 | 0.0018 |
0.0882 | 0.0082 |
For annotation, annotate two pairs of orthogonal lines.
Since the photo has already been affined in Q1:
\[ l' \begin{bmatrix} KK^T & 0\\ 0 & 0 \end{bmatrix} m = 0 \]
Calculate the K:
C = np.array([-l1[1]*m1[1], -l2[1]*m2[1]])
A = np.array([[l1[0]*m1[0], l1[0]*m1[1] + l1[1]*m1[0]], [l2[0]*m2[0], l2[0]*m2[1] + l2[1]*m2[0]]])
s = np.matmul(np.linalg.inv(A), C)
s_new = np.array([[s[0], s[1]], [s[1], 1]])
U,D,V = np.linalg.svd(s_new)
sigma = np.sqrt(D)
sigma_matrix = np.array([[sigma[0],0],[0,sigma[1]]])
K = U @ sigma_matrix @ V
Normal Image | Perspective Image | Annotated corners in Perspective Image | Warped and Overlaid Image |
---|---|---|---|
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
\[ \mathbf{H} = \begin{bmatrix} h_{11} & h_{12} & h_{13} \\ h_{21} & h_{22} & h_{23} \\ h_{31} & h_{32} & h_{33} \end{bmatrix} \]
\[ x' = \frac{h_{11}x + h_{12}y + h_{13}}{h_{31}x + h_{32}y + h_{33}}, \quad y' = \frac{h_{21}x + h_{22}y + h_{23}}{h_{31}x + h_{32}y + h_{33}} \]
\[ \begin{bmatrix} x & y & 1 & 0 & 0 & 0 & -x' x & -x' y & -x' \\ 0 & 0 & 0 & x & y & 1 & -y' x & -y' y & -y' \end{bmatrix} \begin{bmatrix} h_{11} \\ h_{12} \\ h_{13} \\ h_{21} \\ h_{22} \\ h_{23} \\ h_{31} \\ h_{32} \\ h_{33} \end{bmatrix} = \mathbf{0} \]
Therefore, using 4 pairs of correspondence points, we can calculate the \( H \). Then normalize \( H \). After that, we warp the image to the background image:
mask = np.ones((x1.shape[0],x1.shape[1],1))
size = (x2.shape[1],x2.shape[0])
warped_mask = cv2.warpPerspective(mask, np.linalg.inv(H), size).astype(bool)
warped_x1 = cv2.warpPerspective(x1, np.linalg.inv(H), size)
x2[warped_mask] = warped_x1[warped_mask]
Input |
---|
![]() |
Output |
---|
![]() |
Pick three images and pick three rectangles in the background image.
Then use the method in Q3 to warp the three images to the background rectangles.