Newer
Older
#include <cstdlib>
#include <ctime>
#include "bsdetectionwidget.h"
using namespace std;
const int BSDetectionWidget::BACK_BLACK = 0;
const int BSDetectionWidget::BACK_WHITE = 1;
const int BSDetectionWidget::BACK_IMAGE = 2;
const int BSDetectionWidget::BACK_GRAD = 3;
const int BSDetectionWidget::BACK_GRADX = 4;
const int BSDetectionWidget::BACK_GRADY = 5;
const int BSDetectionWidget::DEFAULT_PEN_WIDTH = 1;
BSDetectionWidget::BSDetectionWidget (QWidget *parent)
{
Q_UNUSED (parent);
// Initializes the gradient map and the auxiliary views
gMap = NULL;
accuview = NULL;
strucview = NULL;
profileview = NULL;
}
BSDetectionWidget::~BSDetectionWidget ()
{
if (accuview != NULL) delete accuview;
if (strucview != NULL) delete strucview;
}
QSize BSDetectionWidget::openImage (const QString &fileName, int type)
{
QSize newSize (0, 0);
loadedImage.load (fileName);
width = loadedImage.width ();
height = loadedImage.height ();
newSize = loadedImage.size ();
augmentedImage = loadedImage;
if (gMap != NULL) delete gMap;
gMap = new VMap (width, height, getBitmap (augmentedImage), type);
detector.setGradientMap (gMap);
if (idetview != NULL) idetview->setImage (&loadedImage, gMap);
if (strucview != NULL) strucview->setGradientImage (&gradImage);
void BSDetectionWidget::setDefaults ()
{
ifstream input ("gradient.txt", ios::in);
if (input)
{
int gtval = gMap->getGradientThreshold ();
input >> gtval;
if (gtval >= 0 && gtval < 256)
gMap->incGradientThreshold (gtval - gMap->getGradientThreshold ());
}
}
int **BSDetectionWidget::getBitmap (const QImage &image)
{
int w = image.width ();
int h = image.height ();
int **tabImage = new int*[h];
for (int i = 0; i < h; i++)
{
tabImage[i] = new int[w];
for(int j = 0; j < w; j++)
{
QColor c = QColor (image.pixel (j, h - i - 1));
tabImage[i][j] = c.value ();
}
}
return tabImage;
}
void BSDetectionWidget::toggleBackground ()
{
if (background++ == BACK_GRADY) background = BACK_BLACK;
if (background >= BACK_GRAD) buildGradientImage (background - BACK_GRAD);
}
bool BSDetectionWidget::saveAugmentedImage (const QString &fileName,
const char *fileFormat)
{
QImage aImage = augmentedImage;
return (aImage.save (fileName, fileFormat));
}
void BSDetectionWidget::clearImage ()
{
augmentedImage.fill (qRgb (255, 255, 255));
update ();
}
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
void BSDetectionWidget::buildGradientImage (int dir)
{
int w = gMap->getWidth ();
int h = gMap->getHeight ();
double gn[w * h];
for (int j = 0; j < h; j++)
for (int i = 0; i < w; i++)
{
if (dir == 2)
gn[j * w + i] = gMap->getValue(i,j).y ();
else if (dir == 1)
gn[j * w + i] = gMap->getValue(i,j).x ();
else
gn[j * w + i] = gMap->magn (i, j);
}
double min = gn[0];
double max = gn[0];
for (int i = 1; i < w * h; i++)
{
if (max < gn[i]) max = gn[i];
if (min > gn[i]) min = gn[i];
}
gradImage = QImage (w, h, QImage::Format_RGB32);
for (int j = 0; j < h; j++)
for (int i = 0; i < w; i++)
{
int val = (int) ((gn[(h - 1 - j) * w + i] - min) * 255 / (max - min));
gradImage.setPixel (i, j, val + val * 256 + val * 256 * 256);
}
// gradImage.save ("hgradient.png");
}
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
void BSDetectionWidget::paintEvent (QPaintEvent *)
{
QPainter painter (this);
painter.drawImage (QPoint (0, 0), augmentedImage);
}
void BSDetectionWidget::closeAccuAnalyzer ()
{
if (accuview != NULL)
{
accuview->close ();
delete accuview;
accuview = NULL;
}
}
void BSDetectionWidget::closePixelAnalyzer ()
{
if (strucview != NULL)
{
strucview->close ();
delete strucview;
strucview = NULL;
}
}
void BSDetectionWidget::closeProfileAnalyzer ()
{
if (profileview != NULL)
{
profileview->close ();
delete profileview;
profileview = NULL;
}
}
void BSDetectionWidget::closeIdetAnalyzer ()
{
if (idetview != NULL)
{
idetview->close ();
delete idetview;
idetview = NULL;
}
}
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
void BSDetectionWidget::switchAccuAnalyzer ()
{
if (accuview != NULL)
{
accuview->close ();
delete accuview;
accuview = NULL;
}
else
{
accuview = new BSAccumulatorView (&detector);
accuview->show ();
}
}
void BSDetectionWidget::switchPixelAnalyzer ()
{
if (strucview != NULL)
{
strucview->close ();
delete strucview;
strucview = NULL;
}
else
{
strucview = new BSStructureView (&loadedImage, &detector);
strucview->show ();
}
}
void BSDetectionWidget::switchProfileAnalyzer ()
{
if (profileview != NULL)
{
profileview->close ();
delete profileview;
profileview = NULL;
}
else
{
profileview = new BSProfileView ();
profileview->setImage (&loadedImage, gMap);
if (! p1.equals (p2)) profileview->buildScans (p1, p2);
profileview->show ();
}
}
void BSDetectionWidget::switchIdetAnalyzer ()
{
if (idetview != NULL)
{
idetview->close ();
delete idetview;
idetview = NULL;
}
else
{
idetview = new BSIdetView (&detector);
idetview->setImage (&loadedImage, gMap);
p1 = Pt2i (event->pos().x (), height - 1 - event->pos().y());
if (p1.manhattan (p2) < 10) p1.set (oldp1);
else if (p1.manhattan (oldp1) < 10) p1.set (p2);
}
void BSDetectionWidget::mouseReleaseEvent (QMouseEvent *event)
{
p2 = Pt2i (event->pos().x (), height - 1 - event->pos().y());
if (p1.equals (p2))
{
p1.set (oldp1);
p2.set (oldp2);
}
else
{
alternate = 0;
cerr << "p1 defined: " << p1.x () << " " << p1.y () << endl;
cerr << "p2 defined: " << p2.x () << " " << p2.y () << endl;
nbdettrials = detector.countOfTrials ();
nbmaxdettrials = 0;
if (detector.isMultiSelection ())
cout << detector.getBlurredSegments().size ()
<< " blurred segments detected on "
<< nbdettrials << " essais " << endl;
}
void BSDetectionWidget::mouseMoveEvent (QMouseEvent *event)
{
p2 = Pt2i (event->pos().x (), height - 1 - event->pos().y ());
if (verbose) cerr << "(" << p1.x () << ", " << p1.y () << ") ("
<< p2.x () << ", " << p2.y () << ")" << endl;
if (p1.manhattan (p2) > 5
&& (width > p2.x() && height > p2.y()
&& p2.x() > 0 && p2.y() > 0))
{
}
}
void BSDetectionWidget::keyPressEvent (QKeyEvent *event)
{
if (isActiveWindow ()) switch (event->key ())
{
case Qt::Key_A :
// Registers the last extracted blurred segment
saveExtractedSegment ();
case Qt::Key_B :
if (event->modifiers () & Qt::ControlModifier)
// Toggles background image
toggleBackground ();
if (p1.equals (p2)) displayBackground ();
else
{
// Tunes the gradient resolution for gradient local max filtering
detector.incGradientResolution (
(event->modifiers () & Qt::ShiftModifier ? -1 : 1));
cout << "Gradient resolution = "
<< detector.getGradientResolution () << endl;
extract ();
}
break;
case Qt::Key_C :
// Clears the registered blurred segments
clearSavedSegments ();
break;
case Qt::Key_D :
if (event->modifiers () & Qt::ControlModifier)
// Switches density test at initial step
detector.switchDensityTest ();
extract ();
cout << "Density test : "
<< (detector.isDensityTestOn () ? "on" : "off") << endl;
case Qt::Key_E :
// Handles directed edge or stroke detection
if (event->modifiers () & Qt::ControlModifier)
detector.switchEdgeDirectionConstraint ();
else detector.invertEdgeDirection ();
switch (detector.edgeDirectionConstraint ())
case 0 :
cout << "Stroke detection" << endl;
break;
case 1 :
cout << "Edge detection" << endl;
break;
case -1 :
cout << "Opposite edge detection" << endl;
break;
extract ();
break;
case Qt::Key_F :
if (event->modifiers () & Qt::ControlModifier)
// Switches initial detection filtering
detector.switchFiltering (BSDetector::STEP_INITIAL);
cout << "Pre-filtering "
<< (detector.isFiltering (BSDetector::STEP_INITIAL) ? "on" : "off")
<< endl;
extract ();
if (event->modifiers () & Qt::ControlModifier)
{
// Switches length test at final step
detector.switchFinalLengthTest ();
extract ();
cout << "Final length test : "
<< (detector.isFinalLengthTestOn () ? "on" : "off") << endl;
}
else
{
// Tunes the gradient threshold for maximal value detection
detector.incGradientThreshold (
(event->modifiers () & Qt::ShiftModifier ? -1 : 1));
cout << "Gradient threshold = "
<< detector.getGradientThreshold () << endl;
extract ();
}
break;
case Qt::Key_H :
if (event->modifiers () & Qt::ControlModifier)
// Switches final detection filtering
detector.switchFiltering (BSDetector::STEP_FINAL);
cout << "Final filtering "
<< (detector.isFiltering (BSDetector::STEP_FINAL) ? "on" : "off")
<< endl;
extract ();
case Qt::Key_J :
if (event->modifiers () & Qt::ControlModifier)
{
// Switches the proximity constraint for fast tracks
detector.switchFastTrackProximityConstraint ();
cout << "Proximity constraint on fast tracks "
<< (detector.fastTrackProximityConstraintOn () ? "on" : "off")
else if (detector.fastTrackProximityConstraintOn ())
// Tunes the proximity threshold for fast tracks
detector.incFastTrackProximityThreshold (
cout << "Proximity threshold for fast tracks = "
<< detector.getFastTrackProximityThreshold () << endl;
case Qt::Key_K :
if (event->modifiers () & Qt::ControlModifier)
{
// Switches the final step connectivity constraint
detector.switchConnectivityConstraint ();
cout << "Connectivity constraint "
<< (detector.isConnectivityConstraintOn () ? "on" : "off")
else
{
// Tunes the minimal size of connected components
detector.incConnectedComponentMinSize (
(event->modifiers () & Qt::ShiftModifier) == 0);
cout << "Connected components min size = "
<< detector.getConnectedComponentMinSize () << endl;
extract ();
}
if (event->modifiers () & Qt::ControlModifier)
{
// Switches density test at final step
detector.switchFinalDensityTest ();
extract ();
cout << "Final density test : "
<< (detector.isFinalDensityTestOn () ? "on" : "off") << endl;
}
else
{
// Tunes the output blurred segment minimal size
detector.setBSminSize (detector.getBSminSize () +
(event->modifiers () & Qt::ShiftModifier ? -1 : 1));
cout << "Output BS min size = " << detector.getBSminSize () << endl;
extract ();
}
// Switches the multi-detection
detector.switchMultiSelection ();
cout << "Multi-selection "
<< (detector.isMultiSelection () ? "on" : "off") << endl;
nbdettrials = detector.countOfTrials ();
nbmaxdettrials = 0;
// cout << detector.getBlurredSegments().size ()
// << " blurred segments detected on "
// << nbdettrials << " essais " << endl;
// Switches the initial detection extension limitation
detector.switchInitialBounding ();
cout << "Initial step max extension = "
<< detector.initialDetectionMaxExtent () << endl;
// Highlights the next segment in a multi-detection
if (! detector.getBlurredSegments().empty ())
{
nbmaxdettrials += (event->modifiers () & Qt::ShiftModifier ? -1 : 1);
if (nbmaxdettrials < 0) nbmaxdettrials = nbdettrials;
else if (nbmaxdettrials > nbdettrials) nbmaxdettrials = 0;
detector.setMaxTrials (nbmaxdettrials);
cout << "Selection du segment " << nbmaxdettrials << endl;
extract ();
}
}
break;
case Qt::Key_O :
if (event->modifiers () & Qt::ControlModifier)
{
// Switches the scan directionality
detector.switchOrthoScans ();
cout << (detector.orthoScansOn () ?
"Orthographic scans" : "Directional scans") << endl;
}
else
{
// Outputs the detected segment
writeDetectionResult ();
cout << "Detection result output" << endl;
case Qt::Key_P :
if (event->modifiers () & Qt::ControlModifier)
{
// Switches the preliminary detection
detector.switchPreliminary ();
cout << "Preliminary detection "
<< (detector.isPreliminary () ? "on" : "off") << endl;
extract ();
}
else
{
// Captures main window
augmentedImage.save ("capture.png");
cout << "Main window shot in capture.png" << endl;
}
case Qt::Key_Q :
if (event->modifiers () & Qt::ControlModifier)
{
// Switches the scan flexibility
detector.switchDynamicScans ();
cout << (detector.dynamicScansOn () ?
"Dynamic scans" : "Static scans") << endl;
extract ();
}
else
{
// Displays registered blurred segments
displaySavedSegments ();
}
// Toggles the occupancy mask dilation type
gMap->toggleMaskDilation ();
cout << "Occupancy mask dilation size : "
<< gMap->getMaskDilation () << endl;
}
else
{
// Tunes the automatic detection grid resolution
detector.setAutoGridResolution (detector.getAutoGridResolution () +
(event->modifiers () & Qt::ShiftModifier ? -1 : 1));
cout << "Auto grid resolution = "
<< detector.getAutoGridResolution () << " pixels" << endl;
}
if (event->modifiers () & Qt::ControlModifier)
{
// Switches the interruption handling
detector.switchAutoRestart ();
extract ();
cout << "Segment continuation after = "
<< detector.getRestartOnLack () << " pixels" << endl;
// Tunes the pixel lack tolerence value
detector.setPixelLackTolerence (detector.getPixelLackTolerence () +
(event->modifiers () & Qt::ShiftModifier ? -1 : 1));
cout << "Lack tolerence = " << detector.getPixelLackTolerence ()
<< " pixels" << endl;
case Qt::Key_T :
if (event->modifiers () & Qt::ControlModifier)
{
// Switches the progressive thinning
detector.toggleThinning ();
if (detector.isThinningOn () && detector.isThickenningOn ())
<< (detector.isThinningOn () ? "on" : "off") << endl;
{
// Switches the display of the detected blurred segment bounds
bsBoundsVisible = ! bsBoundsVisible;
cout << "Segments bounds "
<< (bsBoundsVisible ? "visible" : "hidden") << endl;
}
else
{
// Replays last extraction
cerr << "p1 update: " << p1.x () << " " << p1.y () << endl;
cerr << "p2 update: " << p2.x () << " " << p2.y () << endl;
extract ();
}
break;
case Qt::Key_V :
if (event->modifiers () & Qt::ControlModifier)
// Switches the detection result edition
switchVerbose ();
// Switches the scan centering on the detected segment
detector.switchScanRecentering ();
cout << "Fine tracking centered on " << (detector.isScanRecentering () ?
"detected segment" : "initial scan") << endl;
// Tunes the assigned max width margin for fine tracks
detector.setFastTracksMaxMargin (detector.fastTracksMaxMargin () +
(event->modifiers () & Qt::ShiftModifier ? -1 : 1));
extract ();
cout << "Fast tracks max width margin = "
<< detector.fastTracksMaxMargin () << endl;
case Qt::Key_X :
if (event->modifiers () & Qt::ControlModifier)
// Switches the setting of the assigned width on the detected segment
detector.switchScanFitting ();
cout << "Fine tracking fitted to " << (detector.isScanFitting () ?
"detected segment width" : "assigned width") << endl;
extract ();
}
else
{
// Tunes the assigned max width for fast tracks
detector.setFineTracksMaxWidth (detector.fineTracksMaxWidth () +
(event->modifiers () & Qt::ShiftModifier ? -1 : 1));
extract ();
cout << "Fine tracks max width = "
<< detector.fineTracksMaxWidth () << endl;
case Qt::Key_Y :
if (event->modifiers () & Qt::ControlModifier)
{
// Switches the display of the detected blurred segment pixels
bsPointsVisible = ! bsPointsVisible;
cout << "Segments points "
<< (bsPointsVisible ? "visible" : "hidden") << endl;
else
{
// Tunes the background image black level
incBlackLevel ((event->modifiers () & Qt::ShiftModifier) ? -1 : 1);
displayDetectionResult ();
cout << "Background black level = " << getBlackLevel () << endl;
}
case Qt::Key_Z :
if (event->modifiers () & Qt::ControlModifier)
{
// Switches the thickenning control
detector.toggleThickenning ();
if (detector.isThickenningOn () && detector.isThinningOn ())
detector.toggleThinning ();
extract ();
cout << "Thickenning "
<< (detector.isThickenningOn () ? "on" : "off") << endl;
}
else
{
// Tunes the thickenning limit
detector.incThickenningLimit (
extract ();
cout << "Thickenning limit = " << detector.getThickenningLimit ()
<< " pixels" << endl;
}
break;
case Qt::Key_1 :
switchPixelAnalyzer ();
break;
case Qt::Key_2 :
switchAccuAnalyzer ();
break;
case Qt::Key_3 :
switchProfileAnalyzer ();
break;
case Qt::Key_4 :
switchIdetAnalyzer ();
break;
case Qt::Key_5 :
// Switches the crosswise segment detection
detector.switchTrackCrosswise ();
extract ();
cout << "Crosswise segment detection "
<< (detector.trackCrosswiseOn () ? "on" : "off") << endl;
break;
case Qt::Key_6 :
detector.switchDetector ();
cout << (detector.oldDetectorOn () ?
"Old detector set" : "Present detector set") << endl;
extract ();
break;
case Qt::Key_8 :
alternateTest ();
break;
case Qt::Key_9 :
performanceTest ();
break;
case Qt::Key_0 :
localTest ();
break;
}
else if (strucview != NULL && strucview->isActiveWindow ())
{
}
else if (accuview != NULL && accuview->isActiveWindow ())
{
}
else if (profileview != NULL && profileview->isActiveWindow ())
{
else if (idetview != NULL && idetview->isActiveWindow ())
{
if (idetview->processKeyEvent (event)) extract ();
}
void BSDetectionWidget::drawPoints (QPainter &painter,
vector<Pt2i> pts, QColor color)
vector<Pt2i>::iterator iter = pts.begin ();
while (iter != pts.end ())
painter.setPen (QPen (color, DEFAULT_PEN_WIDTH, Qt::SolidLine,
Qt::RoundCap, Qt::RoundJoin));
if (p.x() < width && p.y() < height && p.x() >= 0 && p.y() >= 0)
painter.drawPoint (QPoint (p.x(), height - 1 - p.y())); // dec 1
void BSDetectionWidget::drawPixels (QPainter &painter, vector<Pt2i> pix)
vector<Pt2i>::iterator iter = pix.begin ();
while (iter != pix.end ())
painter.setPen (QPen (QBrush (loadedImage.pixel (p.x (),
loadedImage.height () - 1 - p.y ())),
DEFAULT_PEN_WIDTH, Qt::SolidLine,
Qt::RoundCap, Qt::RoundJoin));
if (p.x() < width && p.y() < height && p.x() >= 0 && p.y() >= 0)
painter.drawPoint (QPoint (p.x(), height - 1 - p.y())); // dec 1
void BSDetectionWidget::drawLine (QPainter &painter,
const Pt2i from, const Pt2i to, QColor color)
{
int n;
Pt2i *pts = from.drawing (to, &n);
painter.setPen (QPen (color, DEFAULT_PEN_WIDTH, Qt::SolidLine,
Qt::RoundCap, Qt::RoundJoin));
for (int i = 0; i < n; i++)
painter.drawPoint (QPoint (pts[i].x (),
height - 1 - pts[i].y ())); // dec 1
delete [] pts;
}
void BSDetectionWidget::drawSelection (QPainter &painter,
const Pt2i from, const Pt2i to)
drawLine (painter, from, to, selectionColor);
}
void BSDetectionWidget::drawBlurredSegment (QPainter &painter,
BlurredSegment *bs, bool high)
{
if (bs != NULL)
if (bsBoundsVisible)
{
vector<Pt2i> bnd;
DigitalStraightSegment *dss = bs->getSegment ();
if (dss != NULL)
{
dss->getBounds (bnd, 0, 0, width, height);
drawPoints (painter, bnd, high ? boundHighColor : boundColor);
}
}
if (bsPointsVisible)
drawPoints (painter, bs->getAllPoints (), high ? bsHighColor : bsColor);
void BSDetectionWidget::incBlackLevel (int val)
{
blevel += val * 5;
if (blevel < 0) blevel = 0;
if (blevel > 200) blevel = 200;
}
void BSDetectionWidget::lighten (QImage &im)
{
if (blevel != 0 && background != BACK_BLACK && background != BACK_WHITE)
{
for (int i = 0; i < im.height (); i++)
for(int j = 0; j < im.width (); j++)
{
int col = blevel + (QColor (im.pixel(j,i)).value ()
* (255 - blevel)) / 255;
im.setPixel (j, i, col + col * 256 + col * 256 * 256);
}
}
}
if (background == BACK_BLACK) augmentedImage.fill (qRgb (0, 0, 0));
else if (background == BACK_WHITE) augmentedImage.fill (qRgb (255, 255, 255));
else if (background == BACK_IMAGE) augmentedImage = loadedImage;
else augmentedImage = gradImage;
QPainter painter (&augmentedImage);
update (QRect (QPoint (0, 0), QPoint (width, height)));
void BSDetectionWidget::writeDetectionResult ()
{
if (bs != NULL)
{
ofstream outf ("seg.txt", ios::out);
outf << "(" << bs->antipodalEdgeStart().x ()
<< ", " << bs->antipodalEdgeStart().y ()
<< ") (" << bs->antipodalEdgeEnd().x ()
<< ", " << bs->antipodalEdgeEnd().y ()
<< ") (" << bs->antipodalVertex().x ()
<< ", " << bs->antipodalVertex().y ()
<< ") (" << bs->getLastLeft().x ()
<< ", " << bs->getLastLeft().y ()
<< ") (" << bs->getLastRight().x ()
<< ", " << bs->getLastRight().y ()
<< ")" << endl;
outf.close ();
}
}
void BSDetectionWidget::displayDetectionResult ()
if (background == BACK_BLACK) augmentedImage.fill (qRgb (0, 0, 0));
else if (background == BACK_WHITE) augmentedImage.fill (qRgb (255, 255, 255));
else if (background == BACK_IMAGE) augmentedImage = loadedImage;
else augmentedImage = gradImage;
vector<BlurredSegment *> bss = detector.getBlurredSegments ();
// cout << bss.size () << " blurred segments detected" << endl;
// double bsw = 0.;
// int bsc = 0;
vector<BlurredSegment *>::const_iterator it = bss.begin ();
while (it != bss.end ())
// if ((*it) != NULL)
// {
// DigitalStraightSegment *dss = (*it)->getSegment ();
// bsc++;
// if (dss == NULL) cout << "DSS null" << endl;
// else bsw += dss->width () / (double) dss->period ();
// }
drawBlurredSegment (painter, *it, nbmaxdettrials == 0 ||
(*it == bss.back () && detector.isLastTrialOk ()));
it++;
}
// cout << bsc << " effective blurred segments" << endl;
// if (bsc != 0) cout << "Mean width is " << bsw / bsc << endl;
drawBlurredSegment (painter, detector.getBlurredSegment ());