I'm trying to use a camera model to reconstruct images one could have taken with certain cameras and their (extrinsic/intrinsic) parameters. This I don't have any problems with. Now I want to add distortions as they are described in OpenCV(seems to be the reference model).
The goal is to get a vector for every pixel in the camera grid which I can then use to determine the point it reaches on a surface (i.e. a plane with distance 1 to the camera). Sadly there only seems to be a function for the other direction, being given a point in the world I can compute the corresponding point in the image plane. This method is called projectPoints().
Is there an inverse function of this? I can't seem to find one or a different reliable method/python module. Thank you in advance.
Okay, I've read up a bit and it seems like there is no closed form solution at all for this direction! I do solve it now by iteratively approximating the solution. I only use 5 distortion coefficients, but it should be possible to extend that to more. The first guess is simply the undistorted vectors.
This is the code I use and it is reasonable fast:
def distort(D, coeff, th=10e-7, MAXITER=40):
undistorted = D
k1, k2, p1, p2, k3 = coeff
done = True
i = 0
while(done):
undistorted_old = undistorted
xn, yn = undistorted
xn2 = np.square(xn)
yn2 = np.square(yn)
r2 = xn2 + yn2
r4 = np.square(r2)
r6 = r4 * r2
xyn2 = 2 * xn * yn
# radial and tangential distortions
DR = np.tile((1 + k1*r2 + k2*r4 + k3*r6), (2,1))
DT = np.array([p1*xyn2 + p2*(r2 + 2*xn2), p2*xyn2 + p1*(r2 + 2*yn2)])
# Update
undistorted = (D-DT) / DR
# calculate error
error = undistorted_old - undistorted
if ((np.sum(np.square(error)) < th) or (i==MAXITER)):
done=False
i=i+1
return undistorted
Hope that helps!