user736358
user736358

Reputation: 11

OpenCV cv2 perspective transformation matrix multiplication

I am trying to combine a series of warpPerspective into one by combining the matrices generated by getPerspectiveTransform. If I multiply them together using cv2.multiply the resulting matrix doesn’t work. Example for just two transformations:

src = np.array([[0,0],[0,480],[640,480],[640,0]],np.float32)
dst = np.array([[-97,-718],[230,472],[421,472],[927,-717]],np.float32) 

retval = cv2.getPerspectiveTransform(src, dst);
test = cv2.multiply(retval.copy(),retval.copy())

img1 = cv2.warpPerspective(img1,test,(640,480))

img2 = cv2.warpPerspective(img2,retval,(640,480))
img2 = cv2.warpPerspective(img2,retval,(640,480))

Why aren't img1 and img2 the same? How do I combine the perspective transformation matrices?

Thanks

Upvotes: 1

Views: 3385

Answers (1)

Haydon Berrow
Haydon Berrow

Reputation: 495

You misunderstand the purpose of cv2.multiply(). It is for multiplying images and does point-by-point multiply so if A = cv2.multiply(B,C) then ai,j = bi,j * ci,j for all i,j.

To do a proper matrix-multiplication you need to either use the powerful but complex cv2.gemm() or use the fact that your generated transformation is a numpy array and use the inbuilt dot() function

import numpy as np  
import cv2

# test images
img1 = np.zeros((600,600,3),np.uint8)
img1[:] = (255,255,255)
cv2.fillConvexPoly( img1,np.array([(250,50),(350,50),(350,550),(250,550)],np.int32), (0,0,255) )
img2 = img1.copy()

# source and destination coordinates
src = np.array([[0,0],[0,480],[640,480],[640,0]],np.float32)
dst = np.array([[-97,-718],[230,472],[421,472],[927,-717]],np.float32) 
# transformation matrix
retval = cv2.getPerspectiveTransform(src, dst);

# test1 is wrong, test2 is the application of the transform twice
test1 = cv2.multiply(retval.copy(),retval.copy())
test2 = cv2.gemm(retval,retval,1,None,0) 
# test3 is using matrix-multiplication using numpy
test3 = retval.dot(retval)

img2 = cv2.warpPerspective(img1,test2,(640,480))
img3 = cv2.warpPerspective(img1,test3,(640,480))

img4 = cv2.warpPerspective(img1,retval,(640,480))
img4 = cv2.warpPerspective(img4,retval,(640,480))

cv2.imshow( "one application of doubled transform", img2 )
cv2.imshow( "one applications using numpy", img3 )
cv2.imshow( "two applications of single transform", img4 )
cv2.waitKey()

Be aware that cv2 transformations act from the left, so if you want to apply A and then B you must apply B.dot(A) as the combination.

Upvotes: 1

Related Questions