From 7af2bb7858ac23a7dcae60771321954bc284d921 Mon Sep 17 00:00:00 2001
From: even <philippe.even@loria.fr>
Date: Sun, 11 Nov 2018 13:55:15 +0100
Subject: [PATCH] Detection widget revisited

---
 Code/Seg/BSTools/bsdetectionwidget.cpp | 423 +++++++++++--------------
 Code/Seg/BSTools/bsdetectionwidget.h   | 138 +++++---
 Code/Seg/BlurredSegment/bsdetector.cpp |  43 +--
 Code/Seg/BlurredSegment/bsdetector.h   |  17 +-
 Methode/ctrl.tex                       |   4 +-
 5 files changed, 311 insertions(+), 314 deletions(-)

diff --git a/Code/Seg/BSTools/bsdetectionwidget.cpp b/Code/Seg/BSTools/bsdetectionwidget.cpp
index a5e919e..772688f 100755
--- a/Code/Seg/BSTools/bsdetectionwidget.cpp
+++ b/Code/Seg/BSTools/bsdetectionwidget.cpp
@@ -7,9 +7,6 @@
 using namespace std;
 
 
-
-const int BSDetectionWidget::MAX_WIDTH_TUNING = 400;
-const int BSDetectionWidget::DETECTION_LACKS_TUNING = 20;
 const int BSDetectionWidget::DEFAULT_PEN_WIDTH = 1;
 
 
@@ -21,7 +18,7 @@ BSDetectionWidget::BSDetectionWidget (QWidget *parent)
   // Sets default user interface parameters
   setFocus ();
   grabKeyboard ();
-  fixed = false;
+  udef = false;
 
   // Sets initial values for the gradient map
   gMap = NULL;
@@ -33,9 +30,16 @@ BSDetectionWidget::BSDetectionWidget (QWidget *parent)
 
   alternate = 0;
   verbose = false;
-  capture = false;
   paintItBlack = false;
   exam = -1;
+
+  selectionColor = Qt::red;
+  bsColor = Qt::yellow;
+  bsHighColor = Qt::blue;
+  bsPointsVisible = true;
+  boundColor = Qt::magenta;
+  boundHighColor = Qt::green;
+  bsBoundsVisible = false;
 }
 
 
@@ -108,55 +112,6 @@ void BSDetectionWidget::paintEvent (QPaintEvent *)
 }
 
 
-void BSDetectionWidget::storeExtractedSegment ()
-{
-  BlurredSegment *bs = detector.getBlurredSegment (1);
-  if (bs != NULL)
-  {
-    ExtractedSegment es;
-    es.bs = bs;
-    es.p1 = p1;
-    es.p2 = p2;
-    extractedSegments.push_back (es);
-    detector.preserveFormerBlurredSegment ();
-  }
-}
-
-
-void BSDetectionWidget::displayExtractedSegments ()
-{
-  augmentedImage = loadedImage;
-  QPainter painter (&augmentedImage);
-  if (! extractedSegments.empty ())
-  {
-    vector<ExtractedSegment>::iterator it = extractedSegments.begin ();
-    while (it != extractedSegments.end ())
-    {
-      vector<Pt2i> bnd;
-      DigitalStraightSegment *dss = it->bs->getSegment ();
-      dss->getBoundPoints (bnd, false, 0, 0, width, height);
-      drawListOfPixels (bnd, Qt::green, painter);
-      dss->getBoundPoints (bnd, true, 0, 0, width, height);
-      drawListOfPixels (bnd, Qt::green, painter);
-      bnd = it->bs->getAllPoints ();
-      drawListOfPixels (bnd, Qt::blue, painter);
-      drawLine (it->p1, it->p2, Qt::white, painter);
-      it ++;
-    }
-  }
-  update (QRect (QPoint (0, 0), QPoint (width, height)));
-}
-
-
-void BSDetectionWidget::clearExtractedSegments ()
-{
-  vector<ExtractedSegment>::iterator it = extractedSegments.begin ();
-  while (it != extractedSegments.end ())
-    delete ((it++)->bs->getSegment ());
-  extractedSegments.clear ();
-}
-
-
 void BSDetectionWidget::closeAccuAnalyzer ()
 {
   if (accuview != NULL)
@@ -244,12 +199,12 @@ void BSDetectionWidget::switchProfileAnalyzer ()
 void BSDetectionWidget::mousePressEvent (QMouseEvent *event)
 {
   this->p1 = Pt2i (event->pos().x (), height - 1 - event->pos().y());
+  udef = true;
 }
 
 
 void BSDetectionWidget::mouseReleaseEvent (QMouseEvent *event)
 {
-  fixed = true;
   this->p2 = Pt2i (event->pos().x (), height - 1 - event->pos().y());
 alternate = 0;
   cerr << "p1 defined: " << p1.x () << " " << p1.y () << endl;
@@ -260,7 +215,6 @@ alternate = 0;
 
 void BSDetectionWidget::mouseMoveEvent (QMouseEvent *event)
 {
-  fixed = false;
   this->p2 = Pt2i (event->pos().x (), height - 1 - event->pos().y ());
   if (verbose) cerr << "(" << p1.x () << ", " << p1.y () << ") ("
                     << p2.x () << ", " << p2.y () << ")" << endl;
@@ -268,7 +222,7 @@ void BSDetectionWidget::mouseMoveEvent (QMouseEvent *event)
       && (width > p2.x() && height > p2.y()
           && p2.x() > 0 && p2.y() > 0))
   {
-    extract ();
+    extract (false);
   }
 }
 
@@ -280,7 +234,22 @@ void BSDetectionWidget::keyPressEvent (QKeyEvent *event)
     case Qt::Key_U :
       cerr << "p1 update: " << p1.x () << " " << p1.y () << endl;
       cerr << "p2 update: " << p2.x () << " " << p2.y () << endl;
-      extract (true);
+      extract ();
+      break;
+
+    case Qt::Key_A :
+      if (event->modifiers () & Qt::ShiftModifier)
+      {
+        bsBoundsVisible = ! bsBoundsVisible;
+        cout << "Segments bounds "
+             << (bsBoundsVisible ? "visible" : "hidden") << endl;
+      }
+      else
+      {
+        bsPointsVisible = ! bsPointsVisible;
+        cout << "Segments points "
+             << (bsPointsVisible ? "visible" : "hidden") << endl;
+      }
       break;
 
     case Qt::Key_M : // Multi-selection switch
@@ -299,20 +268,23 @@ void BSDetectionWidget::keyPressEvent (QKeyEvent *event)
       break;
 
     case Qt::Key_L : // Next multi-selected segment
-      displayNext (event->modifiers () & Qt::ShiftModifier ? -1 : 1);
-      cout << "Selection du segment " << exam << endl;
+      if (! detector.getBlurredSegments(1).empty ())
+      {
+        displayNext (event->modifiers () & Qt::ShiftModifier ? -1 : 1);
+        cout << "Selection du segment " << exam << endl;
+      }
       break;
 
     case Qt::Key_Y : // Initial detection extension limitation
       detector.switchInitialBounding ();
-      extract (true);
+      extract ();
       cout << "Initial step max extension = "
            << detector.initialDetectionMaxExtent () << endl;
       break;
 
     case Qt::Key_D : // Density test at initial step
       detector.switchDensityTest ();
-      extract (true);
+      extract ();
       cout << "Density test : "
            << (detector.isSetDensityTest () ? "on" : "off") << endl;
       break;
@@ -320,21 +292,21 @@ void BSDetectionWidget::keyPressEvent (QKeyEvent *event)
     case Qt::Key_W : // Input max width
       detector.setInputMaxWidth (detector.getInputMaxWidth () +
         (event->modifiers () & Qt::ShiftModifier ? -1 : 1));
-      extract (true);
+      extract ();
       cout << "Input max width = " << detector.getInputMaxWidth () << endl;
       break;
 
     case Qt::Key_K : // Output blurred segment min size
       detector.setBSminSize (detector.getBSminSize () +
         (event->modifiers () & Qt::ShiftModifier ? -1 : 1));
-      extract (true);
+      extract ();
       cout << "Output BS min size = " << detector.getBSminSize () << endl;
       break;
 
     case Qt::Key_H : // Pixel lack tolerence
       detector.setPixelLackTolerence (detector.getPixelLackTolerence () +
         (event->modifiers () & Qt::ShiftModifier ? -1 : 1));
-      extract (true);
+      extract ();
       cout << "Lack tolerence = " << detector.getPixelLackTolerence ()
            << " pixels" << endl;
       break;
@@ -348,14 +320,14 @@ void BSDetectionWidget::keyPressEvent (QKeyEvent *event)
 
     case Qt::Key_Q :
       detector.switchAutoRestart ();
-      extract (true);
+      extract ();
       cout << "Segment continuation after = "
            << detector.getRestartOnLack () << " pixels" << endl;
       break;
 
     case Qt::Key_T :
       detector.toggleThinning ();
-      extract (true);
+      extract ();
       cout << "Thinning "
            << (detector.isThinningActivated () ? "on" : "off") << endl;
       break;
@@ -364,42 +336,42 @@ void BSDetectionWidget::keyPressEvent (QKeyEvent *event)
       detector.switchAutoWidth ();
       cout << "Final step max width " << (detector.autoWidthOn () ?
               "fitted to initial segment" : "left unchanged") << endl;
-      extract (true);
+      extract ();
       break;
 
     case Qt::Key_S :
       detector.switchDynamicScans ();
       cout << (detector.dynamicScansOn () ?
                "Dynamic scans" : "Static scans") << endl;
-      extract (true);
+      extract ();
       break;
 
     case Qt::Key_O :
       detector.switchOrthoScans ();
       cout << (detector.orthoScansOn () ?
                "Orthographic scans" : "Directional scans") << endl;
-      extract (true);
+      extract ();
       break;
 
     case Qt::Key_F :
       detector.switchFiltering (1);
       cout << "Final filtering "
            << (detector.isFiltering (1) ? "on" : "off") << endl;
-      extract (true);
+      extract ();
       break;
 
     case Qt::Key_P :
       if (event->modifiers () & Qt::ShiftModifier)
       {
-        capture = true;
-        cout << "Next extraction will be shot in capture.png" << endl;
+        augmentedImage.save ("capture.png");
+        cout << "Main window shot in capture.png" << endl;
       }
       else
       {
         detector.switchFiltering (0);
         cout << "Pre-filtering "
              << (detector.isFiltering (0) ? "on" : "off") << endl;
-        extract (true);
+        extract ();
       }
       break;
 
@@ -407,23 +379,23 @@ void BSDetectionWidget::keyPressEvent (QKeyEvent *event)
       detector.switchConnectivityConstraint ();
       cout << "Connectivity constraint "
            << (detector.isSetConnectivityConstraint () ? "on" : "off") << endl;
-      extract (true);
+      extract ();
       break;
 
     case Qt::Key_C :
       if (event->modifiers () & Qt::ControlModifier)
-        storeExtractedSegment ();
+        saveExtractedSegment ();
       break;
 
     case Qt::Key_V :
       if (event->modifiers () & Qt::ControlModifier)
-        displayExtractedSegments ();
+        displaySavedSegments ();
       else switchVerbose ();
       break;
 
     case Qt::Key_Z :
       if (event->modifiers () & Qt::ControlModifier)
-        clearExtractedSegments ();
+        clearSavedSegments ();
       break;
 
     case Qt::Key_E :
@@ -442,14 +414,14 @@ void BSDetectionWidget::keyPressEvent (QKeyEvent *event)
           cout << "Opposite edge detection" << endl;
           break;
       }
-      extract (true);
+      extract ();
       break;
 
     case Qt::Key_J :
       detector.switchPreliminary ();
       cout << "Preliminary detection "
            << (detector.isPreliminary () ? "on" : "off") << endl;
-      extract (true);
+      extract ();
       break;
 
     case Qt::Key_1 :
@@ -478,55 +450,52 @@ void BSDetectionWidget::keyPressEvent (QKeyEvent *event)
   }
   else if (strucview != NULL && strucview->isActiveWindow ())
   {
-    if (strucview->processKeyEvent (event)) extract (true);
+    if (strucview->processKeyEvent (event)) extract ();
   }
   else if (accuview != NULL && accuview->isActiveWindow ())
   {
-    if (accuview->processKeyEvent (event)) extract (true);
+    if (accuview->processKeyEvent (event)) extract ();
   }
   else if (profileview != NULL && profileview->isActiveWindow ())
   {
-    if (profileview->processKeyEvent (event)) extract (true);
+    if (profileview->processKeyEvent (event)) extract ();
   }
 }
 
 
-void BSDetectionWidget::drawListOfPixels (vector<Pt2i> vectPixels,
-                                          QColor color, QPainter &painter)
+void BSDetectionWidget::drawPoints (QPainter &painter,
+                                    vector<Pt2i> pts, QColor color)
 {
-  vector<Pt2i>::iterator iter = vectPixels.begin ();
-  while (iter != vectPixels.end ())
+  vector<Pt2i>::iterator iter = pts.begin ();
+  while (iter != pts.end ())
   {
-    Pt2i p = *iter;
+    Pt2i p = *iter++;
     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
-    iter ++;
-   }
+  }
 }
 
 
-void BSDetectionWidget::drawListOfPixels (vector<Pt2i> vectPixels,
-                                          QPainter &painter)
+void BSDetectionWidget::drawPixels (QPainter &painter, vector<Pt2i> pix)
 {
-  vector<Pt2i>::iterator iter = vectPixels.begin ();
-  while (iter != vectPixels.end ())
+  vector<Pt2i>::iterator iter = pix.begin ();
+  while (iter != pix.end ())
   {
-    Pt2i p = *iter;
+    Pt2i p = *iter++;
     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
-    iter ++;
-   }
+  }
 }
 
 
-void BSDetectionWidget::drawLine (const Pt2i from, const Pt2i to,
-                                  QColor color, QPainter &painter)
+void BSDetectionWidget::drawLine (QPainter &painter,
+                                  const Pt2i from, const Pt2i to, QColor color)
 {
   int n;
   Pt2i *pts = from.drawing (to, &n);
@@ -539,37 +508,63 @@ void BSDetectionWidget::drawLine (const Pt2i from, const Pt2i to,
 }
 
 
-void BSDetectionWidget::extract (bool withAllDisplay)
+void BSDetectionWidget::drawSelection (QPainter &painter,
+                                       const Pt2i from, const Pt2i to)
 {
-  if (! p1.equals (p2))
+  drawLine (painter, from, to, selectionColor);
+}
+
+
+void BSDetectionWidget::drawBlurredSegment (QPainter &painter,
+                                            BlurredSegment *bs, bool high)
+{
+  if (bs != NULL)
   {
-    fixed = withAllDisplay;
-    extract ();
+    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::extract ()
+void BSDetectionWidget::displayBackground ()
 {
   augmentedImage = loadedImage;
   QPainter painter (&augmentedImage);
-  if (p1.equals (p2))
-  {
-    update (QRect (QPoint (0, 0), QPoint (width, height)));
-    fixed = false;
-    return;
-  }
-  drawLine (p1, p2, Qt::red, painter);
+  update (QRect (QPoint (0, 0), QPoint (width, height)));
+}
 
-  if (detector.isMultiSelection ()) detector.multidetect (p1, p2);
-  else
+
+void BSDetectionWidget::displayDetectionResult (bool aux, int hnum)
+{
+  augmentedImage = loadedImage;
+  QPainter painter (&augmentedImage);
+  if (paintItBlack) painter.fillRect (0, 0, width, height, QBrush (Qt::black));
+  paintItBlack = false;
+  vector<BlurredSegment *> bss = detector.getBlurredSegments (1);
+  if (! bss.empty ())
   {
-    detector.freeMultiSelection ();
-    detector.detect (p1, p2);
+    int index = 0;
+    vector<BlurredSegment *>::const_iterator it = bss.begin ();
+    while (it != bss.end ())
+      drawBlurredSegment (painter, *it++, index++ == hnum);
   }
+  else
+    drawBlurredSegment (painter, detector.getBlurredSegment (1));
+  if (udef) drawSelection (painter, p1, p2);
+  update (QRect (QPoint (0, 0), QPoint (width, height)));
 
   // Update auxiliary view if not dragging
-  if (fixed)
+  if (aux)
   {
     if (profileview != NULL)
     {
@@ -582,144 +577,83 @@ void BSDetectionWidget::extract ()
       strucview->setExamined (-1);
       strucview->scene()->update ();
     }
+    if (verbose) writeDetectionResult ();
   }
+}
 
-  if (detector.isMultiSelection ())
+
+void BSDetectionWidget::displayNext (int dir)
+{
+  int size = (int) (detector.getBlurredSegments (1).size ());
+  if (size != 0)
   {
-    vector<BlurredSegment *> mbs = detector.getBlurredSegments (1);
-    vector<BlurredSegment *>::iterator it = mbs.begin ();
-    while (it != mbs.end ())
-    {
-      DigitalStraightSegment *dss = (*it)->getSegment ();
-      if (dss != NULL) 
-      {
-        vector<Pt2i> bnd;
-        dss->getBounds (bnd, 0, 0, width, height);
-        drawListOfPixels (bnd, Qt::green, painter);
-      }
-      it++;
-    }
+    exam = (exam + dir) % size;
+    if (strucview != NULL) strucview->setExamined (exam);
+    displayDetectionResult (true, exam);
   }
-  else
-  {
-    BlurredSegment *bs = detector.getBlurredSegment (1);
-    if (bs != NULL)
-    {
-      DigitalStraightSegment *dss = bs->getSegment ();
-      if (dss != NULL) 
-      {
-        vector<Pt2i> bnd;
-        dss->getBounds (bnd, 0, 0, width, height);
-        drawListOfPixels (bnd, Qt::green, painter);
-      }
-    }
-  }
-
-  update (QRect (QPoint (0, 0), QPoint (width, height)));
-  if (verbose && fixed) displayExtractionResult ();
-  fixed = false;
 }
 
 
-void BSDetectionWidget::extractAll ()
+void BSDetectionWidget::displaySavedSegments ()
 {
-  bool formerMultiMode = detector.isMultiSelection ();
-  if (! formerMultiMode) detector.switchMultiSelection ();
   augmentedImage = loadedImage;
   QPainter painter (&augmentedImage);
-  if (paintItBlack) painter.fillRect (0, 0, width, height, QBrush (Qt::black));
-  paintItBlack = false;
-
-  detector.detectAll ();
-
-  // Update auxiliary view
-  if (profileview != NULL)
-  {
-    profileview->buildScans (p1, p2);
-    profileview->scene()->update ();
-  }
-  if (accuview != NULL) accuview->scene()->update ();
-  if (strucview != NULL)
-  {
-    strucview->setExamined (-1);
-    strucview->scene()->update ();
-  }
-
-  // Update auxiliary view
-  if (strucview != NULL) strucview->scene()->update ();
-
-  vector<BlurredSegment *> mbs = detector.getBlurredSegments (1);
-  cout << mbs.size () << " blurred segments detected" << endl;
-  vector<BlurredSegment *>::iterator it = mbs.begin ();
-  while (it != mbs.end ())
+  if (! extractedSegments.empty ())
   {
-/*
-    DigitalStraightSegment *dss = (*it)->getSegment ();
-    if (dss != NULL) 
+    vector<ExtractedSegment>::iterator it = extractedSegments.begin ();
+    while (it != extractedSegments.end ())
     {
-      vector<Pt2i> bnd;
-      dss->getBounds (bnd, 0, 0, width, height);
-      drawListOfPixels (bnd, Qt::green, painter);
+      drawBlurredSegment (painter, it->bs);
+      drawSelection (painter, it->p1, it->p2);
+      it ++;
     }
-*/
-    drawListOfPixels ((*it)->getAllPoints (), Qt::green, painter);
-    it++;
   }
-
   update (QRect (QPoint (0, 0), QPoint (width, height)));
-  if (verbose && fixed) displayExtractionResult ();
-  fixed = false;
-  if (! formerMultiMode) detector.switchMultiSelection ();
-  exam = -1;
-
-  if (capture)
-  {
-    augmentedImage.save ("capture.png");
-    capture = false;
-  }
 }
 
 
-void BSDetectionWidget::displayNext (int dir)
+void BSDetectionWidget::saveExtractedSegment ()
 {
-  vector<BlurredSegment *> mbs = detector.getBlurredSegments (1);
-  if (mbs.empty ()) return;
-
-  augmentedImage = loadedImage;
-  QPainter painter (&augmentedImage);
-  exam = (exam + dir) % ((int) (mbs.size ()));
-
-  // Update auxiliary view
-  if (strucview != NULL)
+  if (detector.isMultiSelection ())
   {
-    strucview->setExamined (exam);
-    strucview->scene()->update ();
+    vector<BlurredSegment *> bss = detector.getBlurredSegments (1);
+    vector<BlurredSegment *>::const_iterator it = bss.begin ();
+    while (it != bss.end ())
+    {
+      ExtractedSegment es;
+      es.bs = *it++;
+      es.p1 = p1;
+      es.p2 = p2;
+      extractedSegments.push_back (es);
+    }
+    detector.preserveFormerBlurredSegments ();
   }
-
-  vector<BlurredSegment *>::iterator it = mbs.begin ();
-  QColor bsCol = Qt::blue;
-  int index = 0;
-  while (it != mbs.end ())
+  else
   {
-    if (index++ == exam) bsCol = Qt::green;
-    else bsCol = Qt::blue;
-/*
-    DigitalStraightSegment *dss = (*it)->getSegment ();
-    if (dss != NULL) 
+    BlurredSegment *bs = detector.getBlurredSegment (1);
+    if (bs != NULL)
     {
-      vector<Pt2i> bnd;
-      dss->getBounds (bnd, 0, 0, width, height);
-      drawListOfPixels (bnd, Qt::green, painter);
+      ExtractedSegment es;
+      es.bs = bs;
+      es.p1 = p1;
+      es.p2 = p2;
+      extractedSegments.push_back (es);
+      detector.preserveFormerBlurredSegment ();
     }
-*/
-    drawListOfPixels ((*it)->getAllPoints (), bsCol, painter);
-    it++;
   }
-  update (QRect (QPoint (0, 0), QPoint (width, height)));
 }
 
 
-void BSDetectionWidget::displayExtractionResult ()
+void BSDetectionWidget::clearSavedSegments ()
+{
+  vector<ExtractedSegment>::iterator it = extractedSegments.begin ();
+  while (it != extractedSegments.end ())
+    delete ((it++)->bs->getSegment ());
+  extractedSegments.clear ();
+}
+
+
+void BSDetectionWidget::writeDetectionResult ()
 {
   int res = detector.result ();
   if (res == BSDetector::RESULT_UNDETERMINED)
@@ -753,6 +687,36 @@ void BSDetectionWidget::displayExtractionResult ()
 }
 
 
+void BSDetectionWidget::extract (bool updateAll)
+{
+  exam = -1;
+  if (p1.equals (p2))
+  {
+    displayBackground ();
+    return;
+  }
+
+  detector.detectSelection (p1, p2);
+  displayDetectionResult (updateAll);
+}
+
+
+void BSDetectionWidget::extractAll ()
+{
+  udef = false;
+  exam = -1;
+  bool formerMultiMode = detector.isMultiSelection ();
+  if (! formerMultiMode) detector.switchMultiSelection ();
+
+  detector.detectAll ();
+  vector<BlurredSegment *> mbs = detector.getBlurredSegments (1);
+  cout << mbs.size () << " blurred segments detected" << endl;
+  displayDetectionResult (true);
+
+  if (! formerMultiMode) detector.switchMultiSelection ();
+}
+
+
 void BSDetectionWidget::alternateTest ()
 {
   if (p1.equals (p2))
@@ -771,7 +735,6 @@ void BSDetectionWidget::alternateTest ()
   else if (alternate == 2)
   {
   }
-//  extract (true);
 } 
 
 
@@ -785,7 +748,7 @@ void BSDetectionWidget::performanceTest ()
     for (int i = 0; i < 100; i++) detector.detectAll ();
     double diff = (clock () - start) / (double) CLOCKS_PER_SEC;
     cout << "Test run : " << diff << endl;
-    extract (true);
+    extract ();
   }
   else
   {
@@ -799,7 +762,7 @@ void BSDetectionWidget::performanceTest ()
     for (int i = 0; i < 1000; i++) detector.detect (p1, p2);
     double diff = (clock () - start) / (double) CLOCKS_PER_SEC;
     cout << "Test run : " << diff << endl;
-    extract (true);
+    extract ();
   }
 }
 
@@ -816,6 +779,6 @@ void BSDetectionWidget::localTest ()
   p1 = Pt2i (157, 125);
   p2 = Pt2i (165, 88);
 
-  extract (true);
+  extract ();
   cout << "Test run" << endl;
 }
diff --git a/Code/Seg/BSTools/bsdetectionwidget.h b/Code/Seg/BSTools/bsdetectionwidget.h
index d85c2d7..c29d359 100755
--- a/Code/Seg/BSTools/bsdetectionwidget.h
+++ b/Code/Seg/BSTools/bsdetectionwidget.h
@@ -148,31 +148,37 @@ protected:
 
 private:
  
-  /** Sensitiveness of segment max width parameter. */
-  static const int MAX_WIDTH_TUNING;
-  /** Sensitiveness of detection lacks parameter. */
-  static const int DETECTION_LACKS_TUNING;
   /** Default value for pen width. */
   static const int DEFAULT_PEN_WIDTH;
 
 
   /** Initial scan end points */
   Pt2i p1, p2;
-  /** Flag indicating if the stroke is completely defined. */
-  bool fixed;
-  /** Flag indicating whether extraction result should be displayed. */
-  bool verbose;
-  /** Flag indicating whether extraction result should be captured. */
-  bool capture;
-  /** Flag indicating whether no background should be displayed. */
-  bool paintItBlack;
-
-  /** Activation of alternate comparative tests (F8). */
-  int alternate;
-
+  /** Flag indicating if the detection is user defined. */
+  bool udef;
   /** Index of the examined blurred segment in a multi-selection. */
   int exam;
+  /** Activation of alternate comparative tests (F8). */
+  int alternate;
 
+  /** Color of user selections. */
+  QColor selectionColor;
+  /** Color of blurred segments. */
+  QColor bsColor;
+  /** Color of highlighted blurred segments. */
+  QColor bsHighColor;
+  /** Flag indicating whether blurred segments points are visible. */
+  bool bsPointsVisible;
+  /** Color of blurred segments bounds. */
+  QColor boundColor;
+  /** Color of highlighted blurred segments bounds. */
+  QColor boundHighColor;
+  /** Flag indicating whether blurred segments bounds are visible. */
+  bool bsBoundsVisible;
+  /** Flag indicating whether no background should be displayed. */
+  bool paintItBlack;
+  /** Flag indicating whether detection result should be output. */
+  bool verbose;
 
   /** Presently loaded image. */
   QImage loadedImage;
@@ -184,92 +190,122 @@ private:
   int width;
   /** Height of the present image. */
   int height;
+
   /** Blurred segment detector. */
   BSDetector detector;
+  /** Scanned profile graphics view. */
+  BSProfileView *profileview;
+  /** Filter accumulator view. */
+  BSAccumulatorView *accuview;
+  /** Blurred segment contents view. */
+  BSStructureView *strucview;
 
   /** Aggregation of segment extraction results with initial conditions. */
   struct ExtractedSegment
   {
     /** Extracted blurred segment. */
     BlurredSegment *bs;
-    /** Selected strock start point. */
+    /** Selection stroke start point. */
     Pt2i p1;
-    /** Selected stroke end point. */
+    /** Selection stroke end point. */
     Pt2i p2;
   };
-
   /** List of registred blurred segments. */
   vector<ExtractedSegment> extractedSegments;
 
-  /** Scanned profile graphics view. */
-  BSProfileView *profileview;
-  /** Filter accumulator view. */
-  BSAccumulatorView *accuview;
-  /** Blurred segment contents view. */
-  BSStructureView *strucview;
-
 
 
   /**
    * \brief Draws a list of points with the given color.
+   * @param painter Drawing device.
+   * @param pts List of points to be drawn.
+   * @param color Drawing color.
    */
-  void drawListOfPixels (vector<Pt2i> vectPixels,
-                         QColor color, QPainter &painter);
+  void drawPoints (QPainter &painter,
+                   vector<Pt2i> pts, QColor color);
 
   /**
    * \brief Draws a list of image pixels.
+   * @param painter Drawing device.
+   * @param pix List of pixels to be drawn.
    */
-  void drawListOfPixels (vector<Pt2i> vectPixels,
-                       QPainter &painter);
+  void drawPixels (QPainter &painter, vector<Pt2i> pix);
 
   /**
    * \brief Draws the line joining two points.
+   * @param painter Drawing device.
+   * @param from Line start position.
+   * @param to Line reach position.
+   * @param color Drawing color.
    */
-  void drawLine (const Pt2i from, const Pt2i to,
-                 QColor color, QPainter &painter);
+  void drawLine (QPainter &painter,
+                 const Pt2i from, const Pt2i to, QColor color);
 
   /**
-   * \brief Registers the last extracted blurred segment.
+   * \brief Draws a user selection.
+   * @param painter Drawing device.
+   * @param from Selection line start position.
+   * @param to Selection line reach position.
    */
-  void storeExtractedSegment ();
+  void drawSelection (QPainter &painter, const Pt2i from, const Pt2i to);
 
   /**
-   * \brief Displays the registred blurred segments.
+   * \brief Draws a blurred segment.
+   * @param painter Drawing device.
+   * @param bs Reference to the blurred segment to be drawn.
+   * @param high Flag indicated whether the blurred segment is highlighted.
    */
-  void displayExtractedSegments ();
+  void drawBlurredSegment (QPainter &painter,
+                           BlurredSegment *bs, bool high = false);
 
   /**
-   * \brief Clears off the already extracted segments.
+   * \brief Displays the window background (no detection).
    */
-  void clearExtractedSegments ();
+  void displayBackground ();
 
   /**
-   * \brief Displays the last extraction result.
+   * \brief Displays the result of a detection.
+   * @param aux Indicates if auxiliary views should be displayed.
+   * @param hnum Highlighted segment index (-1 if none).
    */
-  void displayExtractionResult ();
+  void displayDetectionResult (bool aux, int hnum = -1);
 
   /**
-   * \brief Detects a blurred segment under the selected stroke.
-   * @param withAllDisplay Indicates if all information about the extraction
-   *                       should be displayed.
+   * \brief Highlights the next blurred segment in multi-selection mode.
+   * @param dir Increment in the multi-selection.
    */
-  void extract (bool withAllDisplay);
+  void displayNext (int dir);
 
   /**
-   * \brief Detects and displays a blurred segment under the selected stroke.
+   * \brief Displays the saved blurred segments.
    */
-  void extract ();
+  void displaySavedSegments ();
 
   /**
-   * \brief Detects and displays all the blurred segment in the picture.
+   * \brief Registers the last extracted blurred segment.
    */
-  void extractAll ();
+  void saveExtractedSegment ();
 
   /**
-   * \brief Highlights the next blurred segment in multi-selection mode.
-   * @param dir Increment in the multi-selection.
+   * \brief Clears off the saved blurred segments.
    */
-  void displayNext (int dir);
+  void clearSavedSegments ();
+
+  /**
+   * \brief Outputs the last detection result.
+   */
+  void writeDetectionResult ();
+
+  /**
+   * \brief Detects and displays a blurred segment under the selected stroke.
+   * @param updateAll Indicates if the extraction result should be displayed.
+   */
+  void extract (bool updateAll = true);
+
+  /**
+   * \brief Detects and displays all the blurred segment in the picture.
+   */
+  void extractAll ();
 
 };
 #endif
diff --git a/Code/Seg/BlurredSegment/bsdetector.cpp b/Code/Seg/BlurredSegment/bsdetector.cpp
index 0b74219..d628c35 100755
--- a/Code/Seg/BlurredSegment/bsdetector.cpp
+++ b/Code/Seg/BlurredSegment/bsdetector.cpp
@@ -75,27 +75,9 @@ void BSDetector::setGradientMap (VMap *data)
 }
 
 
-void BSDetector::freeMultiSelection ()
-{
-  vector<BlurredSegment *>::iterator it = mbsini.begin ();
-  while (it != mbsini.end ()) delete (*it++);
-  mbsini.clear ();
-  it = mbsf.begin ();
-  while (it != mbsf.end ()) delete (*it++);
-  mbsf.clear ();
-}
-
-
 void BSDetector::detectAll ()
 {
-  // Deletes former blurred segments
-  vector<BlurredSegment *>::iterator it = mbsini.begin ();
-  while (it != mbsini.end ()) delete (*it++);
-  mbsini.clear ();
-  it = mbsf.begin ();
-  while (it != mbsf.end ()) delete (*it++);
-  mbsf.clear ();
-
+  freeMultiSelection ();
   gMap->setMasking (true);
 
   int width = gMap->getWidth ();
@@ -114,20 +96,28 @@ void BSDetector::detectAll ()
 }
 
 
-void BSDetector::multidetect (const Pt2i &p1, const Pt2i &p2)
+void BSDetector::detectSelection (const Pt2i &p1, const Pt2i &p2)
+{
+  freeMultiSelection ();
+  if (multiSelection)
+  {
+    gMap->setMasking (true);
+    runMultiDetection (p1, p2, p1.vectorTo (p2));
+    gMap->clearMask ();
+    gMap->setMasking (false);
+  }
+  else detect (p1, p2);
+}
+
+
+void BSDetector::freeMultiSelection ()
 {
-  // Deletes former blurred segments
   vector<BlurredSegment *>::iterator it = mbsini.begin ();
   while (it != mbsini.end ()) delete (*it++);
   mbsini.clear ();
   it = mbsf.begin ();
   while (it != mbsf.end ()) delete (*it++);
   mbsf.clear ();
-
-  gMap->setMasking (true);
-  runMultiDetection (p1, p2, p1.vectorTo (p2));
-  gMap->clearMask ();
-  gMap->setMasking (false);
 }
 
 
@@ -168,6 +158,7 @@ void BSDetector::detect (const Pt2i &p1, const Pt2i &p2, Pt2i *p0)
   bsini = NULL;
   if (bsf != NULL) delete bsf;
   bsf = NULL;
+
   if (p1.equals (p2)) return;
   Pt2i pt1 (p1);
   Pt2i pt2 (p2);
diff --git a/Code/Seg/BlurredSegment/bsdetector.h b/Code/Seg/BlurredSegment/bsdetector.h
index 38a6569..a0cabb6 100755
--- a/Code/Seg/BlurredSegment/bsdetector.h
+++ b/Code/Seg/BlurredSegment/bsdetector.h
@@ -69,11 +69,11 @@ public:
   void detectAll ();
 
   /**
-   * \brief Detects all blurred segments between two input points.
+   * \brief Detects blurred segments between two input points.
    * @param p1 First input point.
    * @param p2 Second input point.
    */
-  void multidetect (const Pt2i &p1, const Pt2i &p2);
+  void detectSelection (const Pt2i &p1, const Pt2i &p2);
 
   /**
    * \brief Detects a blurred segment between two input points.
@@ -106,14 +106,14 @@ public:
     return (step == 0 ? mbsini : mbsf); }
 
   /**
-   * \brief Resets the multi-selection list.
+   * \brief Avoids the deletion of the last extracted blurred segment.
    */
-  void freeMultiSelection ();
+  inline void preserveFormerBlurredSegment () { bsf = NULL; }
 
   /**
-   * \brief Avoids the deletion of the last extracted blurred segent.
+   * \brief Avoids the deletion of the last extracted blurred segments.
    */
-  inline void preserveFormerBlurredSegment () { bsf = NULL; }
+  inline void preserveFormerBlurredSegments () { mbsf.clear (); }
 
   /**
    * \brief Returns the input maximal width of the initial segment.
@@ -474,5 +474,10 @@ private :
   void runMultiDetection (const Pt2i &p1, const Pt2i &p2,
                           const Vr2i &dir);
 
+  /**
+   * \brief Resets the multi-selection list.
+   */
+  void freeMultiSelection ();
+
 };
 #endif
diff --git a/Methode/ctrl.tex b/Methode/ctrl.tex
index 4a9450c..caf4094 100755
--- a/Methode/ctrl.tex
+++ b/Methode/ctrl.tex
@@ -25,6 +25,8 @@
 \multicolumn{3}{|l|}{Contr\^ole de l'extraction :} \\
 u & \spa & Actualiser \\
 v && Afficher le r\'esultat \\
+a && Commute l'affichage des points des segments flous. \\
+A && Commute l'affichage des bords des segments flous. \\
 w && Consigne initiale d'\'epaisseur du segment flou \\
 h && Longueur tol\'er\'ee pour les sauts de d\'etection \\
 k && Taille minimale des segments d\'etect\'es \\
@@ -47,7 +49,7 @@ g && Commute la contrainte de connectivit\'e \\
 s && Commute l'aspect dynamique des scans \\
 o && Commute l'aspect directionel des scans \\
 x && Commute l'ajustement de la consigne d'\'epaisseur \\
-P && Demande la capture de la prochaine extraction \\
+P && Capture la fen\^etre principale \\
 1 && Commute la visu des segments (pixels) \\
 2 && Commute la visu de l'accumulateur \\
 3 && Commute la visu des profils \\
-- 
GitLab