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:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user