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?
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: