merge branch 'lcp-fisheye'
This commit is contained in:
@@ -1145,15 +1145,33 @@ bool Crop::setCropSizes (int rcx, int rcy, int rcw, int rch, int skip, bool inte
|
||||
parent->ipf.transCoord (parent->fw, parent->fh, bx1, by1, bw, bh, orx, ory, orw, orh);
|
||||
|
||||
if (check_need_larger_crop_for_lcp_distortion(parent->fw, parent->fh, orx, ory, orw, orh, parent->params)) {
|
||||
double dW = double(parent->fw) * 0.15 / skip; // TODO - this is hardcoded ATM!
|
||||
double dH = double(parent->fh) * 0.15 / skip; // this is an estimate of the max
|
||||
// distortion relative to the image
|
||||
// size. BUT IS 15% REALLY ENOUGH?
|
||||
// In fact, is there a better way??
|
||||
orx = max(int(orx - dW/2.0), 0);
|
||||
ory = max(int(ory - dH/2.0), 0);
|
||||
orw = min(int(orw + dW), parent->fw - orx);
|
||||
orh = min(int(orh + dH), parent->fh - ory);
|
||||
// TODO - this is an estimate of the max distortion relative to the image size. ATM it is hardcoded to be 15%, which seems enough. If not, need to revise
|
||||
int dW = int(double(parent->fw) * 0.15 / (2 * skip));
|
||||
int dH = int(double(parent->fh) * 0.15 / (2 * skip));
|
||||
int x1 = orx - dW;
|
||||
int x2 = orx + orw + dW;
|
||||
int y1 = ory - dH;
|
||||
int y2 = ory + orh + dH;
|
||||
if (x1 < 0) {
|
||||
x2 += -x1;
|
||||
x1 = 0;
|
||||
}
|
||||
if (x2 > parent->fw) {
|
||||
x1 -= x2 - parent->fw;
|
||||
x2 = parent->fw;
|
||||
}
|
||||
if (y1 < 0) {
|
||||
y2 += -y1;
|
||||
y1 = 0;
|
||||
}
|
||||
if (y2 > parent->fh) {
|
||||
y1 -= y2 - parent->fh;
|
||||
y2 = parent->fh;
|
||||
}
|
||||
orx = max(x1, 0);
|
||||
ory = max(y1, 0);
|
||||
orw = min(x2 - x1, parent->fw - orx);
|
||||
orh = min(y2 - y1, parent->fh - ory);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -85,16 +85,17 @@ float normn (float a, float b, int n)
|
||||
}
|
||||
}
|
||||
|
||||
void correct_distortion (const rtengine::LCPMapper *lcp, double &x, double &y,
|
||||
int cx, int cy)
|
||||
|
||||
void correct_distortion(const rtengine::LCPMapper *lcp, double &x, double &y,
|
||||
int cx, int cy, double scale)
|
||||
{
|
||||
assert (lcp);
|
||||
|
||||
x += cx;
|
||||
y += cy;
|
||||
lcp->correctDistortion (x, y);
|
||||
x -= cx;
|
||||
y -= cy;
|
||||
lcp->correctDistortion(x, y, scale);
|
||||
x -= (cx * scale);
|
||||
y -= (cy * scale);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -156,11 +157,14 @@ bool ImProcFunctions::transCoord (int W, int H, const std::vector<Coord2D> &src,
|
||||
double x_d = src[i].x, y_d = src[i].y;
|
||||
|
||||
if (pLCPMap && params->lensProf.useDist) {
|
||||
correct_distortion (pLCPMap, x_d, y_d, 0, 0);
|
||||
correct_distortion (pLCPMap, x_d, y_d, 0, 0, ascale);
|
||||
} else {
|
||||
x_d *= ascale;
|
||||
y_d *= ascale;
|
||||
}
|
||||
|
||||
y_d = ascale * (y_d - h2);
|
||||
x_d = ascale * (x_d - w2);
|
||||
x_d += ascale * (0 - w2); // centering x coord & scale
|
||||
y_d += ascale * (0 - h2); // centering y coord & scale
|
||||
|
||||
if (needsPerspective()) {
|
||||
// horizontal perspective transformation
|
||||
@@ -799,11 +803,14 @@ void ImProcFunctions::transformHighQuality (Imagefloat* original, Imagefloat* tr
|
||||
double x_d = x, y_d = y;
|
||||
|
||||
if (enableLCPDist) {
|
||||
correct_distortion (pLCPMap, x_d, y_d, cx, cy); // must be first transform
|
||||
correct_distortion(pLCPMap, x_d, y_d, cx, cy, ascale); // must be first transform
|
||||
} else {
|
||||
x_d *= ascale;
|
||||
y_d *= ascale;
|
||||
}
|
||||
|
||||
x_d = ascale * (x_d + cx - w2); // centering x coord & scale
|
||||
y_d = ascale * (y_d + cy - h2); // centering y coord & scale
|
||||
x_d += ascale * (cx - w2); // centering x coord & scale
|
||||
y_d += ascale * (cy - h2); // centering y coord & scale
|
||||
|
||||
double vig_x_d = 0., vig_y_d = 0.;
|
||||
|
||||
@@ -976,11 +983,14 @@ void ImProcFunctions::transformPreview (Imagefloat* original, Imagefloat* transf
|
||||
double x_d = x, y_d = y;
|
||||
|
||||
if (pLCPMap && params->lensProf.useDist) {
|
||||
correct_distortion (pLCPMap, x_d, y_d, cx, cy); // must be first transform
|
||||
correct_distortion(pLCPMap, x_d, y_d, cx, cy, ascale); // must be first transform
|
||||
} else {
|
||||
x_d *= ascale;
|
||||
y_d *= ascale;
|
||||
}
|
||||
|
||||
y_d = ascale * (y_d + cy - h2); // centering y coord & scale
|
||||
x_d = ascale * (x_d + cx - w2); // centering x coord & scale
|
||||
x_d += ascale * (cx - w2); // centering x coord & scale
|
||||
y_d += ascale * (cy - h2); // centering y coord & scale
|
||||
|
||||
double vig_x_d = 0., vig_y_d = 0.;
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -142,6 +142,7 @@ class LCPMapper
|
||||
bool swapXY;
|
||||
LCPModelCommon mc;
|
||||
LCPModelCommon chrom[3]; // in order RedGreen/Green/BlueGreen
|
||||
bool isFisheye;
|
||||
|
||||
public:
|
||||
bool enableCA; // is the mapper capable if CA correction?
|
||||
@@ -150,7 +151,7 @@ public:
|
||||
LCPMapper(LCPProfile* pProf, float focalLength, float focalLength35mm, float focusDist, float aperture, bool vignette, bool useCADistP, int fullWidth, int fullHeight,
|
||||
const CoarseTransformParams& coarse, int rawRotationDeg);
|
||||
|
||||
void correctDistortion(double& x, double& y) const; // MUST be the first stage
|
||||
void correctDistortion(double& x, double& y, double scale) const; // MUST be the first stage
|
||||
void correctCA(double& x, double& y, int channel) const;
|
||||
void processVignetteLine(int width, int y, float *line) const;
|
||||
void processVignetteLine3Channels(int width, int y, float *line) const;
|
||||
|
Reference in New Issue
Block a user