Can't understand how to get (x', y') of original (x, y) in image, for Barrel/Pincushion distortion.
4 Answers
Section 2 of this paper explains the transformation. Basically:
Here I made an example in Mathematica:

- 60,527
- 15
- 115
- 190
-
3When recreating this code in openGL without trimming (like you have in the 1st 2 pictures) the image looked disjointed. I had more success using this algorithm http://www.geeks3d.com/20140213/glsl-shader-library-fish-eye-and-dome-and-barrel-distortion-post-processing-filters/2/ – user819640 Sep 29 '15 at 08:42
-
Your transform is only valid for turning a rectilinear image into a distorted image, to reverse that distortion you need the inverse function which is `p1 = cbrt(2 / (3 * a)); p2 = cbrt( sqrt(3*a) * sqrt( 27*a*x*x + 4 ) - 9*a*x ); p3 = cbrt(2) * pow(3*a, 2/3); return p1/p2 - p2/p3;` – Michel Rouzic Apr 16 '17 at 19:43
simple barrel\pincushion distortion in opencv c++
IplImage* barrel_pincusion_dist(IplImage* img, double Cx,double Cy,double kx,double ky)
{
IplImage* mapx = cvCreateImage( cvGetSize(img), IPL_DEPTH_32F, 1 );
IplImage* mapy = cvCreateImage( cvGetSize(img), IPL_DEPTH_32F, 1 );
int w= img->width;
int h= img->height;
float* pbuf = (float*)mapx->imageData;
for (int y = 0; y < h; y++)
{
for (int x = 0; x < w; x++)
{
float u= Cx+(x-Cx)*(1+kx*((x-Cx)*(x-Cx)+(y-Cy)*(y-Cy)));
*pbuf = u;
++pbuf;
}
}
pbuf = (float*)mapy->imageData;
for (int y = 0;y < h; y++)
{
for (int x = 0; x < w; x++)
{
*pbuf = Cy+(y-Cy)*(1+ky*((x-Cx)*(x-Cx)+(y-Cy)*(y-Cy)));
++pbuf;
}
}
/*float* pbuf = (float*)mapx->imageData;
for (int y = 0; y < h; y++)
{
int ty= y-Cy;
for (int x = 0; x < w; x++)
{
int tx= x-Cx;
int rt= tx*tx+ty*ty;
*pbuf = (float)(tx*(1+kx*rt)+Cx);
++pbuf;
}
}
pbuf = (float*)mapy->imageData;
for (int y = 0;y < h; y++)
{
int ty= y-Cy;
for (int x = 0; x < w; x++)
{
int tx= x-Cx;
int rt= tx*tx+ty*ty;
*pbuf = (float)(ty*(1+ky*rt)+Cy);
++pbuf;
}
}*/
IplImage* temp = cvCloneImage(img);
cvRemap( temp, img, mapx, mapy );
cvReleaseImage(&temp);
cvReleaseImage(&mapx);
cvReleaseImage(&mapy);
return img;
}
more complicated form http://opencv.willowgarage.com/documentation/camera_calibration_and_3d_reconstruction.html

- 20,061
- 36
- 171
- 301
An approximation of the polynomial radial distortion model you can find in Fitzgibbon, 2001
is
where rd and ru are the distances from the center of distortion. This is also used to filter the distortion out of a wide-angle camera image for computer vision and image processing purposes.
You can find a more detailed explanation of the principle and the shader code to implement the undistortion filtering (and also the forward transformation) here: http://marcodiiga.github.io/radial-lens-undistortion-filtering
I'm also posting the papers you should take a look at if you want to know the mathematical details for the method I posted
- Zhang Z. (1999). Flexible camera calibration by viewing a plane from unknown orientation
- Andrew W. Fitzgibbon (2001). Simultaneous linear estimation of multiple view geometry and lens distortion

- 43,032
- 26
- 132
- 246
According to Wikipedia, there can also be an r to the power 4 term too. The signs of the two constants (for the r to the 2 and r to the 4 terms) can be opposite giving handlebar distortion where the centre of the image has barrel distortion and the edge has pincushion distortion giving straight lines the appearance of a handlebar moustache.

- 1,597
- 1
- 14
- 22