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

5

8

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

Depriest answered 2/7, 2020 at 11:53 Comment(1)
See answer here: #27585855Sander
M
2

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).

Moist answered 2/7, 2020 at 12:20 Comment(3)
I've done that :trans_mtx = cv2.perspectiveTransform(pts_src,pts_dst), Still the same error.Depriest
You need to pass exactly four points. Also try to add the data type, when declaring the points: pts_src = np.array([[281, 238], [325, 297], [283, 330],[248, 325]], dtype=np.float32). Note that I have arbitrarily dropped the fifth value. You need to figure out, which coordinates you want to keep.Moist
Still the same. I solved it using cv2.findHomography(). However, thanks for replyingDepriest
A
3

I think there are two mistakes in your code. First, you should 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

# determine the transform matrix
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)    

# use the above matrix to transform required pixels
pts = np.float32(np.array([[[1920, 1280]]]))    
warped_pt = cv2.perspectiveTransform(pts, perspective_transform)[0]    
print ("warped_pt = ", warped_pt)
Alroi answered 29/12, 2021 at 9:46 Comment(0)
M
2

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).

Moist answered 2/7, 2020 at 12:20 Comment(3)
I've done that :trans_mtx = cv2.perspectiveTransform(pts_src,pts_dst), Still the same error.Depriest
You need to pass exactly four points. Also try to add the data type, when declaring the points: pts_src = np.array([[281, 238], [325, 297], [283, 330],[248, 325]], dtype=np.float32). Note that I have arbitrarily dropped the fifth value. You need to figure out, which coordinates you want to keep.Moist
Still the same. I solved it using cv2.findHomography(). However, thanks for replyingDepriest
P
2

Note: Code snippets are in Python language. Find Transformation matrix: So in principle, you may use either of the following methods to compute transformation matrix.

i) cv2.findHomography() OR ii) cv2.getPerspectiveTransform()

Small difference is that when you provide 4 set of manual points that you are confident with, you may use cv2.getPerspectiveTransform(), but when you have 50 points and want to filter points using techniques like RANSAC, use cv2.findHomography().

Transform points using transformation matrix:

You may transform points using transformation matrix with two options: i) Transform set of points using perspectiveTransform(). You may need to make sure the datatype needs to be a float64 numpy array (use pts = np.array(pts,np.float64)) with resulting shape of (n,1,2) (pts = pts.reshape((-1, 1, 2))).

ii) (Obtained from accepted answer)Transform individual point using 'np.dot(transformation_matrix, a)'. where 'a' is an XY co-ordinate.

Preconscious answered 19/10, 2023 at 15:18 Comment(0)
H
0

This error also occurs when H is None. This can happen in some (not closer specified in the docs) cases:

Note that whenever an H matrix cannot be estimated, an empty one will be returned.

Hokanson answered 8/8 at 9:49 Comment(0)
D
-1

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().

Depriest answered 2/7, 2020 at 13:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.