HW1: Projective Geometry and Homography

Kewen Wu

Q1: Affine Rectification (30 points)

  1. Affined Images
  2. Input Image Annotated parallel lines on input image Affine-Rectified Image
  3. Evaluate Angles: Checker1
  4. Before After
    0.8964 0.9999
    0.9574 0.9999
  5. Brief description of your implementation
  6. 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} \]

Q2: Metric Rectification (40 points)

  1. Metric Rectification images
  2. Input Image Annotated perpendicular lines on input image Annotated perpendicular lines on Affine-Rectified Image Rectified Image
  3. Evaluate Angles: Checker1
  4. Before After
    -0.2527 0.0018
    0.0882 0.0082
  5. Brief description of your implementation
  6. 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
    

Q3: Planar Homography from Point Correspondences (30 points)

  1. Warped images and intermediate images
  2. Normal Image Perspective Image Annotated corners in Perspective Image Warped and Overlaid Image
  3. Brief description
  4. \[ \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]
    

Q5: Bonus: More Planar Homography from Point Correspondences (10 points)

Input
Output

Submission

  1. Brief description of your implementation
  2. 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.