7 #include "DocumentModelGridRemoval.h" 8 #include "EngaugeAssert.h" 9 #include "GridHealer.h" 16 const BoundaryGroup BOUNDARY_GROUP_FIRST = 100;
20 m_boundaryGroupNext (BOUNDARY_GROUP_FIRST),
21 m_modelGridRemoval (modelGridRemoval)
23 LOG4CPP_INFO_S ((*mainCat)) <<
"GridHealer::GridHealer";
26 ENGAUGE_ASSERT (NUM_PIXEL_STATES < BOUNDARY_GROUP_FIRST);
28 m_pixels.resize (imageBefore.height());
29 for (
int row = 0; row < imageBefore.height(); row++) {
30 m_pixels [row].resize (imageBefore.width());
32 for (
int col = 0; col < imageBefore.width(); col++) {
34 QRgb rgb = imageBefore.pixel(col, row);
35 if (qGray (rgb) > 128) {
36 m_pixels [row] [col] = PIXEL_STATE_BACKGROUND;
38 m_pixels [row] [col] = PIXEL_STATE_FOREGROUND;
44 void GridHealer::connectCloseGroups(QImage &imageToHeal)
46 LOG4CPP_INFO_S ((*mainCat)) <<
"GridHealer::connectCloseGroups";
49 for (
int iFrom = 0; iFrom < m_groupNumberToCentroid.count() - 1; iFrom++) {
51 BoundaryGroup groupFrom = m_groupNumberToCentroid.keys().at (iFrom);
53 ENGAUGE_ASSERT (m_groupNumberToCentroid.contains (groupFrom));
54 ENGAUGE_ASSERT (m_groupNumberToPixel.contains (groupFrom));
56 QPointF posCentroidFrom = m_groupNumberToCentroid [groupFrom];
57 QPointF pixelPointFrom = m_groupNumberToPixel [groupFrom];
59 for (
int iTo = iFrom + 1; iTo < m_groupNumberToCentroid.count(); iTo++) {
61 BoundaryGroup groupTo = m_groupNumberToCentroid.keys().at (iTo);
63 ENGAUGE_ASSERT (m_groupNumberToCentroid.contains (groupTo));
64 ENGAUGE_ASSERT (m_groupNumberToPixel.contains (groupTo));
66 QPointF posCentroidTo = m_groupNumberToCentroid [groupTo];
67 QPointF pixelPointTo = m_groupNumberToPixel [groupTo];
69 QPointF separation = posCentroidFrom - posCentroidTo;
70 double separationMagnitude = qSqrt (separation.x() * separation.x() + separation.y() * separation.y());
72 if (separationMagnitude < m_modelGridRemoval.
closeDistance()) {
75 int count = 1 + qMax (qAbs (pixelPointFrom.x() - pixelPointTo.x()),
76 qAbs (pixelPointFrom.y() - pixelPointTo.y()));
78 for (
int index = 0; index < count; index++) {
81 double s = (double) index / (
double) (count - 1);
82 int xCol = (int) (0.5 + (1.0 - s) * pixelPointFrom.y() + s * pixelPointTo.y());
83 int yRow = (int) (0.5 + (1.0 - s) * pixelPointFrom.x() + s * pixelPointTo.x());
84 m_pixels [yRow] [xCol] = PIXEL_STATE_HEALED;
87 imageToHeal.setPixel (QPoint (xCol,
99 m_pixels [yRow] [xCol] = PIXEL_STATE_REMOVED;
101 for (
int rowOffset = -1; rowOffset <= 1; rowOffset++) {
102 int rowSearch = yRow + rowOffset;
103 if (0 <= rowSearch && rowSearch < m_pixels.count()) {
105 for (
int colOffset = -1; colOffset <= 1; colOffset++) {
106 int colSearch = xCol + colOffset;
107 if (0 <= colSearch && colSearch < m_pixels[0].count()) {
109 if (m_pixels [rowSearch] [colSearch] == PIXEL_STATE_FOREGROUND) {
111 m_pixels [rowSearch] [colSearch] = PIXEL_STATE_ADJACENT;
120 void GridHealer::groupContiguousAdjacentPixels()
122 LOG4CPP_INFO_S ((*mainCat)) <<
"GridHealer::groupContiguousAdjacentPixels";
124 for (
int row = 0; row < m_pixels.count(); row++) {
125 for (
int col = 0; col < m_pixels [0].count(); col++) {
127 if (m_pixels [row] [col] == PIXEL_STATE_ADJACENT) {
131 int centroidCount = 0;
132 double rowCentroidSum = 0, colCentroidSum = 0;
134 recursiveSearchForAdjacentPixels (m_boundaryGroupNext,
142 m_groupNumberToCentroid [m_boundaryGroupNext] = QPointF (rowCentroidSum / centroidCount,
143 colCentroidSum / centroidCount);
144 m_groupNumberToPixel [m_boundaryGroupNext] = QPointF (row,
147 ++m_boundaryGroupNext;
155 LOG4CPP_INFO_S ((*mainCat)) <<
"GridHealer::heal";
157 groupContiguousAdjacentPixels ();
158 connectCloseGroups (imageToHeal);
161 void GridHealer::recursiveSearchForAdjacentPixels (
int boundaryGroup,
165 double &rowCentroidSum,
166 double &colCentroidSum)
168 ENGAUGE_ASSERT (m_pixels [row] [col] == PIXEL_STATE_ADJACENT);
172 rowCentroidSum += row;
173 colCentroidSum += col;
175 m_pixels [row] [col] = boundaryGroup;
177 for (
int rowOffset = -1; rowOffset <= 1; rowOffset++) {
178 int rowNeighbor = row + rowOffset;
179 if (0 <= rowNeighbor && rowNeighbor < m_pixels.count()) {
181 for (
int colOffset = -1; colOffset <= 1; colOffset++) {
182 int colNeighbor = col + colOffset;
183 if (0 <= colNeighbor && colNeighbor < m_pixels[0].count()) {
185 if (m_pixels [rowNeighbor] [colNeighbor] == PIXEL_STATE_ADJACENT) {
187 recursiveSearchForAdjacentPixels (boundaryGroup,
double closeDistance() const
Get method for close distance.
void erasePixel(int xCol, int yRow)
Remember that pixel was erased since it belongs to an grid line.
GridHealer(const QImage &imageBefore, const DocumentModelGridRemoval &modelGridRemoval)
Single constructor.
Model for DlgSettingsGridRemoval and CmdSettingsGridRemoval. The settings are unstable until the user...
void heal(QImage &imageToHeal)
Heal the broken curve lines by spanning the gaps across the newly-removed grid lines.