The method below to remove lens distortion from a camera was written more than ten years ago and I am trying to understand how the approximation works.

void Distortion::removeLensDistortion(const V2 &dist, V2 &ideal) const
 const int ITERATIONS=10;
 V2 xn;
 xn.x=(dist.x - lensParam.centerX)/lensParam.fX;
 xn.y=(dist.y - lensParam.centerY)/lensParam.fY;

 V2 x=xn;
 for (int i=0;i<ITERATIONS;i++) {
   double r2 = Utilities::square(x.x)+Utilities::square(x.y);
   double r4 = Utilities::square(r2);
   double rad=1+lensParam.kc1 * r2 + lensParam.kc2 * r4;

As a reminder:

  • lensParam.centerX and lensParam.centerY is the principal point
  • lensParam.fX and lensParam.fY is the focal length in pixel
  • lensParam.kc1 and lensParam.kc2 are the first two radial distortion coefficients. This is $k_1$ and $k_2$ in the formula below.

The formula to add lens distortion given the first two radial distortion parameters is as follows:

$$ x_{distorted} = x_{undistorted} \cdot (1+k_1\cdot r^2 + k_2 \cdot r^4) \\ y_{distorted} = y_{undistorted} \cdot (1+k_1\cdot r^2 + k_2 \cdot r^4) $$ where $r^2=x_{undistorted}^2+y_{undistorted}^2$ and $r^4=(r^2)^2$

In the code above, the term $(1+k_1\cdot r^2 + k_2 \cdot r^4)$ is calculated and saved in the variable rad and the distorted x is divided by rad in each of the ten iterations.

All of the cameras we use have a pincushion distortion (so $k_1<0$)

The question is how is this algorithm approximating the undistorted image points? Do you know if there is any paper in which this algorithm is proposed?

The opencv undistortion may be a bit similar, so that link may be useful but it is not quite the same though.


Welcome to SP. I happen to have already answered your question in SO: see point 2 of my answer here.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.