Skip to content

Commit

Permalink
4.13.4: dewarping: replacing Lagrange with Akima spline
Browse files Browse the repository at this point in the history
  • Loading branch information
zvezdochiot committed Dec 19, 2022
1 parent 5436dfb commit 34d27ba
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 13 deletions.
2 changes: 1 addition & 1 deletion src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,12 @@ Window:: Window()
fileMenu->addAction("Paste Image", this, SLOT(openFromClipboard()));
fileBtn->setMenu(fileMenu);
QMenu *transformMenu = new QMenu(transformBtn);
transformMenu->addAction("Mirror Image", this, SLOT(mirror()));
QMenu *geometryMenu = transformMenu->addMenu("Geometry");
geometryMenu->addAction("Un-tilt Image", this, SLOT(perspectiveTransform()));
geometryMenu->addAction("DeWarping", this, SLOT(deWarping()));
geometryMenu->addAction("DeOblique", this, SLOT(deOblique()));
geometryMenu->addAction("Lens Distortion", this, SLOT(lensDistort()));
transformMenu->addAction("Mirror Image", this, SLOT(mirror()));
transformMenu->addAction("Rotate by ...", this, SLOT(rotateAny()));
transformBtn->setMenu(transformMenu);
QMenu *decorateMenu = new QMenu(decorateBtn);
Expand Down
89 changes: 77 additions & 12 deletions src/transform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -609,7 +609,7 @@ DeWarping(Canvas *canvas, QStatusBar *statusbar, int count) : QObject(canvas),
lnd << QPointF(pixmap.width(), 0);
lndt << QPointF(pixmap.width(), 0);
// add buttons
LagrangeCheck = new QCheckBox("Lagrange?", statusbar);
LagrangeCheck = new QCheckBox("Akima?", statusbar);
statusbar->addPermanentWidget(LagrangeCheck);
EqualAreaCheck = new QCheckBox("Equal Area?", statusbar);
statusbar->addPermanentWidget(EqualAreaCheck);
Expand Down Expand Up @@ -746,9 +746,10 @@ DeWarping:: EqualAreaMode()
void
DeWarping:: transform()
{
int i, n, y, x, w, h, ih, id, ic;
int i, n, y, x, w, h, ih, id;
// int ic; // InterpolateLagrangePolynomial
float yh, yd, dyh, dyd, yk0, yk1, yk2, oy;
QPolygonF lni;
// QPolygonF lni; // InterpolateLagrangePolynomial
n = lnh.count();
if (n > 4)
{
Expand Down Expand Up @@ -780,6 +781,7 @@ DeWarping:: transform()
}
if (flagrange)
{
/* // InterpolateLagrangePolynomial
lni.clear();
ic = (ih < 3) ? 3 : (ih > n - 3) ? (n - 3) : ih;
for (i = ic - 2; i < ic + 2; i++)
Expand All @@ -792,21 +794,17 @@ DeWarping:: transform()
yd = InterpolateLagrangePolynomial (x, lni);
yh = (yh < 1.0f) ? 1.0f : ((yh < h - 1) ? yh : (h - 1));
yd = (yd < 1.0f) ? 1.0f : ((yd < h - 1) ? yd : (h - 1));
*/
yh = InterpolateAkima (x, lnh);
yd = InterpolateAkima (x, lnd);
yh = (yh < 1.0f) ? 1.0f : ((yh < h - 1) ? yh : (h - 1));
yd = (yd < 1.0f) ? 1.0f : ((yd < h - 1) ? yd : (h - 1));
}
else
{
yh = (float)lnh[ih - 1].y() + dyh * (x - lnh[ih - 1].x());
yd = (float)lnd[id - 1].y() + dyd * (x - lnd[id - 1].x());
}
/*
if (yh < yd)
{
yh += yd;
yh *= 0.5f;
yh += 0.5f;
yd = yh - 1.0f;
}
*/
yk0 = yd / ylnd;
yk1 = (yh - yd) / (ylnh - ylnd);
yk2 = (h - yh) / (h - ylnh);
Expand Down Expand Up @@ -1123,6 +1121,73 @@ float InterpolateLagrangePolynomial (float x, QPolygonF p)
return lagrange_pol;
}

float InterpolateAkima (float x, QPolygonF p)
{
int i, k, l, n = p.count();
float xt, dx, dy, a, b, fx, val, m[5], t[2];

k = 0;
dx = (p[n - 1].x() - p[0].x()) / n;
for (i = 1; i < (n - 1); i++)
{
xt = p[i].x();
k = (xt < x) ? i : k;
}
if (k < 2)
{
for (i = (2 - k); i < 5; i++)
{
l = k + i - 2;
dx = p[l + 1].x() - p[l].x();
dy = p[l + 1].y() - p[l].y();
m[i] = (dx > 0.0f) ? (dy / dx) : 0.0f;
}
for (i = (1 - k); i >= 0; i--)
{
m[i] = 2.0f * m[i + 1] - m[i + 2];
}
}
else
{
if (k > (n - 4))
{
for (i = 0; i < (n - k + 1); i++)
{
l = k + i - 2;
dx = p[l + 1].x() - p[l].x();
dy = p[l + 1].y() - p[l].y();
m[i] = (dx > 0.0f) ? (dy / dx) : 0.0f;
}
for (i = (n - k + 1); i < 5; i++)
{
m[i] = 2.0f * m[i - 1] - m[i - 2];
}
}
else
{
for (i = 0; i < 5; i++)
{
l = k + i - 2;
dx = p[l + 1].x() - p[l].x();
dy = p[l + 1].y() - p[l].y();
m[i] = (dx > 0.0f) ? (dy / dx) : 0.0f;
}
}
}
for(i = 0; i < 2; i++)
{
a = (m[i + 2] > m[i + 3]) ? (m[i + 2] - m[i + 3]) : (m[i + 3] - m[i + 2]);
b = (m[i] > m[i + 1]) ? (m[i] - m[i + 1]) : (m[i + 1] - m[i]);
t[i] = ((a + b) > 0) ? ((a * m[i + 1] + b * m[i + 2]) / (a + b)) : (0.5f * (m[i + 1] + m[i + 2]));
}
dx = x - p[k].x();
dy = p[k + 1].x() - p[k].x();
fx = (dy > 0.0f) ? (dx / dy) : 0.0f;
val = p[k].y() + t[0] * dx + (3.0f * m[2] - 2.0f * t[0] - t[1]) * dx * fx + (t[0] + t[1] - 2.0f * m[2]) * dx * fx * fx;

return val;
}

QRgb InterpolateBiCubic (QImage img, float y, float x)
{
int i, d, dn, xi, yi, xf, yf;
Expand Down
1 change: 1 addition & 0 deletions src/transform.h
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,7 @@ void calcArc(QPointF center, QPointF from, QPointF to, QPointF through,
float &start, float &span);
float calcArea(QPolygonF p);
float InterpolateLagrangePolynomial (float x, QPolygonF p);
float InterpolateAkima (float x, QPolygonF p);
QRgb InterpolateBiCubic (QImage img, float y, float x);
// transformation end

Expand Down

0 comments on commit 34d27ba

Please sign in to comment.