Engauge Digitizer 2
Loading...
Searching...
No Matches
GridHealerHorizontal.cpp
Go to the documentation of this file.
1/******************************************************************************************************
2 * (C) 2018 markummitchell@github.com. This file is part of Engauge Digitizer, which is released *
3 * under GNU General Public License version 2 (GPLv2) or (at your option) any later version. See file *
4 * LICENSE or go to gnu.org/licenses for details. Distribution requires prior written permission. *
5 ******************************************************************************************************/
6
9#include "GridLog.h"
10#include "Pixels.h"
11#include <qmath.h>
12
14 const DocumentModelGridRemoval &modelGridRemoval) :
16 modelGridRemoval)
17{
18}
19
21{
22 MutualPairHalves::const_iterator itrBelow = mutualPairHalvesBelow().begin();
23 MutualPairHalves::const_iterator itrAbove = mutualPairHalvesAbove().begin();
24
25 while (itrBelow != mutualPairHalvesBelow().end() &&
27
28 QPoint p0 = *(itrBelow++);
29 QPoint p1 = *(itrAbove++);
30
31 // Save (independent,dependent) pairs
32 if (Pixels::pixelIsBlack (image, p0.x(), p0.y())) {
33 m_blackPixelsBelow [p0.x()] = p0.y();
34 }
35
36 if (Pixels::pixelIsBlack (image, p1.x(), p1.y())) {
37 m_blackPixelsAbove [p1.x()] = p1.y();
38 }
39
40 saveGapSeparation (qAbs (p1.y() - p0.y()));
41 }
42}
43
45{
46 // LOG4CPP_INFO_S is replaced by GridLog
47 GridIndependentToDependent::const_iterator itrBelow, itrAbove;
48 for (itrBelow = m_blackPixelsBelow.begin(); itrBelow != m_blackPixelsBelow.end(); itrBelow++) {
49 QPoint p (itrBelow.key(),
50 itrBelow.value());
53 }
54 for (itrAbove = m_blackPixelsAbove.begin(); itrAbove != m_blackPixelsAbove.end(); itrAbove++) {
55 QPoint p (itrAbove.key(),
56 itrAbove.value());
59 }
60
61 // Algorithm requires at least one point in each of the lists
62 if (m_blackPixelsBelow.count() > 0 &&
63 m_blackPixelsAbove.count() > 0) {
64
65 int xFirst = qMin (m_blackPixelsBelow.firstKey (),
66 m_blackPixelsAbove.firstKey ());
67 int xLast = qMax (m_blackPixelsBelow.lastKey (),
68 m_blackPixelsAbove.lastKey ());
69
70 int xBelowEnd = 0; // Used by inner loop to skip to this iterator value
71
73
74 if ((xBelowEnd < xBelowStart) &&
75 m_blackPixelsBelow.contains (xBelowStart)) {
76
77 // This could be the start of a new trapezoid. Find where the range on the same side ends
78 int xBelowOutOfBounds = xLast + 1; // Value forcing transition to out of range
79
81
82 if (!m_blackPixelsBelow.contains (xBelowEnd) || (xBelowEnd == xBelowOutOfBounds)) {
83
84 doHealingOnBelowRange (image,
88
89 // Go back to outer loop, which will skip to xBelowEnd
90 break;
91 }
92 }
93 }
94 }
95 }
96}
97
98void GridHealerHorizontal::doHealingOnBelowAndAboveRangePair (QImage &image,
99 int xBelowStart,
100 int xBelowEnd,
101 int xAboveStart,
102 int xAboveEnd)
103{
104 // LOG4CPP_INFO_S is replaced by GridLog
105
106 int x0 = xBelowStart;
107 int x1 = xBelowEnd;
108 int x2 = xAboveEnd;
109 int x3 = xAboveStart;
110 int y0 = m_blackPixelsBelow [xBelowStart];
111 int y1 = m_blackPixelsBelow [xBelowEnd ];
112 int y2 = m_blackPixelsAbove [xAboveEnd ];
113 int y3 = m_blackPixelsAbove [xAboveStart];
114
116 QPoint (x1, y1),
117 QPoint (x2, y2),
118 QPoint (x3, y3));
119
120 if (pointsAreGood (image, x0, y0, x2, y2)) {
121
122 // Big enough so keep it. Four points that define the trapezoid to be filled in
123 fillTrapezoid (image,
124 x0, y0,
125 x1, y1,
126 x2, y2,
127 x3, y3);
128 }
129}
130
131void GridHealerHorizontal::doHealingOnBelowRange (QImage &image,
132 int xBelowStart,
133 int xBelowEnd,
134 int maxHorSep)
135{
136 // LOG4CPP_INFO_S is replaced by GridLog
137
138 // Below range goes from xBelowStart (inclusive) to xBelowEnd (exclusive). There could
139 // be zero, one or more above ranges that overlap within maxHorSep, corresponding
140 // to an equal number of trapezoids to be filled in
141 //
142 // It is important to note that every above point between xBelowStart-maxHorSep to
143 // xBelowEnd+maxHorSep is close enough (<close distance) to a point in the below range
144
145 int xAboveOutOfBounds = xBelowEnd + maxHorSep + 1; // Value forcing transition to out of range
146
147 int xAboveEnd = 0; // Used by inner loop to skip to this iterator value
148
150
151 if ((xAboveEnd < xAboveStart) &&
152 m_blackPixelsAbove.contains (xAboveStart) &&
154
156
157 if (!m_blackPixelsAbove.contains (xAboveEnd) || (xAboveEnd == xAboveOutOfBounds)) {
158
162
164
165 doHealingOnBelowAndAboveRangePair (image,
170
171 // Go back to outer loop, which will skip to xAboveEnd
172 break;
173 }
174 }
175 }
176 }
177 }
178}
const int INNER_RADIUS_MIN
const double HALFWIDTH_HORIZONTAL
Model for DlgSettingsGridRemoval and CmdSettingsGridRemoval. The settings are unstable until the user...
Class that 'heals' the curves after one grid line has been removed.
bool pointsAreGood(const QImage &image, int x0, int y0, int x1, int y1) const
Apply blackPixelRegionIsBigEnough to regions around each of two points.
const MutualPairHalves & mutualPairHalvesAbove() const
Mutual pair halves for below grid line.
const MutualPairHalves & mutualPairHalvesBelow() const
Mutual pair halves for above grid line.
GridLog & gridLog()
Logging get method.
double maxPointSeparation() const
Max point separation get method.
void fillTrapezoid(QImage &image, int xBL, int yBL, int xBR, int yBR, int xTR, int yTR, int xTL, int yTL)
Fill trapezoid with bottom left, bottom right, top right, and top left points.
void saveGapSeparation(double gapSeparation)
Gap separation set method.
GridHealerHorizontal(GridLog &gridLog, const DocumentModelGridRemoval &modelGridRemoval)
Single constructor.
virtual void doHealingAcrossGaps(QImage &image)
Guts of the algorithm in which sequences of black pixels across the gap from each other are filled in...
virtual void applyMutualPairs(const QImage &image)
Apply mutual pair points after all grid removal is done.
Class that does special logging for GridLog and GridRemoval classes.
Definition GridLog.h:17
void showOutputTrapezoid(const QPoint &p0, const QPoint &p1, const QPoint &p2, const QPoint &p3)
Show trapezoids that are intermediate results in GridHealer.
Definition GridLog.cpp:104
void showInputPixel(const QPoint &p, double halfWidth)
Show pixels that are inputs to GridHealer.
Definition GridLog.cpp:68
static bool pixelIsBlack(const QImage &image, int x, int y)
Return true if pixel is black in black and white image.
Definition Pixels.cpp:286