Correctly apply LCP "distortion" correction for Fisheye lenses

Note: as discussed e.g. at http://lensfun.sourceforge.net/manual/corrections.html, this is really a combination of distortion correction and change of projection (from fisheye to rectilinear), but "distortion correction" is how the Adobe camera model calls it, and this is how it appears in the RT gui
This commit is contained in:
Alberto Griggio
2017-04-08 10:13:53 +02:00
parent 73e14702dd
commit 871c75e494
3 changed files with 65 additions and 26 deletions

View File

@@ -198,24 +198,52 @@ LCPMapper::LCPMapper(LCPProfile* pProf, float focalLength, float focalLength35mm
}
enableCA = !vignette && focusDist > 0;
isFisheye = pProf->isFisheye;
}
void LCPMapper::correctDistortion(double& x, double& y) const
void LCPMapper::correctDistortion(double& x, double& y, double scale) const
{
double xd = (x - mc.x0) / mc.fx, yd = (y - mc.y0) / mc.fy;
if (isFisheye) {
double u = x * scale;
double v = y * scale;
double u0 = mc.x0 * scale;
double v0 = mc.y0 * scale;
double du = (u - u0);
double dv = (v - v0);
double fx = mc.fx;
double fy = mc.fy;
double k1 = mc.param[0];
double k2 = mc.param[1];
double r = sqrt(du * du + dv * dv);
double f = sqrt(fx*fy / (scale * scale));
double th = atan2(r, f);
double th2 = th * th;
double cfact = (((k2 * th2 + k1) * th2 + 1) * th) / r;
double ud = cfact * fx * du + u0;
double vd = cfact * fy * dv + v0;
const LCPModelCommon::Param aDist = mc.param;
double rsqr = xd * xd + yd * yd;
double xfac = aDist[swapXY ? 3 : 4], yfac = aDist[swapXY ? 4 : 3];
x = ud;
y = vd;
} else {
x *= scale;
y *= scale;
double x0 = mc.x0 * scale;
double y0 = mc.y0 * scale;
double xd = (x - x0) / mc.fx, yd = (y - y0) / mc.fy;
double commonFac = (((aDist[2] * rsqr + aDist[1]) * rsqr + aDist[0]) * rsqr + 1.)
+ 2. * (yfac * yd + xfac * xd);
const LCPModelCommon::Param aDist = mc.param;
double rsqr = xd * xd + yd * yd;
double xfac = aDist[swapXY ? 3 : 4], yfac = aDist[swapXY ? 4 : 3];
double xnew = xd * commonFac + xfac * rsqr;
double ynew = yd * commonFac + yfac * rsqr;
double commonFac = (((aDist[2] * rsqr + aDist[1]) * rsqr + aDist[0]) * rsqr + 1.)
+ 2. * (yfac * yd + xfac * xd);
x = xnew * mc.fx + mc.x0;
y = ynew * mc.fy + mc.y0;
double xnew = xd * commonFac + xfac * rsqr;
double ynew = yd * commonFac + yfac * rsqr;
x = xnew * mc.fx + x0;
y = ynew * mc.fy + y0;
}
}
void LCPMapper::correctCA(double& x, double& y, int channel) const