error: (-215:Assertion failed) scn + 1 == m.cols in function 'cv::perspectiveTransform'

Viewed 8128

Below is a python script that calculates the homography between two images and then map a desired point from one image to another

import cv2

import numpy as np


if __name__ == '__main__' :

  # Read source image.
  im_src = cv2.imread(r'C:/Users/kjbaili/.spyder-py3/webcam_calib/homography/khaledd 35.0 sec.jpg')

  # Five corners of the book in source image
  pts_src = np.array([[281, 238], [325, 297], [283, 330],[248, 325],[213, 321]])

  # Read destination image.
  im_dst = cv2.imread(r'C:/Users/kjbaili/.spyder-py3/webcam_calib/homography/20.jpg')

  # Five corners of the book in destination image.
  pts_dst = np.array([[377, 251],[377, 322],[316, 315],[289, 284],[263,255]])



  # Calculate Homography

  h, status = cv2.findHomography(pts_src, pts_dst)


  
  # provide a point i wish to map from image 1 to image 2
  a = np.array([[260, 228]])


  

  pointsOut = cv2.getPerspectiveTransform(a, h)

  # Display image
  cv2.imshow("treced_point_image", pointsOut)


  cv2.waitKey(0)
cv2.destroyAllWindows()

However, when i display the image that contains the mapped point it returns the following error:

error: OpenCV(4.2.0) C:\projects\opencv-python\opencv\modules\core\src\matmul.dispatch.cpp:531: 
error: (-215:Assertion failed) scn + 1 == m.cols in function 'cv::perspectiveTransform'

According to my knowledge this error means that parameter assigned to the function perspective transform is not correct or not being read. I checked the two images at the reading step and everything is fine. So anyone knows why this happens?

Thanks in advance Khaled

3 Answers

You are passing wrong arguments to cv2.getPerspectiveTransform(). The function expects a set of four coordinates in the original image and the new coordinates in the transformed image. You can directly pass the pts_src and pts_dst to the function and you will get the transformation matrix. You can then get the transformed coordinates for point "a" by matrix multiplication like a_transformed = np.dot(matrix, a).

I think there are two mistakes in your code. First, you use cv2.getPerspectiveTransform() to get the transform matrix. Secondly, to do the actual transformation of a point, you need to call cv2.perspectiveTransform(). The cv2.perspectiveTransform() is expecting a 3 or 4 dimensional matrix as input. So, you need to give something similar to the following. Notice the 3-dimensional array "pts" in the code below. I have only one point in the "pts" array. You can add more.

import cv2    
import numpy as np

src = np.float32([[0, 1280], [1920, 1280], [1920, 0], [0, 0]])    
dst = np.float32([[0, 600], [400, 600], [400, 0], [0, 0]])    
perspective_transform = cv2.getPerspectiveTransform(src, dst)    
pts = np.float32(np.array([[[1920, 1280]]]))    
warped_pt = cv2.perspectiveTransform(pts, perspective_transform)[0]    
print ("warped_pt = ", warped_pt)

I actually found out that the function cv2.findHomography() already does the job by finding the perspective transformation between two planes so that i no longer need the cv2.perspectiveTransform().

Related