Skip to content

Commit 5b5c3f3

Browse files
committed
1.2024.10.04: page split and deskew: complite order
1 parent fc0b38e commit 5b5c3f3

34 files changed

+654
-114
lines changed

src/stages/deskew/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@ SET(
2222
Params.cpp Params.h
2323
ApplyDialog.cpp ApplyDialog.h
2424
Utils.cpp Utils.h
25+
orders/OrderByTypeProvider.cpp orders/OrderByTypeProvider.h
2526
orders/OrderByAngleProvider.cpp orders/OrderByAngleProvider.h
27+
orders/OrderByAngleAbsProvider.cpp orders/OrderByAngleAbsProvider.h
2628
orders/OrderByAngleObliqueProvider.cpp orders/OrderByAngleObliqueProvider.h
2729
orders/OrderByAngleHorProvider.cpp orders/OrderByAngleHorProvider.h
2830
orders/OrderByAngleVertProvider.cpp orders/OrderByAngleVertProvider.h

src/stages/deskew/DewarpingParams.cpp

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,10 @@ DewarpingParams::getAngle() const
8080
{
8181
/* Conformal transform */
8282
float x[4], y[4], xc = 0.0f, yc = 0.0f, sx, sy, dx, dy;
83-
float sumxx = 0.0f, sumyy = 0.0f, sumxy;
84-
float sumxh, sumyh, sumxv, sumyv, sumd;
83+
float sumxx = 0.0f, sumyy = 0.0f;
84+
float sumxh = 0.0f, sumyh = 0.0f;
85+
float sumxv = 0.0f, sumyv = 0.0f;
86+
float sumxy, sumd;
8587
QPointF point_tl = m_distortionModel.topCurve().polyline().front();
8688
QPointF point_tr = m_distortionModel.topCurve().polyline().back();
8789
QPointF point_bl = m_distortionModel.bottomCurve().polyline().front();
@@ -105,6 +107,13 @@ DewarpingParams::getAngle() const
105107
{
106108
x[j] -= xc;
107109
y[j] -= yc;
110+
float xy = x[j] * y[j];
111+
x[j] = (x[j] < 0.0f) ? -x[j] : x[j];
112+
y[j] = (y[j] < 0.0f) ? -y[j] : y[j];
113+
sumxh += x[j];
114+
sumyh += y[j];
115+
sumxv += (xy < 0.0f) ? -x[j] : x[j];
116+
sumyv += (xy < 0.0f) ? -y[j] : y[j];
108117
sumxx += x[j] * x[j];
109118
sumyy += y[j] * y[j];
110119
}
@@ -113,13 +122,9 @@ DewarpingParams::getAngle() const
113122
{
114123
sx = sqrtf(sumxx * 0.25f);
115124
sy = sqrtf(sumyy * 0.25f);
116-
sumxh = x[1] - x[0] + x[3] - x[2];
117-
sumyh = y[0] + y[1] - y[2] - y[3];
118-
sumxv = x[0] + x[1] - x[2] - x[3];
119-
sumyv = y[1] - y[0] + y[3] - y[2];
120125

121126
dx = sumxh * sx + sumyh * sy;
122-
dy = sumyv * sx - sumxv * sy;
127+
dy = sumxv * sy - sumyv * sx;
123128
dx /= sumxy;
124129
dy /= sumxy;
125130

src/stages/deskew/Filter.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@
3434
#include "CacheDrivenTask.h"
3535
#include "RelinkablePath.h"
3636
#include "AbstractRelinker.h"
37+
#include "orders/OrderByTypeProvider.h"
3738
#include "orders/OrderByAngleProvider.h"
39+
#include "orders/OrderByAngleAbsProvider.h"
3840
#include "orders/OrderByAngleObliqueProvider.h"
3941
#include "orders/OrderByAngleHorProvider.h"
4042
#include "orders/OrderByAngleVertProvider.h"
@@ -55,12 +57,16 @@ Filter::Filter(PageSelectionAccessor const& page_selection_accessor)
5557
typedef PageOrderOption::ProviderPtr ProviderPtr;
5658

5759
ProviderPtr const default_order;
60+
ProviderPtr const order_by_type(new OrderByTypeProvider(m_ptrSettings));
5861
ProviderPtr const order_by_angle(new OrderByAngleProvider(m_ptrSettings));
62+
ProviderPtr const order_by_angle_abs(new OrderByAngleAbsProvider(m_ptrSettings));
5963
ProviderPtr const order_by_angle_oblique(new OrderByAngleObliqueProvider(m_ptrSettings));
6064
ProviderPtr const order_by_angle_hor(new OrderByAngleHorProvider(m_ptrSettings));
6165
ProviderPtr const order_by_angle_vert(new OrderByAngleVertProvider(m_ptrSettings));
6266
m_pageOrderOptions.push_back(PageOrderOption(tr("Natural order"), default_order));
67+
m_pageOrderOptions.push_back(PageOrderOption(tr("Order by type distortion"), order_by_type));
6368
m_pageOrderOptions.push_back(PageOrderOption(tr("Order by increasing angle"), order_by_angle));
69+
m_pageOrderOptions.push_back(PageOrderOption(tr("Order by angle size"), order_by_angle_abs));
6470
m_pageOrderOptions.push_back(PageOrderOption(tr("Order by oblique"), order_by_angle_oblique));
6571
m_pageOrderOptions.push_back(PageOrderOption(tr("Order by extension horizontally"), order_by_angle_hor));
6672
m_pageOrderOptions.push_back(PageOrderOption(tr("Order by extension vertically"), order_by_angle_vert));

src/stages/deskew/PerspectiveParams.cpp

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,10 @@ PerspectiveParams::getAngle() const
9292
{
9393
/* Conformal transform */
9494
float x[4], y[4], xc = 0.0f, yc = 0.0f, sx, sy, dx, dy;
95-
float sumxx = 0.0f, sumyy = 0.0f, sumxy;
96-
float sumxh, sumyh, sumxv, sumyv, sumd;
95+
float sumxx = 0.0f, sumyy = 0.0f;
96+
float sumxh = 0.0f, sumyh = 0.0f;
97+
float sumxv = 0.0f, sumyv = 0.0f;
98+
float sumxy, sumd;
9799
QPointF point_tl = corner(TOP_LEFT);
98100
QPointF point_tr = corner(TOP_RIGHT);
99101
QPointF point_bl = corner(BOTTOM_LEFT);
@@ -117,6 +119,13 @@ PerspectiveParams::getAngle() const
117119
{
118120
x[j] -= xc;
119121
y[j] -= yc;
122+
float xy = x[j] * y[j];
123+
x[j] = (x[j] < 0.0f) ? -x[j] : x[j];
124+
y[j] = (y[j] < 0.0f) ? -y[j] : y[j];
125+
sumxh += x[j];
126+
sumyh += y[j];
127+
sumxv += (xy < 0.0f) ? -x[j] : x[j];
128+
sumyv += (xy < 0.0f) ? -y[j] : y[j];
120129
sumxx += x[j] * x[j];
121130
sumyy += y[j] * y[j];
122131
}
@@ -125,13 +134,9 @@ PerspectiveParams::getAngle() const
125134
{
126135
sx = sqrtf(sumxx * 0.25f);
127136
sy = sqrtf(sumyy * 0.25f);
128-
sumxh = x[1] - x[0] + x[3] - x[2];
129-
sumyh = y[0] + y[1] - y[2] - y[3];
130-
sumxv = x[0] + x[1] - x[2] - x[3];
131-
sumyv = y[1] - y[0] + y[3] - y[2];
132137

133138
dx = sumxh * sx + sumyh * sy;
134-
dy = sumyv * sx - sumxv * sy;
139+
dy = sumxv * sy - sumyv * sx;
135140
dx /= sumxy;
136141
dy /= sumxy;
137142

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
/*
2+
Scan Tailor - Interactive post-processing tool for scanned pages.
3+
Copyright (C) Joseph Artsimovich <[email protected]>
4+
5+
This program is free software: you can redistribute it and/or modify
6+
it under the terms of the GNU General Public License as published by
7+
the Free Software Foundation, either version 3 of the License, or
8+
(at your option) any later version.
9+
10+
This program is distributed in the hope that it will be useful,
11+
but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
GNU General Public License for more details.
14+
15+
You should have received a copy of the GNU General Public License
16+
along with this program. If not, see <http://www.gnu.org/licenses/>.
17+
*/
18+
19+
#include <memory>
20+
#include "../Params.h"
21+
#include "OrderByAngleAbsProvider.h"
22+
23+
namespace deskew
24+
{
25+
26+
OrderByAngleAbsProvider::OrderByAngleAbsProvider(IntrusivePtr<Settings> const& settings)
27+
: m_ptrSettings(settings)
28+
{
29+
}
30+
31+
bool
32+
OrderByAngleAbsProvider::precedes(
33+
PageId const& lhs_page, bool const lhs_incomplete,
34+
PageId const& rhs_page, bool const rhs_incomplete) const
35+
{
36+
std::unique_ptr<Params> const lhs_params(m_ptrSettings->getPageParams(lhs_page));
37+
std::unique_ptr<Params> const rhs_params(m_ptrSettings->getPageParams(rhs_page));
38+
39+
bool const lhs_valid = !lhs_incomplete;
40+
bool const rhs_valid = !rhs_incomplete;
41+
42+
if (lhs_valid != rhs_valid)
43+
{
44+
// Invalid (unknown) sizes go to the back.
45+
return lhs_valid;
46+
}
47+
48+
double lhs_angle = 0.0;
49+
if (lhs_params.get())
50+
{
51+
switch (lhs_params->distortionType().get())
52+
{
53+
case DistortionType::NONE:
54+
lhs_angle = 0.0;
55+
break;
56+
case DistortionType::ROTATION:
57+
lhs_angle = -lhs_params->rotationParams().compensationAngleDeg();
58+
break;
59+
case DistortionType::PERSPECTIVE:
60+
lhs_angle = lhs_params->perspectiveParams().getAngle();
61+
break;
62+
case DistortionType::WARP:
63+
lhs_angle = lhs_params->dewarpingParams().getAngle();
64+
break;
65+
} // switch
66+
}
67+
lhs_angle = (lhs_angle < 0.0) ? -lhs_angle : lhs_angle;
68+
69+
double rhs_angle = 0.0;
70+
if (rhs_params.get())
71+
{
72+
switch (rhs_params->distortionType().get())
73+
{
74+
case DistortionType::NONE:
75+
rhs_angle = 0.0;
76+
break;
77+
case DistortionType::ROTATION:
78+
rhs_angle = -rhs_params->rotationParams().compensationAngleDeg();
79+
break;
80+
case DistortionType::PERSPECTIVE:
81+
rhs_angle = rhs_params->perspectiveParams().getAngle();
82+
break;
83+
case DistortionType::WARP:
84+
rhs_angle = rhs_params->dewarpingParams().getAngle();
85+
break;
86+
} // switch
87+
}
88+
rhs_angle = (rhs_angle < 0.0) ? -rhs_angle : rhs_angle;
89+
90+
if (lhs_angle == rhs_angle)
91+
{
92+
return (lhs_page < rhs_page);
93+
}
94+
else
95+
{
96+
return (lhs_angle < rhs_angle);
97+
}
98+
}
99+
100+
} // namespace deskew
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
Scan Tailor - Interactive post-processing tool for scanned pages.
3+
Copyright (C) Joseph Artsimovich <[email protected]>
4+
5+
This program is free software: you can redistribute it and/or modify
6+
it under the terms of the GNU General Public License as published by
7+
the Free Software Foundation, either version 3 of the License, or
8+
(at your option) any later version.
9+
10+
This program is distributed in the hope that it will be useful,
11+
but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
GNU General Public License for more details.
14+
15+
You should have received a copy of the GNU General Public License
16+
along with this program. If not, see <http://www.gnu.org/licenses/>.
17+
*/
18+
19+
#ifndef DESKEW_ORDER_BY_ANGLE_ABS_PROVIDER_H_
20+
#define DESKEW_ORDER_BY_ANGLE_ABS_PROVIDER_H_
21+
22+
#include "../Settings.h"
23+
#include "IntrusivePtr.h"
24+
#include "PageOrderProvider.h"
25+
26+
namespace deskew
27+
{
28+
29+
class OrderByAngleAbsProvider : public PageOrderProvider
30+
{
31+
public:
32+
OrderByAngleAbsProvider(IntrusivePtr<Settings> const& settings);
33+
34+
virtual bool precedes(
35+
PageId const& lhs_page, bool lhs_incomplete,
36+
PageId const& rhs_page, bool rhs_incomplete) const;
37+
private:
38+
IntrusivePtr<Settings> m_ptrSettings;
39+
};
40+
41+
} // namespace deskew
42+
43+
#endif

src/stages/deskew/orders/OrderByAngleHorProvider.cpp

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,15 @@ OrderByAngleHorProvider::precedes(
3636
std::unique_ptr<Params> const lhs_params(m_ptrSettings->getPageParams(lhs_page));
3737
std::unique_ptr<Params> const rhs_params(m_ptrSettings->getPageParams(rhs_page));
3838

39+
bool const lhs_valid = !lhs_incomplete;
40+
bool const rhs_valid = !rhs_incomplete;
41+
42+
if (lhs_valid != rhs_valid)
43+
{
44+
// Invalid (unknown) sizes go to the back.
45+
return lhs_valid;
46+
}
47+
3948
double lhs_angle = 0.0;
4049
if (lhs_params.get())
4150
{
@@ -55,6 +64,7 @@ OrderByAngleHorProvider::precedes(
5564
break;
5665
} // switch
5766
}
67+
5868
double rhs_angle = 0.0;
5969
if (rhs_params.get())
6070
{
@@ -75,16 +85,14 @@ OrderByAngleHorProvider::precedes(
7585
} // switch
7686
}
7787

78-
bool const lhs_valid = !lhs_incomplete;
79-
bool const rhs_valid = !rhs_incomplete;
80-
81-
if (lhs_valid != rhs_valid)
88+
if (lhs_angle == rhs_angle)
8289
{
83-
// Invalid (unknown) sizes go to the back.
84-
return lhs_valid;
90+
return (lhs_page < rhs_page);
91+
}
92+
else
93+
{
94+
return (lhs_angle < rhs_angle);
8595
}
86-
87-
return (lhs_angle < rhs_angle);
8896
}
8997

9098
} // namespace deskew

src/stages/deskew/orders/OrderByAngleObliqueProvider.cpp

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,15 @@ OrderByAngleObliqueProvider::precedes(
3636
std::unique_ptr<Params> const lhs_params(m_ptrSettings->getPageParams(lhs_page));
3737
std::unique_ptr<Params> const rhs_params(m_ptrSettings->getPageParams(rhs_page));
3838

39+
bool const lhs_valid = !lhs_incomplete;
40+
bool const rhs_valid = !rhs_incomplete;
41+
42+
if (lhs_valid != rhs_valid)
43+
{
44+
// Invalid (unknown) sizes go to the back.
45+
return lhs_valid;
46+
}
47+
3948
double lhs_angle = 0.0;
4049
if (lhs_params.get())
4150
{
@@ -55,6 +64,7 @@ OrderByAngleObliqueProvider::precedes(
5564
break;
5665
} // switch
5766
}
67+
5868
double rhs_angle = 0.0;
5969
if (rhs_params.get())
6070
{
@@ -75,16 +85,14 @@ OrderByAngleObliqueProvider::precedes(
7585
} // switch
7686
}
7787

78-
bool const lhs_valid = !lhs_incomplete;
79-
bool const rhs_valid = !rhs_incomplete;
80-
81-
if (lhs_valid != rhs_valid)
88+
if (lhs_angle == rhs_angle)
8289
{
83-
// Invalid (unknown) sizes go to the back.
84-
return lhs_valid;
90+
return (lhs_page < rhs_page);
91+
}
92+
else
93+
{
94+
return (lhs_angle < rhs_angle);
8595
}
86-
87-
return (lhs_angle < rhs_angle);
8896
}
8997

9098
} // namespace deskew

0 commit comments

Comments
 (0)