7 #include "ColorFilter.h"
8 #include "DocumentModelSegments.h"
9 #include "EngaugeAssert.h"
11 #include <QApplication>
12 #include <QGraphicsScene>
14 #include <QProgressDialog>
16 #include "SegmentFactory.h"
24 m_isGnuplot (isGnuplot)
26 LOG4CPP_INFO_S ((*mainCat)) <<
"SegmentFactory::SegmentFactory";
29 int SegmentFactory::adjacentRuns(
bool *columnBool,
36 for (
int y = yStart - 1; y <= yStop + 1; y++) {
37 if ((0 <= y) && (y < height)) {
38 if (!inRun && columnBool [y]) {
41 }
else if (inRun && !columnBool [y]) {
50 Segment *SegmentFactory::adjacentSegment(SegmentVector &lastSegment,
55 for (
int y = yStart - 1; y <= yStop + 1; y++) {
56 if ((0 <= y) && (y < height)) {
58 ENGAUGE_ASSERT (y < height);
59 if (lastSegment [
unsigned (y)]) {
60 return lastSegment [unsigned (y)];
68 int SegmentFactory::adjacentSegments(SegmentVector &lastSegment,
73 int adjacentSegments = 0;
75 bool inSegment =
false;
76 for (
int y = yStart - 1; y <= yStop + 1; y++) {
77 if ((0 <= y) && (y < height)) {
79 ENGAUGE_ASSERT (y < height);
80 if (!inSegment && lastSegment [
unsigned (y)]) {
84 }
else if (inSegment && !lastSegment [
unsigned (y)]) {
90 return adjacentSegments;
94 QList<Segment*> segments)
96 LOG4CPP_INFO_S ((*mainCat)) <<
"SegmentFactory::fillPoints";
99 QList<Segment*>::iterator itr;
100 for (itr = segments.begin (); itr != segments.end(); itr++) {
103 ENGAUGE_CHECK_PTR(segment);
110 void SegmentFactory::finishRun(
bool *lastBool,
112 SegmentVector &lastSegment,
113 SegmentVector &currSegment,
121 LOG4CPP_DEBUG_S ((*mainCat)) <<
"SegmentFactory::finishRun"
123 <<
" rows=" << yStart <<
"-" << yStop
124 <<
" runsOnLeft=" << adjacentRuns (nextBool, yStart, yStop, height)
125 <<
" runsOnRight=" << adjacentSegments (lastSegment, yStart, yStop, height);
132 if (adjacentRuns(lastBool, yStart, yStop, height) > 1) {
137 if (adjacentRuns(nextBool, yStart, yStop, height) > 1) {
142 if (adjacentSegments(lastSegment, yStart, yStop, height) == 0) {
146 qFloor (0.5 + (yStart + yStop) / 2.0),
148 ENGAUGE_CHECK_PTR (seg);
153 seg = adjacentSegment(lastSegment, yStart, yStop, height);
156 ENGAUGE_CHECK_PTR(seg);
157 seg->
appendColumn(x, qFloor (0.5 + (yStart + yStop) / 2.0), modelSegments);
160 for (
int y = yStart; y <= yStop; y++) {
162 ENGAUGE_ASSERT (y < height);
163 currSegment [unsigned (y)] = seg;
167 void SegmentFactory::loadBool (
const ColorFilter &filter,
172 for (
int y = 0; y < image.height(); y++) {
174 columnBool [y] =
false;
181 void SegmentFactory::loadSegment (SegmentVector &columnSegment,
184 for (
int y = 0; y < height; y++) {
185 columnSegment [unsigned (y)] =
nullptr;
191 QList<Segment*> &segments,
194 LOG4CPP_INFO_S ((*mainCat)) <<
"SegmentFactory::makeSegments";
213 int width = imageFiltered.width();
214 int height = imageFiltered.height();
216 QProgressDialog* dlg =
nullptr;
220 dlg =
new QProgressDialog(
"Scanning segments in image",
"Cancel", 0, width);
221 ENGAUGE_CHECK_PTR (dlg);
225 bool* lastBool =
new bool [unsigned (height)];
226 ENGAUGE_CHECK_PTR(lastBool);
227 bool* currBool =
new bool [unsigned (height)];
228 ENGAUGE_CHECK_PTR(currBool);
229 bool* nextBool =
new bool [unsigned (height)];
230 ENGAUGE_CHECK_PTR(nextBool);
231 SegmentVector lastSegment (static_cast<unsigned long> (height));
232 SegmentVector currSegment (static_cast<unsigned long> (height));
235 loadBool(filter, lastBool, imageFiltered, -1);
236 loadBool(filter, currBool, imageFiltered, 0);
237 loadBool(filter, nextBool, imageFiltered, 1);
238 loadSegment(lastSegment, height);
240 for (
int x = 0; x < width; x++) {
246 qApp->processEvents();
248 if (dlg->wasCanceled()) {
255 matchRunsToSegments(x,
269 scrollBool(lastBool, currBool, height);
270 scrollBool(currBool, nextBool, height);
272 loadBool(filter, nextBool, imageFiltered, x + 1);
274 scrollSegment(lastSegment, currSegment, height);
279 dlg->setValue(width);
283 removeEmptySegments (segments);
285 LOG4CPP_INFO_S ((*mainCat)) <<
"SegmentFactory::makeSegments"
286 <<
" linesCreated=" << madeLines
287 <<
" linesTooShortSoRemoved=" << shortLines
288 <<
" linesFoldedTogether=" << foldedLines;
295 void SegmentFactory::matchRunsToSegments(
int x,
298 SegmentVector &lastSegment,
300 SegmentVector &currSegment,
306 QList<Segment*> &segments)
308 loadSegment(currSegment,
313 for (
int y = 0; y < height; y++) {
315 ENGAUGE_ASSERT (y < height);
316 if (!inRun && currBool [y]) {
321 if ((y + 1 >= height) || !currBool [y + 1]) {
338 removeUnneededLines(lastSegment,
347 void SegmentFactory::removeEmptySegments (QList<Segment*> &segments)
const
349 LOG4CPP_DEBUG_S ((*mainCat)) <<
"SegmentFactory::removeUnneededLines";
351 for (
int i = segments.count(); i > 0;) {
354 Segment *segment = segments.at (i);
362 segments.removeAt (i);
367 void SegmentFactory::removeUnneededLines(SegmentVector &lastSegment,
368 SegmentVector &currSegment,
373 QList<Segment*> &segments)
375 LOG4CPP_DEBUG_S ((*mainCat)) <<
"SegmentFactory::removeUnneededLines";
378 for (
int yLast = 0; yLast < height; yLast++) {
380 ENGAUGE_ASSERT (yLast < height);
381 if (lastSegment [
unsigned (yLast)] && (lastSegment [
unsigned (yLast)] != segLast)) {
383 segLast = lastSegment [unsigned (yLast)];
387 for (
int yCur = 0; yCur < height; yCur++) {
389 ENGAUGE_ASSERT (yCur < height);
390 if (segLast == currSegment [
unsigned (yCur)]) {
398 ENGAUGE_CHECK_PTR(segLast);
406 lastSegment [unsigned (yLast)] =
nullptr;
414 segments.push_back (segLast);
422 void SegmentFactory::scrollBool(
bool *left,
426 for (
int y = 0; y < height; y++) {
427 left [y] = right [y];
431 void SegmentFactory::scrollSegment(SegmentVector &left,
432 SegmentVector &right,
435 for (
int y = 0; y < height; y++) {
436 left [
static_cast<unsigned long> (y)] = right [static_cast<unsigned long> (y)];
442 LOG4CPP_DEBUG_S ((*mainCat)) <<
"SegmentFactory::clearSegments";
444 QList<Segment*>::iterator itr;
445 for (itr = segments.begin(); itr != segments.end(); itr++) {
int lineCount() const
Get method for number of lines.
QList< QPoint > fillPoints(const DocumentModelSegments &modelSegments, QList< Segment * > segments)
Return segment fill points for all segments, for previewing.
void removeUnneededLines(int *foldedLines)
Try to compress a segment that was just completed, by folding together line from point i to point i+1...
SegmentFactory(QGraphicsScene &scene, bool isGnuplot)
Single constructor.
Class for filtering image to remove unimportant information.
void clearSegments(QList< Segment * > &segments)
Remove the segments created by makeSegments.
double pointSeparation() const
Get method for point separation.
void appendColumn(int x, int y, const DocumentModelSegments &modelSegments)
Add some more pixels in a new column to an active segment.
void makeSegments(const QImage &imageFiltered, const DocumentModelSegments &modelSegments, QList< Segment * > &segments, bool useDlg=true)
Main entry point for creating all Segments for the filtered image.
double length() const
Get method for length in pixels.
Selectable piecewise-defined line that follows a filtered line in the image.
QList< QPoint > fillPoints(const DocumentModelSegments &modelSegments)
Create evenly spaced points along the segment.
bool pixelFilteredIsOn(const QImage &image, int x, int y) const
Return true if specified filtered pixel is on.
double minLength() const
Get method for min length.
Model for DlgSettingsSegments and CmdSettingsSegments.