Skip to content

Commit

Permalink
1.2024.10.04: page split and deskew: complite order
Browse files Browse the repository at this point in the history
  • Loading branch information
zvezdochiot committed Oct 4, 2024
1 parent fc0b38e commit 5b5c3f3
Show file tree
Hide file tree
Showing 34 changed files with 654 additions and 114 deletions.
2 changes: 2 additions & 0 deletions src/stages/deskew/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ SET(
Params.cpp Params.h
ApplyDialog.cpp ApplyDialog.h
Utils.cpp Utils.h
orders/OrderByTypeProvider.cpp orders/OrderByTypeProvider.h
orders/OrderByAngleProvider.cpp orders/OrderByAngleProvider.h
orders/OrderByAngleAbsProvider.cpp orders/OrderByAngleAbsProvider.h
orders/OrderByAngleObliqueProvider.cpp orders/OrderByAngleObliqueProvider.h
orders/OrderByAngleHorProvider.cpp orders/OrderByAngleHorProvider.h
orders/OrderByAngleVertProvider.cpp orders/OrderByAngleVertProvider.h
Expand Down
19 changes: 12 additions & 7 deletions src/stages/deskew/DewarpingParams.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,10 @@ DewarpingParams::getAngle() const
{
/* Conformal transform */
float x[4], y[4], xc = 0.0f, yc = 0.0f, sx, sy, dx, dy;
float sumxx = 0.0f, sumyy = 0.0f, sumxy;
float sumxh, sumyh, sumxv, sumyv, sumd;
float sumxx = 0.0f, sumyy = 0.0f;
float sumxh = 0.0f, sumyh = 0.0f;
float sumxv = 0.0f, sumyv = 0.0f;
float sumxy, sumd;
QPointF point_tl = m_distortionModel.topCurve().polyline().front();
QPointF point_tr = m_distortionModel.topCurve().polyline().back();
QPointF point_bl = m_distortionModel.bottomCurve().polyline().front();
Expand All @@ -105,6 +107,13 @@ DewarpingParams::getAngle() const
{
x[j] -= xc;
y[j] -= yc;
float xy = x[j] * y[j];
x[j] = (x[j] < 0.0f) ? -x[j] : x[j];
y[j] = (y[j] < 0.0f) ? -y[j] : y[j];
sumxh += x[j];
sumyh += y[j];
sumxv += (xy < 0.0f) ? -x[j] : x[j];
sumyv += (xy < 0.0f) ? -y[j] : y[j];
sumxx += x[j] * x[j];
sumyy += y[j] * y[j];
}
Expand All @@ -113,13 +122,9 @@ DewarpingParams::getAngle() const
{
sx = sqrtf(sumxx * 0.25f);
sy = sqrtf(sumyy * 0.25f);
sumxh = x[1] - x[0] + x[3] - x[2];
sumyh = y[0] + y[1] - y[2] - y[3];
sumxv = x[0] + x[1] - x[2] - x[3];
sumyv = y[1] - y[0] + y[3] - y[2];

dx = sumxh * sx + sumyh * sy;
dy = sumyv * sx - sumxv * sy;
dy = sumxv * sy - sumyv * sx;
dx /= sumxy;
dy /= sumxy;

Expand Down
6 changes: 6 additions & 0 deletions src/stages/deskew/Filter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@
#include "CacheDrivenTask.h"
#include "RelinkablePath.h"
#include "AbstractRelinker.h"
#include "orders/OrderByTypeProvider.h"
#include "orders/OrderByAngleProvider.h"
#include "orders/OrderByAngleAbsProvider.h"
#include "orders/OrderByAngleObliqueProvider.h"
#include "orders/OrderByAngleHorProvider.h"
#include "orders/OrderByAngleVertProvider.h"
Expand All @@ -55,12 +57,16 @@ Filter::Filter(PageSelectionAccessor const& page_selection_accessor)
typedef PageOrderOption::ProviderPtr ProviderPtr;

ProviderPtr const default_order;
ProviderPtr const order_by_type(new OrderByTypeProvider(m_ptrSettings));
ProviderPtr const order_by_angle(new OrderByAngleProvider(m_ptrSettings));
ProviderPtr const order_by_angle_abs(new OrderByAngleAbsProvider(m_ptrSettings));
ProviderPtr const order_by_angle_oblique(new OrderByAngleObliqueProvider(m_ptrSettings));
ProviderPtr const order_by_angle_hor(new OrderByAngleHorProvider(m_ptrSettings));
ProviderPtr const order_by_angle_vert(new OrderByAngleVertProvider(m_ptrSettings));
m_pageOrderOptions.push_back(PageOrderOption(tr("Natural order"), default_order));
m_pageOrderOptions.push_back(PageOrderOption(tr("Order by type distortion"), order_by_type));
m_pageOrderOptions.push_back(PageOrderOption(tr("Order by increasing angle"), order_by_angle));
m_pageOrderOptions.push_back(PageOrderOption(tr("Order by angle size"), order_by_angle_abs));
m_pageOrderOptions.push_back(PageOrderOption(tr("Order by oblique"), order_by_angle_oblique));
m_pageOrderOptions.push_back(PageOrderOption(tr("Order by extension horizontally"), order_by_angle_hor));
m_pageOrderOptions.push_back(PageOrderOption(tr("Order by extension vertically"), order_by_angle_vert));
Expand Down
19 changes: 12 additions & 7 deletions src/stages/deskew/PerspectiveParams.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,10 @@ PerspectiveParams::getAngle() const
{
/* Conformal transform */
float x[4], y[4], xc = 0.0f, yc = 0.0f, sx, sy, dx, dy;
float sumxx = 0.0f, sumyy = 0.0f, sumxy;
float sumxh, sumyh, sumxv, sumyv, sumd;
float sumxx = 0.0f, sumyy = 0.0f;
float sumxh = 0.0f, sumyh = 0.0f;
float sumxv = 0.0f, sumyv = 0.0f;
float sumxy, sumd;
QPointF point_tl = corner(TOP_LEFT);
QPointF point_tr = corner(TOP_RIGHT);
QPointF point_bl = corner(BOTTOM_LEFT);
Expand All @@ -117,6 +119,13 @@ PerspectiveParams::getAngle() const
{
x[j] -= xc;
y[j] -= yc;
float xy = x[j] * y[j];
x[j] = (x[j] < 0.0f) ? -x[j] : x[j];
y[j] = (y[j] < 0.0f) ? -y[j] : y[j];
sumxh += x[j];
sumyh += y[j];
sumxv += (xy < 0.0f) ? -x[j] : x[j];
sumyv += (xy < 0.0f) ? -y[j] : y[j];
sumxx += x[j] * x[j];
sumyy += y[j] * y[j];
}
Expand All @@ -125,13 +134,9 @@ PerspectiveParams::getAngle() const
{
sx = sqrtf(sumxx * 0.25f);
sy = sqrtf(sumyy * 0.25f);
sumxh = x[1] - x[0] + x[3] - x[2];
sumyh = y[0] + y[1] - y[2] - y[3];
sumxv = x[0] + x[1] - x[2] - x[3];
sumyv = y[1] - y[0] + y[3] - y[2];

dx = sumxh * sx + sumyh * sy;
dy = sumyv * sx - sumxv * sy;
dy = sumxv * sy - sumyv * sx;
dx /= sumxy;
dy /= sumxy;

Expand Down
100 changes: 100 additions & 0 deletions src/stages/deskew/orders/OrderByAngleAbsProvider.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/*
Scan Tailor - Interactive post-processing tool for scanned pages.
Copyright (C) Joseph Artsimovich <joseph.artsimovich@gmail.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#include <memory>
#include "../Params.h"
#include "OrderByAngleAbsProvider.h"

namespace deskew
{

OrderByAngleAbsProvider::OrderByAngleAbsProvider(IntrusivePtr<Settings> const& settings)
: m_ptrSettings(settings)
{
}

bool
OrderByAngleAbsProvider::precedes(
PageId const& lhs_page, bool const lhs_incomplete,
PageId const& rhs_page, bool const rhs_incomplete) const
{
std::unique_ptr<Params> const lhs_params(m_ptrSettings->getPageParams(lhs_page));
std::unique_ptr<Params> const rhs_params(m_ptrSettings->getPageParams(rhs_page));

bool const lhs_valid = !lhs_incomplete;
bool const rhs_valid = !rhs_incomplete;

if (lhs_valid != rhs_valid)
{
// Invalid (unknown) sizes go to the back.
return lhs_valid;
}

double lhs_angle = 0.0;
if (lhs_params.get())
{
switch (lhs_params->distortionType().get())
{
case DistortionType::NONE:
lhs_angle = 0.0;
break;
case DistortionType::ROTATION:
lhs_angle = -lhs_params->rotationParams().compensationAngleDeg();
break;
case DistortionType::PERSPECTIVE:
lhs_angle = lhs_params->perspectiveParams().getAngle();
break;
case DistortionType::WARP:
lhs_angle = lhs_params->dewarpingParams().getAngle();
break;
} // switch
}
lhs_angle = (lhs_angle < 0.0) ? -lhs_angle : lhs_angle;

double rhs_angle = 0.0;
if (rhs_params.get())
{
switch (rhs_params->distortionType().get())
{
case DistortionType::NONE:
rhs_angle = 0.0;
break;
case DistortionType::ROTATION:
rhs_angle = -rhs_params->rotationParams().compensationAngleDeg();
break;
case DistortionType::PERSPECTIVE:
rhs_angle = rhs_params->perspectiveParams().getAngle();
break;
case DistortionType::WARP:
rhs_angle = rhs_params->dewarpingParams().getAngle();
break;
} // switch
}
rhs_angle = (rhs_angle < 0.0) ? -rhs_angle : rhs_angle;

if (lhs_angle == rhs_angle)
{
return (lhs_page < rhs_page);
}
else
{
return (lhs_angle < rhs_angle);
}
}

} // namespace deskew
43 changes: 43 additions & 0 deletions src/stages/deskew/orders/OrderByAngleAbsProvider.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
Scan Tailor - Interactive post-processing tool for scanned pages.
Copyright (C) Joseph Artsimovich <joseph.artsimovich@gmail.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef DESKEW_ORDER_BY_ANGLE_ABS_PROVIDER_H_
#define DESKEW_ORDER_BY_ANGLE_ABS_PROVIDER_H_

#include "../Settings.h"
#include "IntrusivePtr.h"
#include "PageOrderProvider.h"

namespace deskew
{

class OrderByAngleAbsProvider : public PageOrderProvider
{
public:
OrderByAngleAbsProvider(IntrusivePtr<Settings> const& settings);

virtual bool precedes(
PageId const& lhs_page, bool lhs_incomplete,
PageId const& rhs_page, bool rhs_incomplete) const;
private:
IntrusivePtr<Settings> m_ptrSettings;
};

} // namespace deskew

#endif
24 changes: 16 additions & 8 deletions src/stages/deskew/orders/OrderByAngleHorProvider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,15 @@ OrderByAngleHorProvider::precedes(
std::unique_ptr<Params> const lhs_params(m_ptrSettings->getPageParams(lhs_page));
std::unique_ptr<Params> const rhs_params(m_ptrSettings->getPageParams(rhs_page));

bool const lhs_valid = !lhs_incomplete;
bool const rhs_valid = !rhs_incomplete;

if (lhs_valid != rhs_valid)
{
// Invalid (unknown) sizes go to the back.
return lhs_valid;
}

double lhs_angle = 0.0;
if (lhs_params.get())
{
Expand All @@ -55,6 +64,7 @@ OrderByAngleHorProvider::precedes(
break;
} // switch
}

double rhs_angle = 0.0;
if (rhs_params.get())
{
Expand All @@ -75,16 +85,14 @@ OrderByAngleHorProvider::precedes(
} // switch
}

bool const lhs_valid = !lhs_incomplete;
bool const rhs_valid = !rhs_incomplete;

if (lhs_valid != rhs_valid)
if (lhs_angle == rhs_angle)
{
// Invalid (unknown) sizes go to the back.
return lhs_valid;
return (lhs_page < rhs_page);
}
else
{
return (lhs_angle < rhs_angle);
}

return (lhs_angle < rhs_angle);
}

} // namespace deskew
24 changes: 16 additions & 8 deletions src/stages/deskew/orders/OrderByAngleObliqueProvider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,15 @@ OrderByAngleObliqueProvider::precedes(
std::unique_ptr<Params> const lhs_params(m_ptrSettings->getPageParams(lhs_page));
std::unique_ptr<Params> const rhs_params(m_ptrSettings->getPageParams(rhs_page));

bool const lhs_valid = !lhs_incomplete;
bool const rhs_valid = !rhs_incomplete;

if (lhs_valid != rhs_valid)
{
// Invalid (unknown) sizes go to the back.
return lhs_valid;
}

double lhs_angle = 0.0;
if (lhs_params.get())
{
Expand All @@ -55,6 +64,7 @@ OrderByAngleObliqueProvider::precedes(
break;
} // switch
}

double rhs_angle = 0.0;
if (rhs_params.get())
{
Expand All @@ -75,16 +85,14 @@ OrderByAngleObliqueProvider::precedes(
} // switch
}

bool const lhs_valid = !lhs_incomplete;
bool const rhs_valid = !rhs_incomplete;

if (lhs_valid != rhs_valid)
if (lhs_angle == rhs_angle)
{
// Invalid (unknown) sizes go to the back.
return lhs_valid;
return (lhs_page < rhs_page);
}
else
{
return (lhs_angle < rhs_angle);
}

return (lhs_angle < rhs_angle);
}

} // namespace deskew
Loading

0 comments on commit 5b5c3f3

Please sign in to comment.