2

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;
   x.x/=rad;
   x.y/=rad;
 }
 ideal.x=x.x*lensParam.fX+lensParam.centerX;
 ideal.y=x.y*lensParam.fY+lensParam.centerY;
}

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 * (1+k_1 * r² + k_2 * r^4) 
y_distorted = y_undistorted * (1+k_1 * r² + k_2 * r^4)

where r²=(x_undistorted)²+(y_undistorted)² and r^4=(r²)²

In the code above, the term (1+k_1 * r² + k_2 * 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.

0 Answers0