Question

I am trying to rectify an image using a perspective warp in OpenCV and Python. I know the orientation of the camera (X, Y, Z angles) in reference the plane that needs warping. I know that the easiest method is to compute a homography matrix based on known points, however I am trying to do the same thing when that information is not available. The code which I am working with creates a rotational matrix then combines the translational and intrinsic matrices. Currently the code only works with manipulations to the z axis. Any manipulation of the x and y axis results in weird distortion of the image. I am basing my code off the answer at the bottom of the following post: Perspective Warping in OpenCV based on know camera orientation

Attached is the original image and a warped image from the standard homography method.

Original ImagePerspective Warp

from numpy import *
import cv

x = float(0)
y = float(5)
z = float(0)
f = 1

im = cv.LoadImage("Homography_test.jpg")
cv.NamedWindow("Distorted")
cv.NamedWindow("undistorted")

h, w = cv.GetSize(im)

x1 = x * (pi / 180)
y1 = y * (pi / 180)
z1 = z * (pi / 180)

# Create a rotation matrix
R_array = array([[x1], [y1], [z1]])
R_Vec = cv.fromarray(R_array)
R = cv.CreateMat(3, 3, cv.CV_64FC1)

cv.Rodrigues2(R_Vec, R)

#Create and combine with translation matrix
Trans_Mat = array([[[1], [0], [-w/2]],
                    [[0], [1], [-h/2]],
                    [[0], [0], [1]]])

Trans_Mat2 = cv.fromarray(Trans_Mat)
R_T_Mat = dot(R, Trans_Mat2)

#Create and combine with camera matrix
Intrinsic_Mat = array([[[f], [0], [w/2]],
                       [[0], [f], [h/2]],
                       [[0], [0], [1]]])

Int_Mat = cv.fromarray(Intrinsic_Mat)
H = dot(Int_Mat, R_T_Mat)
H2 = cv.fromarray(H)

persp = cv.CreateImage(cv.GetSize(im), cv.IPL_DEPTH_8U, 3)
cv.WarpPerspective(im, persp, H2)

cv.ShowImage("Distorted", im)
cv.ShowImage("undistorted", persp)

cv.WaitKey(0)
cv.DestroyWindow("Distorted")
cv.DestroyWindow("undistorted")
Was it helpful?

Solution

you seem to be missing step 4 from my solution which was "move the image down the z axis" the line I used to do that was.

//4
trans(2,2) += image.rows;

I chose image.rows arbitrarily, it gave a good sense of scale to the rotation I used in the example. Since you are not doing that your z coord is fixed at 1. I would imagine that is the cause of the distortion when you rotate around x and y, essentially since the image is so close to the camera when it rotates around x or y the perspective distortion is massive. The larger the translation down the z axis the smaller the distortion should appear. If you don't want the image to shrink as it moves down the z axis, just increase your focal length as well. You might notice in my example I set my focal length to be image.rows.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top