Newer
Older
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
bsColor = Qt::blue;
bsHighColor = Qt::yellow;
boundColor = Qt::green;
boundHighColor = Qt::magenta;
maxWidth = 768;
maxHeight = 512;
xMaxShift = 0;
yMaxShift = 0;
xShift = 0;
yShift = 0;
zoom = 1;
if (profileview != NULL) delete profileview;
if (idetview != NULL) delete idetview;
if (cannyview != NULL) delete cannyview;
if (yorkview != NULL) delete yorkview;
}
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);
xMaxShift = (width > maxWidth ? maxWidth - width : 0);
yMaxShift = (height > maxHeight ? maxHeight - height : 0);
xShift = xMaxShift / 2;
if (xShift > 0) xShift = 0;
yShift = yMaxShift / 2;
if (yShift > 0) yShift = 0;
return newSize.boundedTo (QSize (maxWidth, maxHeight));
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 ();
}
void BSDetectionWidget::buildGradientImage (int dir)
{
int w = gMap->getWidth ();
int h = gMap->getHeight ();
double *gn = new double[w * h];
// double gn[w * h];
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
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");
}
void BSDetectionWidget::paintEvent (QPaintEvent *)
{
QPainter painter (this);
QImage zoomImage = augmentedImage.scaled (width / zoom, height / zoom);
painter.drawImage (QPoint (xShift, yShift), zoomImage);
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;
}
}
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);
void BSDetectionWidget::switchHighlightColors ()
{
darkHighlightOn = ! darkHighlightOn;
if (darkHighlightOn)
{
bsHighColor = Qt::black;
boundHighColor = Qt::blue;
}
else
{
bsHighColor = Qt::yellow;
boundHighColor = Qt::magenta;
}
}
void BSDetectionWidget::switchArlequin ()
{
arlequinOn = ! arlequinOn;
}
int ex = zoom * (event->pos().x () - xShift);
int ey = zoom * (event->pos().y () - yShift);
p1 = Pt2i (ex, height - 1 - ey);
if (p1.manhattan (p2) < 10) p1.set (oldp1);
else if (p1.manhattan (oldp1) < 10) p1.set (p2);
}
void BSDetectionWidget::mouseReleaseEvent (QMouseEvent *event)
{
int ex = zoom * (event->pos().x () - xShift);
int ey = zoom * (event->pos().y () - yShift);
p2 = Pt2i (ex, height - 1 - ey);
if (p1.equals (p2))
{
p1.set (oldp1);
p2.set (oldp2);
}
else
{
cerr << "p1 defined: " << p1.x () << " " << p1.y () << endl;
cerr << "p2 defined: " << p2.x () << " " << p2.y () << endl;
}
void BSDetectionWidget::mouseMoveEvent (QMouseEvent *event)
{
int ex = zoom * (event->pos().x () - xShift);
int ey = zoom * (event->pos().y () - yShift);
p2 = Pt2i (ex, height - 1 - ey);
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)
{
case Qt::Key_A :
// Registers the last extracted blurred segment
count = saveExtractedSegment ();
cout << count << " new segment(s) -> "
<< extractedSegments.size () << " segments registered" << endl;
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 ();
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 ())
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 ();
cout << "Final length test : "
<< (detector.isFinalLengthTestOn () ? "on" : "off") << endl;
}
else
{
// Tunes the gradient threshold for maximal value detection
(event->modifiers () & Qt::ShiftModifier ? -1 : 1));
cout << "Sensitivity = " << detector.getSensitivity () << endl;
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 ();
<< (detector.isConnectivityConstraintOn () ? "on" : "off")
else
{
// Tunes the minimal size of connected components
detector.incConnectedComponentMinSize (
(event->modifiers () & Qt::ShiftModifier) == 0);
<< detector.getConnectedComponentMinSize () << endl;
extract ();
}
if (event->modifiers () & Qt::ControlModifier)
{
// Switches density test at final step
detector.switchFinalDensityTest ();
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 << "Detected blurred segments min size = "
<< detector.getBSminSize () << endl;
// Switches the multi-detection
detector.switchMultiSelection ();
cout << "Multi-selection "
<< (detector.isMultiSelection () ? "on" : "off") << endl;
// Switches the initial detection extension limitation
detector.switchInitialBounding ();
cout << "Initial step max extension = "
<< detector.initialDetectionMaxExtent () << endl;
vector<BlurredSegment *> bsl = detector.getBlurredSegments ();
if (! bsl.empty ())
detector.incMaxDetections (event->modifiers () & Qt::ShiftModifier);
cout << "Selection of segment "
<< detector.getMaxDetections () << endl;
}
}
break;
case Qt::Key_O :
if (event->modifiers () & Qt::ControlModifier)
{
// Switches the scan directionality
detector.switchOrthoScans ();
cout << (detector.orthoScansOn () ?
"Orthographic scans" : "Directional scans") << endl;
case Qt::Key_P :
if (event->modifiers () & Qt::ControlModifier)
{
<< (detector.isPreliminary () ? "on" : "off") << endl;
extract ();
}
else
{
// Captures main window
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
// 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));
<< detector.getAutoGridResolution () << " pixels" << endl;
}
if (event->modifiers () & Qt::ControlModifier)
{
// Switches the interruption handling
detector.switchAutoRestart ();
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 << "Tolerence to detection lacks = "
<< 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;
}
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 () +
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));
case Qt::Key_Y :
if (event->modifiers () & Qt::ControlModifier)
{
// Switches the display of the detected blurred segment pixels
bsPointsVisible = ! bsPointsVisible;
else
{
// Tunes the background image black level
incBlackLevel ((event->modifiers () & Qt::ShiftModifier) ? -1 : 1);
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 ())
}
else
{
// Tunes the thickenning limit
detector.incThickenningLimit (
cout << "Thickenning limit = " << detector.getThickenningLimit ()
<< " pixels" << endl;
case Qt::Key_Exclam :
switchHighlightColors ();
cout << "Highlight colors "
<< (isHighlightColorsOn () ? "on" : "off") << endl;
displayDetectionResult ();
break;
case Qt::Key_Equal :
switchArlequin ();
cout << "Random coloring " << (isArlequinOn () ? "on" : "off") << endl;
cout << "Stats display " << (isStatsOn () ? "on" : "off") << endl;
cout << "Selection stroke saved" << endl;
break;
case Qt::Key_Percent :
if (cannyview == NULL)
cannyview = new BSCannyView (&loadedImage, &detector);
cannyview->show ();
break;
case Qt::Key_Semicolon :
if (yorkview == NULL)
yorkview = new BSYorkView (&loadedImage, &detector);
yorkview->show ();
case Qt::Key_Plus :
if (zoom > 1)
{
zoom /= 2;
xShift = xShift * 2 - maxWidth / 2;
yShift = yShift * 2 - maxHeight / 2;
displayDetectionResult ();
}
break;
case Qt::Key_Minus :
if (width / zoom > maxWidth || height / zoom > maxHeight)
{
zoom *= 2;
xShift = xShift / 2 + maxWidth / 4;
if (xShift > 0) xShift = 0;
if ((maxWidth - xShift) * zoom > width)
xShift = maxWidth - width / zoom;
yShift = yShift / 2 + maxHeight / 4;
if (yShift > 0) yShift = 0;
if ((maxHeight - yShift) * zoom > height)
yShift = maxHeight - height / zoom;
displayDetectionResult ();
}
break;
case Qt::Key_Left :
xShift += 50;
if (xShift > 0) xShift = 0;
displayDetectionResult ();
break;
case Qt::Key_Right :
xShift -= 50;
if ((maxWidth - xShift) * zoom > width)
xShift = maxWidth - width / zoom;
displayDetectionResult ();
break;
case Qt::Key_Up :
yShift += 50;
if (yShift > 0) yShift = 0;
displayDetectionResult ();
break;
case Qt::Key_Down :
yShift -= 50;
if ((maxHeight - yShift) * zoom > height)
yShift = maxHeight - height / zoom;
case Qt::Key_1 :
switchPixelAnalyzer ();
break;
case Qt::Key_2 :
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 () ?
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 (profileview != NULL && profileview->isActiveWindow ())
{
else if (idetview != NULL && idetview->isActiveWindow ())
{
if (idetview->processKeyEvent (event)) extract ();
}
else if (yorkview != NULL && yorkview->isActiveWindow ())
{
if (yorkview->processKeyEvent (event)) extract ();
}
else if (cannyview != NULL && cannyview->isActiveWindow ())
{
if (cannyview->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