From 0d18691fb0c9b559857a2920a59a4be0a88ff6c4 Mon Sep 17 00:00:00 2001 From: even <philippe.even@loria.fr> Date: Mon, 6 May 2019 17:36:34 +0200 Subject: [PATCH] Double edge detection modes --- Code/FBSD/BSTools/bsdetectionwidget.cpp | 65 +++++++++++++++++-------- Code/FBSD/BSTools/bsrandomtester.cpp | 6 ++- Code/FBSD/BlurredSegment/bsdetector.cpp | 33 ++++++++++--- Code/FBSD/BlurredSegment/bsdetector.h | 55 ++++++++++++++------- Methode/ctrl.tex | 5 +- 5 files changed, 116 insertions(+), 48 deletions(-) diff --git a/Code/FBSD/BSTools/bsdetectionwidget.cpp b/Code/FBSD/BSTools/bsdetectionwidget.cpp index e50ef5c..979fe68 100755 --- a/Code/FBSD/BSTools/bsdetectionwidget.cpp +++ b/Code/FBSD/BSTools/bsdetectionwidget.cpp @@ -481,9 +481,9 @@ void BSDetectionWidget::keyPressEvent (QKeyEvent *event) case Qt::Key_D : if (event->modifiers () & Qt::ControlModifier) { - // Switches density test at initial step + // Switches sparsity test at initial step detector.switchInitialSparsityTest (); - cout << "Initial density test : " + cout << "Initial sparsity test : " << (detector.isInitialSparsityTestOn () ? "on" : "off") << endl; extract (); } @@ -491,23 +491,30 @@ void BSDetectionWidget::keyPressEvent (QKeyEvent *event) // DEV OUT 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 << "Line detection mode set" << endl; - break; - case 1 : - cout << "Main edge detection mode set" << endl; - break; - case -1 : - cout << "Opposite edge detection mode set" << endl; - break; + // Handles single or double edge detection + if (event->modifiers () & Qt::ControlModifier) + { + detector.switchSingleOrDoubleEdge (); + if (detector.isSingleEdgeModeOn ()) + cout << "Single edge detection set (" + << (detector.isOppositeGradientOn () ? + "opposite" : "main") << ")" << endl; + else cout << "Double edge detection set" << endl; + extract (); + } + // Handles gradient orientation direction for the detection + else + { + if (detector.switchOppositeGradient ()) + { + cout << "Single edge detection set (" + << (detector.isOppositeGradientOn () ? + "opposite" : "main") << ")" << endl; + extract (); + } + } } - extract (); break; case Qt::Key_F : @@ -542,6 +549,7 @@ void BSDetectionWidget::keyPressEvent (QKeyEvent *event) } break; +// DEV IN case Qt::Key_J : if (event->modifiers () & Qt::ControlModifier) { @@ -562,6 +570,7 @@ void BSDetectionWidget::keyPressEvent (QKeyEvent *event) extract (); } break; +// DEV OUT case Qt::Key_K : if (event->modifiers () & Qt::ControlModifier) @@ -646,6 +655,7 @@ void BSDetectionWidget::keyPressEvent (QKeyEvent *event) break; case Qt::Key_O : +// DEV IN if (event->modifiers () & Qt::ControlModifier) { // Switches the scan directionality @@ -655,6 +665,7 @@ void BSDetectionWidget::keyPressEvent (QKeyEvent *event) extract (); } else +// DEV OUT { // Outputs the detected segment cout << "Outputs detection result" << endl; @@ -663,15 +674,17 @@ void BSDetectionWidget::keyPressEvent (QKeyEvent *event) break; case Qt::Key_P : +// DEV IN if (event->modifiers () & Qt::ControlModifier) { - // Switchues the preliminary detection + // Switches the preliminary detection detector.switchPreliminary (); cout << "Initial detection duplication " << (detector.isPreliminary () ? "on" : "off") << endl; extract (); } else +// DEV OUT { // Captures main window cout << "Saves main window in capture.png" << endl; @@ -697,6 +710,7 @@ void BSDetectionWidget::keyPressEvent (QKeyEvent *event) break; case Qt::Key_R : +// DEV IN if (event->modifiers () & Qt::ControlModifier) { // Toggles the occupancy mask dilation type @@ -706,6 +720,7 @@ void BSDetectionWidget::keyPressEvent (QKeyEvent *event) extract (); } else +// DEV OUT { // Tunes the sweeping step value for automatic detections detector.setAutoSweepingStep (detector.getAutoSweepingStep () + @@ -779,6 +794,7 @@ void BSDetectionWidget::keyPressEvent (QKeyEvent *event) switchVerbose (); break; +// DEV IN case Qt::Key_W : if (event->modifiers () & Qt::ControlModifier) { @@ -789,6 +805,7 @@ void BSDetectionWidget::keyPressEvent (QKeyEvent *event) extract (); } break; +// DEV OUT case Qt::Key_X : if (event->modifiers () & Qt::ControlModifier) @@ -880,6 +897,14 @@ void BSDetectionWidget::keyPressEvent (QKeyEvent *event) gtview = new BSGroundtruthView (&loadedImage, &detector); gtview->show (); break; + + case Qt::Key_Question : + detector.switchSingleOrDoubleMultiDetection (); + cout << "Multi-detection of " + << (detector.isSingleMultiOn () ? "single edges" : "double edges") + << endl; + extract (); + break; // DEV OUT case Qt::Key_Plus : @@ -956,7 +981,6 @@ void BSDetectionWidget::keyPressEvent (QKeyEvent *event) case Qt::Key_4 : switchIdetAnalyzer (); break; -// DEV OUT case Qt::Key_5 : // Switches the crosswise segment detection @@ -965,11 +989,13 @@ void BSDetectionWidget::keyPressEvent (QKeyEvent *event) cout << "Crosswise segment detection " << (detector.trackCrosswiseOn () ? "on" : "off") << endl; break; +// DEV OUT case Qt::Key_7 : storeUserInput (); break; +// DEV IN case Qt::Key_8 : alternateTest (); break; @@ -977,6 +1003,7 @@ void BSDetectionWidget::keyPressEvent (QKeyEvent *event) case Qt::Key_9 : performanceTest (); break; +// DEV OUT case Qt::Key_0 : localTest (); diff --git a/Code/FBSD/BSTools/bsrandomtester.cpp b/Code/FBSD/BSTools/bsrandomtester.cpp index 91df0c5..b11ac91 100755 --- a/Code/FBSD/BSTools/bsrandomtester.cpp +++ b/Code/FBSD/BSTools/bsrandomtester.cpp @@ -139,10 +139,12 @@ void BSRandomTester::randomTest () if (gMap != NULL) delete gMap; gMap = new VMap (width, height, getBitmap (image), VMap::TYPE_SOBEL_5X5); gMap->incGradientThreshold (50 - gMap->getGradientThreshold ()); - if (gMap->isOrientationConstraintOn ()) - gMap->switchOrientationConstraint (); for (int det = 0; det < nbdets; det ++) + { detectors[det].setGradientMap (gMap); + if (detectors[det].isSingleEdgeModeOn ()) + detectors[det].switchSingleOrDoubleEdge (); + } for (int det = 0; det < nbdets; det ++) { diff --git a/Code/FBSD/BlurredSegment/bsdetector.cpp b/Code/FBSD/BlurredSegment/bsdetector.cpp index bcb64bb..0872508 100755 --- a/Code/FBSD/BlurredSegment/bsdetector.cpp +++ b/Code/FBSD/BlurredSegment/bsdetector.cpp @@ -42,6 +42,7 @@ BSDetector::BSDetector () inThick = DEFAULT_ASSIGNED_THICKNESS; prelimDetectionOn = false; staticDetOn = false; + singleMultiOn = true; bst0 = (prelimDetectionOn ? new BSTracker () : NULL); bst1 = new BSTracker (); @@ -63,7 +64,7 @@ BSDetector::BSDetector () //lsf2 = (filteringOn ? new LineSpaceFilter () : NULL); lsf2 = (filteringOn ? new BSFilter () : NULL); - edgeDirection = 0; // detects strokes (not only edges) + oppositeGradientDir = false; // main edge detection initialMinSize = DEFAULT_INITIAL_MIN_SIZE; finalFragmentationTestOn = false; fragmentMinSize = DEFAULT_FRAGMENT_MIN_SIZE; @@ -236,9 +237,11 @@ bool BSDetector::runMultiDetection (const Pt2i &p1, const Pt2i &p2) Pt2i ptstart = pts.at (locmax[i]); if (gMap->isFree (ptstart)) { - int oldEdgeDir = edgeDirection; - if (edgeDirection != 0) edgeDirection = 1; - while (isnext && edgeDirection >= -1) + bool savedOppDir = oppositeGradientDir; + oppositeGradientDir = false; + int nbDets = (gMap->isOrientationConstraintOn () ? 2 : 1); + if (singleMultiOn) nbDets = 1; + while (isnext && nbDets != 0) { int res = RESULT_VOID; if (staticDetOn) res = staticDetect (p1, p2, true, ptstart); @@ -250,10 +253,11 @@ bool BSDetector::runMultiDetection (const Pt2i &p1, const Pt2i &p2) bsf = NULL; // to avoid BS deletion if ((int) (mbsf.size ()) == maxtrials) isnext = false; } + oppositeGradientDir = ! oppositeGradientDir; + nbDets --; nbtrials ++; - edgeDirection -= 2; } - edgeDirection = oldEdgeDir; + oppositeGradientDir = savedOppDir; } } return (isnext); @@ -366,7 +370,8 @@ int BSDetector::detect (const Pt2i &p1, const Pt2i &p2, //----------------------------- Pt2i pCenter = bsini->getCenter (); Vr2i gRef = gMap->getValue (pCenter); - if (edgeDirection == -1) gRef.invert (); + if (oppositeGradientDir && gMap->isOrientationConstraintOn ()) + gRef.invert (); // Scan recentering and fitting //----------------------------- @@ -488,7 +493,8 @@ int BSDetector::staticDetect (const Pt2i &p1, const Pt2i &p2, //----------------------------- Pt2i pCenter = bsini->getCenter (); Vr2i gRef = gMap->getValue (pCenter); - if (edgeDirection == -1) gRef.invert (); + if (oppositeGradientDir && gMap->isOrientationConstraintOn ()) + gRef.invert (); // Scan recentering and fitting //----------------------------- @@ -677,6 +683,17 @@ void BSDetector::switchPreliminary () } +bool BSDetector::switchOppositeGradient () +{ + if (gMap != NULL && gMap->isOrientationConstraintOn ()) + { + oppositeGradientDir = ! oppositeGradientDir; + return true; + } + return false; +} + + void BSDetector::setStaticDetector (bool status) { if (staticDetOn && ! status) diff --git a/Code/FBSD/BlurredSegment/bsdetector.h b/Code/FBSD/BlurredSegment/bsdetector.h index 4ecb328..9952068 100755 --- a/Code/FBSD/BlurredSegment/bsdetector.h +++ b/Code/FBSD/BlurredSegment/bsdetector.h @@ -269,31 +269,51 @@ public: void switchPreliminary (); /** - * \brief Returns the edge direction constraint status. - * +1 : Edge direction constrained to the initial direction. - * -1 : Edge direction constrained to the initial direction opposite. - * 0 : Edge constraint free (detects lines as well as edges). + * \brief Returns whether opposite edge direction is set in double edge mode. */ - inline int edgeDirectionConstraint () + inline bool isOppositeGradientOn () const { - return (edgeDirection); + return (oppositeGradientDir); } /** * \brief Inverts the edge direction for detection stage. + * Effective only in single edge detection mode. + * Returns whether the modification was actually made. */ - inline void invertEdgeDirection () + bool switchOppositeGradient (); + + /** + * \brief Returns whether opposite edge direction is set in double edge mode. + */ + inline bool isSingleEdgeModeOn () const + { + if (gMap != NULL) return (gMap->isOrientationConstraintOn ()); + return (true); + } + + /** + * \brief Switches between single and double edge detection. + */ + inline void switchSingleOrDoubleEdge () + { + if (gMap != NULL) gMap->switchOrientationConstraint (); + } + + /** + * \brief Returns whether a single edge mode is set for multidetections. + */ + inline bool isSingleMultiOn () const { - edgeDirection = - edgeDirection; + return (singleMultiOn); } /** - * \brief Switches the edge direction constraint. + * \brief Switches between single and double edge mode for multidetections. */ - inline void switchEdgeDirectionConstraint () + inline void switchSingleOrDoubleMultiDetection () { - edgeDirection = (edgeDirection == 0 ? 1 : 0); - gMap->switchOrientationConstraint (); + singleMultiOn = ! singleMultiOn; } /** @@ -626,12 +646,11 @@ private : /** Gradient map. */ VMap *gMap; - /** Direction constraint of the detected edge : - * +1 : complies to initial direction - * -1 : complies to initial direction opposite - * 0 : no direction condition (detects lines as well as edges) + /** Selects points with opposite gradient direction. + * Opposite to gradient direction at start point. + * Used to detect two close edges with opposite gradients. */ - int edgeDirection; + bool oppositeGradientDir; /** Minimal size of the initial segment. */ int initialMinSize; /** Final fragmentation test status. */ @@ -652,6 +671,8 @@ private : int nbSmallBS; /** Segment multi-selection modality status. */ bool multiSelection; + /** Single or double mode for multi-selections. */ + bool singleMultiOn; /** Count of trials in a multi-detection. */ int nbtrials; /** Maximum number of trials in a multi-detection. */ diff --git a/Methode/ctrl.tex b/Methode/ctrl.tex index aafa0e5..dbcf967 100755 --- a/Methode/ctrl.tex +++ b/Methode/ctrl.tex @@ -29,7 +29,7 @@ e && Inverse la direction de r\'ef\'erence (autre bord) \\ g && Ajuste le seuil du gradient \\ j && Ajuste le seuil de voisinage pour les suivis rapides \\ k && Ajuste la taille minimale des fragments \\ -l && Ajuste la taille minimale du segment final \\ +l && Ajuste la taille minimale du segment initial \\ m && D\'etection exhaustive de tous les segments \\ n && Allume le segment suivant dans une d\'etection multiple \\ o && Edite le segment d\'etect\'e (seg.txt) \\ @@ -42,12 +42,13 @@ x && Ajuste la marge de consigne d'\'epaisseur du segment flou pour le suivi rap y && Ajuste le contraste de l'image \\ z && Ajuste le d\'elai de d\'eclenchement du contr\^ole de la consigne d'\'epaisseur \\ Ctrl-b && Commute le fond d'\'ecran de la fen\^etre principale \\ -Ctrl-d && Commute le test de densit\'e \\ +Ctrl-d && Commute le test initial de densit\'e \\ Ctrl-e && Commute la prise en compte de la direction du bord (trait / contour) \\ Ctrl-f && Commute le pr\'e-filtrage (segment initial) \\ Ctrl-h && Commute le filtrage du segment final \\ Ctrl-j && Commute la contrainte de voisinage pour les suivis rapides \\ Ctrl-k && Commute le test de fragmentation \\ +Ctrl-l && Commute le test de densit\'e final \\ Ctrl-m && Commute la d\'etection multiple \\ Ctrl-n && Commute la limitation de l'extension de la d\'etection initiale \\ Ctrl-o && Commute la directionnalit\'e des scans \\ -- GitLab