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?
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) cnt = cv2.approxPolyDP(cnt, 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()