7

I'm using OpenCV+Python+Numpy and I have three points in the image, I know the exact locations of those points.

(P1, P2);
 N1

I am going to transform the image to another view, (for example I am transforming the perspective view to side view). If I do so I will not have the exact location of those three points in the image plane. I should write the code in a way that I can get new coordinates of those points.

   pts1=np.float32([[867,652],[1020,580],[1206,666],[1057,757]]) 

   pts2=np.float32([[700,732],[869,754],[906,916],[712,906]])


   matrix=cv2.getPerspectiveTransform(pts1,pts2)


   result=cv2.warpPerspective(Image1,matrix,(1920,1080))

   cv2.imshow('Image',Image1) cv2.imshow('Tran',result)

My question is: How can I determine the new locations of those 3 points?

  • See for example, https://stackoverflow.com/questions/31147438/how-to-undo-a-perspective-transform-for-a-single-point-in-opencv – fmw42 Aug 07 '19 at 19:08

2 Answers2

21

Easy, you can look in the documentation how warpPerspective works. To transform the location of a point you can use the following transformation:

enter image description here

Where [x, y] is the original point, and M is your perspective matrix

Implementing this in python you can use the following code:

p = (50,100) # your original point
px = (matrix[0][0]*p[0] + matrix[0][1]*p[1] + matrix[0][2]) / ((matrix[2][0]*p[0] + matrix[2][1]*p[1] + matrix[2][2]))
py = (matrix[1][0]*p[0] + matrix[1][1]*p[1] + matrix[1][2]) / ((matrix[2][0]*p[0] + matrix[2][1]*p[1] + matrix[2][2]))
p_after = (int(px), int(py)) # after transformation

You can see the result in a code below. The red dot is your original point. The second figure shows where it went after the perspective transform. The blue circle is the point you calculated in formula above.

blue

You can have a look in my Jupyter Notebook here or here.

The code:

import numpy as np
import cv2
import matplotlib.pyplot as plt

# load the image, clone it for output, and then convert it to grayscale
image = cv2.imread('sample.png')
pts1=np.float32([[867,652],[1020,580],[1206,666],[1057,757]]) 
pts2=np.float32([[700,732],[869,754],[906,916],[712,906]])
matrix=cv2.getPerspectiveTransform(pts1,pts2)

# Draw the point
p = (50,100)
cv2.circle(image,p, 20, (255,0,0), -1)

# Put in perspective
result=cv2.warpPerspective(image,matrix,(1500,800))

# Show images
plt.imshow(image)
plt.title('Original')
plt.show()

plt.imshow(result)
plt.title('Distorced')
plt.show()

# Here you can transform your point
p = (50,100)
px = (matrix[0][0]*p[0] + matrix[0][1]*p[1] + matrix[0][2]) / ((matrix[2][0]*p[0] + matrix[2][1]*p[1] + matrix[2][2]))
py = (matrix[1][0]*p[0] + matrix[1][1]*p[1] + matrix[1][2]) / ((matrix[2][0]*p[0] + matrix[2][1]*p[1] + matrix[2][2]))
p_after = (int(px), int(py))

# Draw the new point
cv2.circle(result,p_after, 20, (0,0,255), 12)

# Show the result
plt.imshow(result)
plt.title('Predicted position of your point in blue')
plt.show()
Leonardo Mariga
  • 1,166
  • 9
  • 17
  • @ Leonardo Mariga, Is this equation "dst(x,y)=..." a mathematical equation? if not, could you please provide the mathematical equation for this transformation? I need to read more about the mathematics behind it. Thanks –  Oct 12 '19 at 19:37
  • @programmer yes, that is a mathematical equation. You acess the link I provided in [warpPerspective](https://docs.opencv.org/2.4/modules/imgproc/doc/geometric_transformations.html) to understand more about this equation. It is a simple space transformation. – Leonardo Mariga Oct 12 '19 at 23:27
  • if it is a mathematical equation, could you pls tell me what are dst and src? I understand that src is the source image. dst is the destination image. But I do not understand how they relate to mathematics? it looks as if they are functions in OpenCV. –  Oct 13 '19 at 01:27
  • This saved my life! – Marco Antonio Faganello Aug 25 '21 at 07:36
1

Have a look a the documentation, but in general:

cv2.perspectiveTransform(points, matrix)

For example:

# note you need to add a new axis, to match the supposed format
cv2.perspectiveTransform(pts1[np.newaxis, ...], matrix)
# returns array equal to pts2
Dima Mironov
  • 525
  • 4
  • 19
  • I need to transform the image as well. Since I will do some further measurements between those points. –  Aug 07 '19 at 19:07
  • 1
    I got error : `cv2.error: OpenCV(4.6.0) D:\a\opencv-python\opencv-python\opencv\modules\core\src\matmul.dispatch.cpp:550: error: (-215:Assertion failed) scn + 1 == m.cols in function 'cv::perspectiveTransform'` – Wade Wang Sep 04 '22 at 13:42