OpenCV - homographic conversion on point used for matrix computation does not match

134 Views Asked by At

I have an image taken from a given perspective. It includes a square of size 350mm in real world. I want to click on the image and know the coordinate of the point in real world. I thought I would use homographic transformation to do it.

I identified the square corners on the image (n_corners_px), and computed the homography matrix H in OpenCV. Then I reapplied a dot product btw H and my n_corners_px points, hoping to find an exact correspondence back with the coordinates of n_corners_mm (where n_corners_mm are corresponding points in real world). It worked for the origin [0, 0] point, but not for the [350, 350] corner point.

n_corners_px = np.array([[88, 102], [1808, 214], [1834, 1872], [109, 1986]])
n_corners_mm = np.array([[0, 350], [350, 350], [350, 0], [0, 0]])
    
H, _ = cv2.findHomography(n_corners_px, n_corners_mm)
    
np.isclose(np.dot(H,  np.append(n_corners_px[3], 1))[:2], n_corners_mm[3])  # True
np.isclose(np.dot(H,  np.append(n_corners_px[1], 1))[:2], n_corners_mm[1])  # False, left-hand size equals to [306.33, 306.33], NOT [350, 350]

It is as if the image was scaled down a bit.

The H matrix I get is:

    [[  0.17823,  -0.00199, -15.48154],
     [ -0.0122 ,  -0.18457, 367.88287],
     [ -0.00007,   0.     ,   1.     ]]

I checked that the image is straightened properly. cv2.warpPerspective(img, H, (img.shape[0], img.shape[1]) (where img is my original image) shows a square with right angles as intended.

> what should I do to get my square with the right 350x350 size?

1

There are 1 best solutions below

1
keuj6 On

Answer from @Micka solved my problem.

I had to divide the X, Y components of my transformed coordinates (AFTER dot product with homography matrix) by the Z component, which is a scale information:

np_transformed = np.dot(H,  np.append(n_corners_px[1], 1))
np.isclose(np_transformed[:2]/np_transformed[2], n_corners_mm[1])  # True