From d53b9414d77510ba681d6717a78c97ff16a5a978 Mon Sep 17 00:00:00 2001 From: even <philippe.even@loria.fr> Date: Fri, 23 Nov 2018 16:24:27 +0100 Subject: [PATCH] Structure view revisited --- Code/Seg/BSTools/bsdetectionwidget.cpp | 38 +++++-- Code/Seg/BSTools/bsdetectionwidget.h | 12 +- Code/Seg/BSTools/bsstructureitem.cpp | 11 +- Code/Seg/BSTools/bsstructureview.cpp | 152 ++++++------------------- Code/Seg/BSTools/bsstructureview.h | 44 +++---- Code/Seg/BlurredSegment/bsdetector.cpp | 10 +- Code/Seg/BlurredSegment/bsdetector.h | 8 +- Methode/ctrl.tex | 6 +- 8 files changed, 107 insertions(+), 174 deletions(-) diff --git a/Code/Seg/BSTools/bsdetectionwidget.cpp b/Code/Seg/BSTools/bsdetectionwidget.cpp index 7f770c7..2392827 100755 --- a/Code/Seg/BSTools/bsdetectionwidget.cpp +++ b/Code/Seg/BSTools/bsdetectionwidget.cpp @@ -279,24 +279,34 @@ void BSDetectionWidget::switchIdetAnalyzer () void BSDetectionWidget::mousePressEvent (QMouseEvent *event) { - this->p1 = Pt2i (event->pos().x (), height - 1 - event->pos().y()); + oldp1.set (p1); + oldp2.set (p2); + p1 = Pt2i (event->pos().x (), height - 1 - event->pos().y()); udef = true; } void BSDetectionWidget::mouseReleaseEvent (QMouseEvent *event) { - this->p2 = Pt2i (event->pos().x (), height - 1 - event->pos().y()); -alternate = 0; - cerr << "p1 defined: " << p1.x () << " " << p1.y () << endl; - cerr << "p2 defined: " << p2.x () << " " << p2.y () << endl; - extract (); + 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; + extract (); + } } void BSDetectionWidget::mouseMoveEvent (QMouseEvent *event) { - this->p2 = Pt2i (event->pos().x (), height - 1 - event->pos().y ()); + 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 @@ -408,14 +418,23 @@ void BSDetectionWidget::keyPressEvent (QKeyEvent *event) << endl; extract (); } + else + { + // Tunes the minimal size of connected components + detector.incConnectedComponentMinSize ( + (event->modifiers () & Qt::ShiftModifier) == 0); + cout << "Connected components min size = " + << detector.getConnectedComponentMinSize () << endl; + extract (); + } break; case Qt::Key_L : // Tunes the output blurred segment minimal size detector.setBSminSize (detector.getBSminSize () + (event->modifiers () & Qt::ShiftModifier ? -1 : 1)); - extract (); cout << "Output BS min size = " << detector.getBSminSize () << endl; + extract (); break; case Qt::Key_M : @@ -743,6 +762,8 @@ void BSDetectionWidget::displayBackground () 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))); } @@ -806,6 +827,7 @@ void BSDetectionWidget::displayDetectionResult (int hnum) { strucview->setExamined (-1); strucview->scene()->update (); + strucview->repaint (); } if (verbose) writeDetectionStatus (); } diff --git a/Code/Seg/BSTools/bsdetectionwidget.h b/Code/Seg/BSTools/bsdetectionwidget.h index 0618b9c..aa6f687 100755 --- a/Code/Seg/BSTools/bsdetectionwidget.h +++ b/Code/Seg/BSTools/bsdetectionwidget.h @@ -187,8 +187,14 @@ private: static const int DEFAULT_PEN_WIDTH; - /** Initial scan end points */ - Pt2i p1, p2; + /** Initial scan start point. */ + Pt2i p1; + /** Initial scan end point. */ + Pt2i p2; + /** Saved scan start point. */ + Pt2i oldp1; + /** Saved scan end point. */ + Pt2i oldp2; /** Flag indicating if the mouse is not dragging. */ bool nodrag; /** Flag indicating if the detection is user defined. */ @@ -213,7 +219,7 @@ private: /** Flag indicating whether blurred segments bounds are visible. */ bool bsBoundsVisible; /** Background type. - * Values : BACK_NO, BACK_IMAGE, BACK_GRAD, BACK_GRADX, BACK_GRADY. */ + * BACK_BLACK, BACK_WHITE, BACK_IMAGE, BACK_GRAD, BACK_GRADX, BACK_GRADY. */ int background; /** Flag indicating whether detection result should be output. */ bool verbose; diff --git a/Code/Seg/BSTools/bsstructureitem.cpp b/Code/Seg/BSTools/bsstructureitem.cpp index ff025de..c52e75f 100755 --- a/Code/Seg/BSTools/bsstructureitem.cpp +++ b/Code/Seg/BSTools/bsstructureitem.cpp @@ -185,16 +185,15 @@ void BSStructureItem::paintConnectedComponents (QPainter *painter, int step) if (verbose) { initText (painter); - int ccs = det->connectedComponentMinSize (); + int ccs = det->getConnectedComponentMinSize (); if (bs != NULL) { int bsccp = bs->countOfConnectedPoints (ccs); int bssize = bs->getAllPoints().size (); - addText (painter, QString ("G connectivity constraint ") - + (det->isSetConnectivityConstraint () ? + bool ccon = (step == BSDetector::STEP_FINAL + && det->isSetConnectivityConstraint ()); + addText (painter, QString ("Connectivity constraint ") + (ccon ? QString ("on") : QString ("off"))); - addText (painter, QString ("C connected components min size = ") - + QString::number (ccs) + QString (" points")); addText (painter, QString::number (bssize) + QString (" points")); addText (painter, QString::number (bs->countOfConnectedComponents ()) + QString (" connected components")); @@ -206,7 +205,7 @@ void BSStructureItem::paintConnectedComponents (QPainter *painter, int step) addText (painter, QString::number (bsccp) + QString (" connected points with min size ") + QString::number (ccs)); - if (bsccp < bssize / 2) + if (ccon && bsccp < bssize / 2) addText (painter, QString ("BS too sparse !")); } } diff --git a/Code/Seg/BSTools/bsstructureview.cpp b/Code/Seg/BSTools/bsstructureview.cpp index b0d33f1..52732a8 100755 --- a/Code/Seg/BSTools/bsstructureview.cpp +++ b/Code/Seg/BSTools/bsstructureview.cpp @@ -6,22 +6,26 @@ using namespace std; +const int BSStructureView::BACK_BLACK = 0; +const int BSStructureView::BACK_WHITE = 1; +const int BSStructureView::BACK_IMAGE = 2; +const int BSStructureView::BACK_GRAD = 3; + + BSStructureView::BSStructureView (QImage *im, BSDetector *sd) { - graylevelImage = im; - currentImage = im; - det = sd; int w = im->width (); int h = im->height (); - imageInBack = true; - gradDir = 0; + background = BACK_IMAGE; + graylevelImage = im; + currentImage = im; gradImage = NULL; - gradInBack = false; + det = sd; setBackgroundBrush (QBrush (*currentImage)); setScene (new QGraphicsScene (0, 0, w, h)); grid = new BSStructureItem (w, h, im, sd); scene()->addItem (grid); - setWindowTitle (grid->itemTitle () + backgroundSource ()); + setWindowTitle (grid->itemTitle ()); } @@ -38,14 +42,18 @@ void BSStructureView::setGradientImage (QImage *gim) } -void BSStructureView::updateBackground (bool zoomChanged) +void BSStructureView::updateBackground () { - if (imageInBack) + if (background == BACK_BLACK) + setBackgroundBrush (QBrush (Qt::black)); + else if (background == BACK_WHITE) + setBackgroundBrush (QBrush (Qt::white)); + else { int w = currentImage->width (); int h = currentImage->height (); int zf = grid->zoomFactor (); - if (zoomChanged) image = currentImage->scaled (w * zf, h * zf); + image = currentImage->scaled (w * zf, h * zf); QBrush qb (image); qb.setTransform (QTransform::fromTranslate ( w / 2 - zf * (w / 2 + grid->focusX ()), @@ -57,34 +65,9 @@ void BSStructureView::updateBackground (bool zoomChanged) void BSStructureView::toggleBackground () { - imageInBack = ! imageInBack; - if (imageInBack) setBackgroundBrush (QBrush (image)); - else setBackgroundBrush (QBrush (Qt::white)); -} - - -void BSStructureView::toggleGradient () -{ - if (currentImage == gradImage) currentImage = graylevelImage; - else currentImage = gradImage; - setWindowTitle (grid->itemTitle () + backgroundSource ()); -} - - -void BSStructureView::toggleGradientType () -{ - if (++gradDir == 3) gradDir = 0; - if (currentImage == gradImage) currentImage = gradImage; - setWindowTitle (grid->itemTitle () + backgroundSource ()); -} - - -QString BSStructureView::backgroundSource () const -{ - if (currentImage != gradImage) return (""); - else if (gradDir == 2) return (" (on gradient Y)"); - else if (gradDir == 1) return (" (on gradient X)"); - return (" (on gradient Magn)"); + if (background++ == BACK_GRAD) background = BACK_BLACK; + if (background == BACK_GRAD) currentImage = gradImage; + else currentImage = graylevelImage; } @@ -106,7 +89,7 @@ bool BSStructureView::processKeyEvent (QKeyEvent *event) case Qt::Key_I : // Info if (event->modifiers () & Qt::ControlModifier) grid->switchScanDisplay (); else grid->toggleDisplay ((event->modifiers () & Qt::ShiftModifier) == 0); - setWindowTitle (grid->itemTitle () + backgroundSource ()); + setWindowTitle (grid->itemTitle ()); scene()->update (); update (); processed = false; @@ -120,18 +103,19 @@ bool BSStructureView::processKeyEvent (QKeyEvent *event) break; case Qt::Key_B : // Background - if (event->modifiers () & Qt::ControlModifier) toggleGradientType (); - else if (event->modifiers () & Qt::ShiftModifier) toggleGradient (); - else toggleBackground (); - updateBackground (true); - scene()->update (); - update (); - processed = false; + if (event->modifiers () & Qt::ControlModifier) + { + toggleBackground (); + updateBackground (); + scene()->update (); + update (); + processed = false; + } break; case Qt::Key_Plus : // Zoom in grid->zoomIn (); - updateBackground (true); + updateBackground (); scene()->update (); update (); processed = false; @@ -139,7 +123,7 @@ bool BSStructureView::processKeyEvent (QKeyEvent *event) case Qt::Key_Minus : // Zoom out grid->zoomOut (); - updateBackground (true); + updateBackground (); scene()->update (); update (); processed = false; @@ -147,7 +131,7 @@ bool BSStructureView::processKeyEvent (QKeyEvent *event) case Qt::Key_Left : // Go leftwards grid->shift (-1, 0); - updateBackground (false); + updateBackground (); scene()->update (); update (); processed = false; @@ -155,7 +139,7 @@ bool BSStructureView::processKeyEvent (QKeyEvent *event) case Qt::Key_Right : // Go rightwards grid->shift (1, 0); - updateBackground (false); + updateBackground (); scene()->update (); update (); processed = false; @@ -163,7 +147,7 @@ bool BSStructureView::processKeyEvent (QKeyEvent *event) case Qt::Key_Up : // Go upwards grid->shift (0, -1); - updateBackground (false); + updateBackground (); scene()->update (); update (); processed = false; @@ -171,75 +155,11 @@ bool BSStructureView::processKeyEvent (QKeyEvent *event) case Qt::Key_Down : // Go downwards grid->shift (0, 1); - updateBackground (false); + updateBackground (); scene()->update (); update (); processed = false; break; - - case Qt::Key_C : // Increments the connected components min size - det->incConnectedComponentMinSize ( - (event->modifiers () & Qt::ShiftModifier) == 0); - update (); - processed = true; - break; - - case Qt::Key_G : // Increments the connected components min size - det->switchConnectivityConstraint (); - update (); - processed = true; - break; - - case Qt::Key_S : // Switch dynamic scans - det->switchDynamicScans (); - update (); - processed = true; - break; - - case Qt::Key_O : // Switch orthographic scans - det->switchOrthoScans (); - update (); - processed = true; - break; - - case Qt::Key_P : // Switch pre-filtering - det->switchFiltering (0); - update (); - processed = true; - break; - - case Qt::Key_F : // Switch final filtering - det->switchFiltering (1); - update (); - processed = true; - break; - - case Qt::Key_D : // Initial detection extension limitation - det->switchInitialBounding (); - update (); - processed = true; - break; - - case Qt::Key_W : // Fine tracks max width - det->setFineTracksMaxWidth (det->fineTracksMaxWidth () + - (event->modifiers () & Qt::ShiftModifier ? -1 : 1)); - update (); - processed = true; - break; - - case Qt::Key_K : // Output blurred segment min size - det->setBSminSize (det->getBSminSize () + - (event->modifiers () & Qt::ShiftModifier ? -1 : 1)); - update (); - processed = true; - break; - - case Qt::Key_H : // Pixel lack tolerence - det->setPixelLackTolerence (det->getPixelLackTolerence () + - (event->modifiers () & Qt::ShiftModifier ? -1 : 1)); - update (); - processed = true; - break; } return processed; } diff --git a/Code/Seg/BSTools/bsstructureview.h b/Code/Seg/BSTools/bsstructureview.h index ea5aa71..00203be 100755 --- a/Code/Seg/BSTools/bsstructureview.h +++ b/Code/Seg/BSTools/bsstructureview.h @@ -47,52 +47,40 @@ protected: private: + /** Background status : uniform black. */ + static const int BACK_BLACK; + /** Background status : uniform white. */ + static const int BACK_WHITE; + /** Background status : intensity image displayed. */ + static const int BACK_IMAGE; + /** Background status : gradient image displayed. */ + static const int BACK_GRAD; /** Pointer to the blurred segment detector. */ BSDetector *det; - /** Pointer to the raw image. */ - QImage *graylevelImage; /** Pointer to the blurred segment structure graphics item. */ BSStructureItem *grid; - /** Background image. */ - QImage image; - /** Background image display modality. */ - bool imageInBack; - /** Pointer to the currently displayed image. */ + /** Background type : BACK_BLACK, BACK_WHITE, BACK_IMAGE or BACK_GRAD. */ + int background; + /** Pointer to the background image. */ QImage *currentImage; + /** Pointer to the raw image. */ + QImage *graylevelImage; /** Pointer to the gradient image. */ QImage *gradImage; - /** Type of gradient image displayed (magnitude, horizontal or vertical). */ - int gradDir; - /** Gradient image display modality. */ - bool gradInBack; + /** Effective background image. */ + QImage image; /** * Updates the background image. - * @param zoomChanged If 'true', the zoom factorshould be taken into account */ - void updateBackground (bool zoomChanged); - - /** - * Gets the background source - */ - QString backgroundSource () const; + void updateBackground (); /** * Toggles the window background between the current image or plain white. */ void toggleBackground (); - /** - * Toggles the current image between gray level or gradient image. - */ - void toggleGradient (); - - /** - * Toggles the displayed gradient image (magnitude, horizontal or vertical). - */ - void toggleGradientType (); - }; #endif diff --git a/Code/Seg/BlurredSegment/bsdetector.cpp b/Code/Seg/BlurredSegment/bsdetector.cpp index 5e94747..0c598e9 100755 --- a/Code/Seg/BlurredSegment/bsdetector.cpp +++ b/Code/Seg/BlurredSegment/bsdetector.cpp @@ -41,10 +41,10 @@ BSDetector::BSDetector () edgeDirection = 0; // detects line (not only edges) bsMinSize = DEFAULT_BS_MIN_SIZE; - connectMinSize = DEFAULT_CONNECT_MIN_SIZE; + ccOn = true; + ccMinSize = DEFAULT_CONNECT_MIN_SIZE; recenteringOn = true; fittingOn = false; - ccOn = true; densityTestOn = true; multiSelection = false; autoResol = DEFAULT_AUTO_RESOLUTION; @@ -274,7 +274,7 @@ void BSDetector::detect (const Pt2i &p1, const Pt2i &p2, Pt2i *p0) //------------------------------*/ if (ccOn) { - int bsccp = bsf->countOfConnectedPoints (connectMinSize); + int bsccp = bsf->countOfConnectedPoints (ccMinSize); int bssize = bsf->getAllPoints().size (); if (bsccp < bssize / 2) { @@ -339,7 +339,7 @@ void BSDetector::switchFiltering (int step) bool BSDetector::incConnectedComponentMinSize (bool increase) { - if ((! increase) && connectMinSize <= 1) return false; - connectMinSize += (increase ? 1 : -1); + if ((! increase) && ccMinSize <= 1) return false; + ccMinSize += (increase ? 1 : -1); return true; } diff --git a/Code/Seg/BlurredSegment/bsdetector.h b/Code/Seg/BlurredSegment/bsdetector.h index a3ab53a..b1301ae 100755 --- a/Code/Seg/BlurredSegment/bsdetector.h +++ b/Code/Seg/BlurredSegment/bsdetector.h @@ -436,7 +436,7 @@ public: /** * \brief Returns the minimal size of the segment connected components. */ - inline int connectedComponentMinSize () { return connectMinSize; } + inline int getConnectedComponentMinSize () { return ccMinSize; } /** * \brief Increments the minimal size of the connected components. @@ -468,12 +468,12 @@ private : * 0 : no direction condition (detects lines as well as edges) */ int edgeDirection; - /** Connectivity constraint status. */ - bool ccOn; /** Minimal size of the detected blurred segment. */ int bsMinSize; + /** Connectivity constraint status. */ + bool ccOn; /** Minimal size of the connected components to validate a blurred segment. */ - int connectMinSize; + int ccMinSize; /** Automatic scan recentering (based on previous detection). */ bool recenteringOn; /** Automatic scan width selection (based on previous detection). */ diff --git a/Methode/ctrl.tex b/Methode/ctrl.tex index f15f4e7..fc34159 100755 --- a/Methode/ctrl.tex +++ b/Methode/ctrl.tex @@ -27,6 +27,7 @@ a/q/c &\spa & Enregistre / Affiche / Supprime les segments \\ e && Inverse la direction de r\'ef\'erence (autre bord) \\ g && Ajuste le seuil du gradient \\ n && Allume le segment suivant dans une d\'etection multiple \\ +k && Ajuste la taille minimale des composantes connexes \\ l && Ajuste la taille minimale du segment final \\ m && D\'etection exhaustive de tous les segments \\ n && Allume le segment suivant dans une d\'etection multiple \\ @@ -69,10 +70,7 @@ v && Commute l'affichage du texte \\ \hline \hline \multicolumn{3}{|l|}{Analyse des segments flous extraits :} \\ Ctrl-i && Commute le type d'affichage des scans \\ -b && Commute l'affichage de l'image de fond \\ -B && Commute l'image d'intensit\'e avec celle du gradient \\ -Ctrl-b && Commute le type de gradient affich\'e (magnitude, X ou Y) \\ -c && Incr\'emente la longueur minimale des composantes connexes \\ +Ctrl-b && Commute le fond d'\'ecran de la fen\^etre principale. \\ + -- && Zoom \\ $< \wedge > \vee$ && D\'ecalage de l'observation \\ \hline \hline -- GitLab