Reputation: 10224
I am trying to transform from a trapezoid (in the first image) to a rectangle (in the second image), but getting a strange result (in the third image).
My plan was to use a perspective transform, defined by the four corner points of the trapezoid and the four corner points of the rectangle.
In this example, for the trapezoid they are:
ptsTrap = [[ 50. 100. ]
[ 50. 200. ]
[ 250. 64.73460388]
[ 250. 235.26539612]]
and for the rectangle:
ptsRect = [[ 50. 100.]
[ 50. 200.]
[ 250. 100.]
[ 250. 200.]]
I am getting a perspective transform from these points:
T = cv2.getPerspectiveTransform(ptsTrap, ptsRect)
And then building the image from that:
arrTrapToRect = cv2.warpPerspective(arrTrap, T, arrTrap.shape[:2])
However, as you can see from the image, this isn't giving the expected transformation.
I can't seem to work out why even the points that defined the transform are not being projected according to it. Any ideas?
Upvotes: 5
Views: 4150
Reputation: 11329
Your methodology is correct. The problem arises when you specify the coordinates of your corner points. I don't know how you calculated them, but you have swapped your X and Y axes. This is reflected in the transformation applied to your final image. I find the corner points to be:
ptsTrap = [[[ 99. 51.]]
[[ 64. 251.]]
[[ 234. 251.]]
[[ 199. 51.]]]
ptsRect = [[[ 102. 49.]]
[[ 100. 249.]]
[[ 200. 250.]]
[[ 200. 50.]]]
Finding the perspective transform from these points gives the correct result:
For reference, this is the code I used:
import cv2
import numpy as np
def find_corners(image):
im = cv2.Canny(image, 100, 200)
cnt = cv2.findContours(im,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)[0]
cnt = cv2.approxPolyDP(cnt[0], 5, True)
return cnt.astype(np.float32)
def main(argv):
trap = cv2.imread('trap.png', cv2.IMREAD_GRAYSCALE)
rect = cv2.imread('rect.png', cv2.IMREAD_GRAYSCALE)
ptsTrap = find_corners(trap)
ptsRect = find_corners(rect)
T = cv2.getPerspectiveTransform(ptsTrap, ptsRect)
warp = cv2.warpPerspective(trap, T, rect.shape[:2])
cv2.imshow('', warp)
cv2.imwrite('warp.png', warp)
cv2.waitKey()
cv2.destroyAllWindows()
Upvotes: 9