From 937127020b9cf116d11828c54a2d92af60e6c33e Mon Sep 17 00:00:00 2001
From: even <philippe.even@loria.fr>
Date: Sat, 4 May 2019 16:10:39 +0200
Subject: [PATCH] Code interface up-to-date

---
 Code/FBSD/BSTools/bsdetectionwidget.cpp |  91 ++++---
 Code/FBSD/BSTools/bsrandomtester.cpp    |   6 +-
 Code/FBSD/BSTools/bsstructureitem.cpp   |   8 +-
 Code/FBSD/BSTools/extlines.cpp          |   6 +-
 Code/FBSD/BlurredSegment/bsdetector.cpp | 313 ++++++++++++------------
 Code/FBSD/BlurredSegment/bsdetector.h   | 127 +++++-----
 Code/FBSD/BlurredSegment/bstracker.cpp  |  58 +----
 Code/FBSD/BlurredSegment/bstracker.h    |  75 ++----
 Code/FBSD/ImageTools/absrat.cpp         |  26 +-
 Code/FBSD/ImageTools/absrat.h           |  45 ++--
 Code/FBSD/main.cpp                      |  12 +-
 Methode/ctrl.tex                        |   6 +-
 12 files changed, 350 insertions(+), 423 deletions(-)

diff --git a/Code/FBSD/BSTools/bsdetectionwidget.cpp b/Code/FBSD/BSTools/bsdetectionwidget.cpp
index ca0ccf1..0fb3b6a 100755
--- a/Code/FBSD/BSTools/bsdetectionwidget.cpp
+++ b/Code/FBSD/BSTools/bsdetectionwidget.cpp
@@ -718,15 +718,35 @@ void BSDetectionWidget::keyPressEvent (QKeyEvent *event)
       }
       else
       {
-        // Tunes the automatic detection grid resolution
-        detector.setAutoGridResolution (detector.getAutoGridResolution () +
+        // Tunes the sweeping step value for automatic detections
+        detector.setAutoSweepingStep (detector.getAutoSweepingStep () +
           (event->modifiers () & Qt::ShiftModifier ? -1 : 1));
-        cout << "Automatic detection grid resolution = "
-             << detector.getAutoGridResolution () << " pixels" << endl;
+        cout << "Stroke sweeping step for automatic detections = "
+             << detector.getAutoSweepingStep () << " pixels" << endl;
       }
       break;
 
     case Qt::Key_S :
+      if (event->modifiers () & Qt::ControlModifier)
+      {
+        // Switches the final size test of detected blurred segments
+        detector.switchFinalSizeTest ();
+        cout << "Final size test "
+             << (detector.isFinalSizeTestOn () ? "on" : "off") << endl;
+        extract ();
+      }
+      else
+      {
+        // Tunes the detector assigned thickness
+        detector.setAssignedThickness (detector.finalSizeMinValue () +
+          (event->modifiers () & Qt::ShiftModifier ? -1 : 1));
+        cout << "Minimal size of detected blurred segments = "
+             << detector.finalSizeMinValue () << " points" << endl;
+        extract ();
+      }
+      break;
+
+    case Qt::Key_T :
       if (event->modifiers () & Qt::ControlModifier)
       {
         // Switches the interruption handling
@@ -746,19 +766,6 @@ void BSDetectionWidget::keyPressEvent (QKeyEvent *event)
       }
       break;
 
-    case Qt::Key_T :
-      if (event->modifiers () & Qt::ControlModifier)
-      {
-        // Switches the progressive thinning
-        detector.toggleThinning ();
-        if (detector.isThinningOn () && detector.isThickenningOn ())
-          detector.toggleThickenning ();
-        cout << "Thinning "
-             << (detector.isThinningOn () ? "on" : "off") << endl;
-        extract ();
-      }
-      break;
-
     case Qt::Key_U :
       if (event->modifiers () & Qt::ControlModifier)
       {
@@ -814,11 +821,11 @@ void BSDetectionWidget::keyPressEvent (QKeyEvent *event)
       }
       else
       {
-        // Tunes the assigned max width for fast tracks
-        detector.setFineTracksMaxWidth (detector.fineTracksMaxWidth () +
+        // Tunes the assigned thickness to detector
+        detector.setAssignedThickness (detector.assignedThickness () +
           (event->modifiers () & Qt::ShiftModifier ? -1 : 1));
-        cout << "Initial assigned width = "
-             << detector.fineTracksMaxWidth () << endl;
+        cout << "Assigned width = "
+             << detector.assignedThickness () << endl;
         extract ();
       }
       break;
@@ -844,20 +851,20 @@ void BSDetectionWidget::keyPressEvent (QKeyEvent *event)
     case Qt::Key_Z :
       if (event->modifiers () & Qt::ControlModifier)
       {
-        // Switches the thickenning control
-        detector.toggleThickenning ();
-        if (detector.isThickenningOn () && detector.isThinningOn ())
-          detector.toggleThinning ();
-        cout << "Assigned width control "
-             << (detector.isThickenningOn () ? "on" : "off") << endl;
+        // Switches the assigned thickness control
+        detector.toggleAssignedThicknessControl ();
+        cout << "Assigned thickness control "
+             << (detector.isAssignedThicknessControlOn () ? "on" : "off")
+             << endl;
         extract ();
       }
       else
       {
-        // Tunes the thickenning limit
-        detector.incThickenningLimit (
+        // Tunes the assigned thickness control delay
+        detector.incAssignedThicknessControlDelay (
           (event->modifiers () & Qt::ShiftModifier) ? -1 : 1);
-        cout << "Thickenning limit = " << detector.getThickenningLimit ()
+        cout << "Assigned thickness control delay = "
+             << detector.getAssignedThicknessControlDelay ()
              << " pixels" << endl;
         extract ();
       }
@@ -899,14 +906,6 @@ void BSDetectionWidget::keyPressEvent (QKeyEvent *event)
         yorkview = new BSYorkView (&loadedImage, &detector);
       yorkview->show ();
       break;
-
-    case Qt::Key_Period :
-      // Switches the thickenning control
-      detector.switchStrict ();
-      cout << "Assigned strict (leaning lines) thickness control "
-           << (detector.isStrictOn () ? "on" : "off") << endl;
-      extract ();
-      break;
 // DEV OUT
 
     case Qt::Key_Plus :
@@ -994,9 +993,9 @@ void BSDetectionWidget::keyPressEvent (QKeyEvent *event)
       break;
 
     case Qt::Key_6 :
-      detector.switchDetector ();
-      cout << (detector.oldDetectorOn () ?
-               "Old detector set" : "New detector set") << endl;
+      detector.setStaticDetector (! (detector.staticDetectorOn ()));
+      cout << (detector.staticDetectorOn () ?
+               "Static detector set" : "Static detector released") << endl;
       extract ();
       break;
 
@@ -1526,9 +1525,8 @@ void BSDetectionWidget::alternateTest ()
   outf << width << endl;
   outf << height << endl;
 
-  if (detector.oldDetectorOn ()) detector.switchDetector ();
-  cout << "Performance test on "
-       << (detector.oldDetectorOn () ? "old" : "new") << " detector" << endl;
+  detector.setStaticDetector (false);
+  cout << "Performance test on new detector" << endl;
   clock_t start = clock ();
   for (int i = 0; i < nbruns; i++) detector.detectAll ();
   diff1 = (clock () - start) / (double) CLOCKS_PER_SEC;
@@ -1575,9 +1573,8 @@ void BSDetectionWidget::alternateTest ()
   lcount = 0;
   wtotal = 0.;
   lwtotal = 0.;
-  detector.switchDetector ();
-  cout << "Performance test on "
-       << (detector.oldDetectorOn () ? "old" : "new") << " detector" << endl;
+  detector.setStaticDetector (true);
+  cout << "Performance test on old detector" << endl;
   start = clock ();
   for (int i = 0; i < nbruns; i++) detector.detectAll ();
   diff1 = (clock () - start) / (double) CLOCKS_PER_SEC;
diff --git a/Code/FBSD/BSTools/bsrandomtester.cpp b/Code/FBSD/BSTools/bsrandomtester.cpp
index 4cde274..06410b8 100755
--- a/Code/FBSD/BSTools/bsrandomtester.cpp
+++ b/Code/FBSD/BSTools/bsrandomtester.cpp
@@ -72,12 +72,12 @@ BSRandomTester::BSRandomTester ()
   detectors = new BSDetector[nbdets];
   for (int i = 0; i < nbdets; i++)
   {
-    detectors[i].setFineTracksMaxWidth (smaxwidth + swmargin);
+    detectors[i].setAssignedThickness (smaxwidth + swmargin);
     if (! detectors[i].isFinalLengthTestOn ())
       detectors[i].switchFinalLengthTest ();
   }
-  if (! detectors[0].oldDetectorOn ()) detectors[0].switchDetector ();
-  if (detectors[1].oldDetectorOn ()) detectors[1].switchDetector ();
+  detectors[0].setStaticDetector (true);
+  detectors[1].setStaticDetector (false);
   names = new QString[nbdets];
   names[0] = "old";
   names[1] = "new";
diff --git a/Code/FBSD/BSTools/bsstructureitem.cpp b/Code/FBSD/BSTools/bsstructureitem.cpp
index 38d3000..ce53886 100755
--- a/Code/FBSD/BSTools/bsstructureitem.cpp
+++ b/Code/FBSD/BSTools/bsstructureitem.cpp
@@ -135,13 +135,13 @@ void BSStructureItem::paintBlurredSegment (QPainter *painter, int step)
     {
       initText (painter);
       if (dss != NULL)
-        addText (painter, QString ("Segment width = ")
+        addText (painter, QString ("Segment thickness = ")
                  + QString::number (dss->width ()) + QString ("/")
                  + QString::number (dss->period ()) + QString (" = ")
                  + QString::number (dss->width () / (double) dss->period ()));
-      else addText (painter, QString ("Segment width = 0"));
-      addText (painter, QString ("W : fine tracks max width = ")
-               + QString::number (det->fineTracksMaxWidth ()));
+      else addText (painter, QString ("Segment thickness = 0"));
+      addText (painter, QString ("W : assigned thickness = ")
+               + QString::number (det->assignedThickness ()));
       addText (painter, QString ("L : output BS min size = ")
                + QString::number (det->getBSminSize ()));
       addText (painter, QString ("H : pixel lack tolerence = ")
diff --git a/Code/FBSD/BSTools/extlines.cpp b/Code/FBSD/BSTools/extlines.cpp
index 0cb8240..8baeb16 100755
--- a/Code/FBSD/BSTools/extlines.cpp
+++ b/Code/FBSD/BSTools/extlines.cpp
@@ -300,11 +300,11 @@ void ExtLines::stats (const QImage &im)
                                      VMap::TYPE_SOBEL_5X5));
   if (MIN_LENGTH != 0.)
   {
-    if (! detector.isFinalSpreadTestOn ()) detector.switchFinalSpreadTest ();
-    detector.setFinalSpreadMinLength ((int) (MIN_LENGTH + 0.5));
+    if (! detector.isFinalSizeTestOn ()) detector.switchFinalSizeTest ();
+    detector.setFinalSizeMinValue ((int) (MIN_LENGTH + 0.5));
   }
   else
-    if (detector.isFinalSpreadTestOn ()) detector.switchFinalSpreadTest ();
+    if (detector.isFinalSizeTestOn ()) detector.switchFinalSizeTest ();
   detector.detectAll ();
   vector<BlurredSegment *> bss = detector.getBlurredSegments ();
   if (loaded)
diff --git a/Code/FBSD/BlurredSegment/bsdetector.cpp b/Code/FBSD/BlurredSegment/bsdetector.cpp
index 2377d33..d3652fd 100755
--- a/Code/FBSD/BlurredSegment/bsdetector.cpp
+++ b/Code/FBSD/BlurredSegment/bsdetector.cpp
@@ -2,7 +2,7 @@
 //#include "linespacefilter.h"
 
 
-const string BSDetector::VERSION = "0.2.1";
+const std::string BSDetector::VERSION = "0.2.1";
 const int BSDetector::STEP_FINAL = 0;
 const int BSDetector::STEP_INITIAL = 1;
 const int BSDetector::STEP_PRELIM = 2;
@@ -24,13 +24,14 @@ const int BSDetector::RESULT_FINAL_TOO_SMALL = 24;
 const int BSDetector::RESULT_FINAL_TOO_MANY_OUTLIERS = 25;
 
 const int BSDetector::DEFAULT_FAST_TRACK_SCAN_WIDTH = 16;
-const int BSDetector::DEFAULT_FINE_TRACK_MAX_WIDTH = 3;
+const int BSDetector::DEFAULT_ASSIGNED_THICKNESS = 3;
 const int BSDetector::DEFAULT_FAST_TRACK_MAX_MARGIN = 2;
 
 const int BSDetector::DEFAULT_BS_MIN_SIZE = 5;
 const int BSDetector::ABSOLUTE_BS_MIN_SIZE = 3;
+const int BSDetector::DEFAULT_FINAL_MIN_SIZE = 10;
 const int BSDetector::DEFAULT_CONNECT_MIN_SIZE = 5;
-const int BSDetector::DEFAULT_AUTO_RESOLUTION = 15;
+const int BSDetector::DEFAULT_AUTO_SWEEPING_STEP = 15;
 const int BSDetector::PRELIM_MIN_HALF_WIDTH = 10;
 
 
@@ -38,7 +39,7 @@ BSDetector::BSDetector ()
 {
   gMap = NULL;
 
-  fmaxWidth = DEFAULT_FINE_TRACK_MAX_WIDTH;
+  inThick = DEFAULT_ASSIGNED_THICKNESS;
   imaxMargin = DEFAULT_FAST_TRACK_MAX_MARGIN;
 
   prelimDetectionOn = false;
@@ -48,10 +49,10 @@ BSDetector::BSDetector ()
   bst2 = new BSTracker ();
   bstold = new BSTracker ();
   if (bstold->dynamicScansOn ()) bstold->toggleDynamicScans ();
-  if (bstold->isThinningOn ()) bstold->toggleThinning ();
-  if (bstold->isThickenningOn ()) bstold->toggleThickenning ();
+  if (bstold->isAssignedThicknessControlOn ())
+    bstold->toggleAssignedThicknessControl ();
 
-  oldp = false;
+  staticDetOn = false;
   prefilteringOn = false;
   //lsf1 = (prefilteringOn ? new LineSpaceFilter () : NULL);
   lsf1 = (prefilteringOn ? new BSFilter () : NULL);
@@ -68,12 +69,12 @@ BSDetector::BSDetector ()
   densityTestOn = true;
   finalDensityTestOn = false;
   finalLengthTestOn = false;
-  finalSpreadTestOn = true;
-  finalSpreadMin = 10;
+  finalSizeTestOn = true;
+  finalSizeMinVal = DEFAULT_FINAL_MIN_SIZE;
   // nbSmallBS = 0;
   multiSelection = false;
   autodet = false;
-  autoResol = DEFAULT_AUTO_RESOLUTION;
+  autoSweepingStep = DEFAULT_AUTO_SWEEPING_STEP;
   maxtrials = 0;
   nbtrials = 0;
 
@@ -120,13 +121,13 @@ void BSDetector::detectAll ()
   // nbSmallBS = 0;
   int width = gMap->getWidth ();
   int height = gMap->getHeight ();
-  for (int x = width / 2; isnext && x > 0; x -= autoResol)
+  for (int x = width / 2; isnext && x > 0; x -= autoSweepingStep)
     isnext = runMultiDetection (Pt2i (x, 0), Pt2i (x, height - 1));
-  for (int x = width / 2 + autoResol; isnext && x < width - 1; x += autoResol)
+  for (int x = width / 2 + autoSweepingStep; isnext && x < width - 1; x += autoSweepingStep)
     isnext = runMultiDetection (Pt2i (x, 0), Pt2i (x, height - 1));
-  for (int y = height / 2; isnext && y > 0; y -= autoResol)
+  for (int y = height / 2; isnext && y > 0; y -= autoSweepingStep)
     isnext = runMultiDetection (Pt2i (0, y), Pt2i (width - 1, y));
-  for (int y = height / 2 + autoResol; isnext && y < height - 1; y += autoResol)
+  for (int y = height / 2 + autoSweepingStep; isnext && y < height - 1; y += autoSweepingStep)
     isnext = runMultiDetection (Pt2i (0, y), Pt2i (width - 1, y));
   if (maxtrials > (int) (mbsf.size ())) maxtrials = 0;
   // cout << nbSmallBS << " petits BS elimines" << endl;
@@ -148,32 +149,32 @@ void BSDetector::detectAllWithBalancedXY ()
   int width = gMap->getWidth ();
   int height = gMap->getHeight ();
   int xg = width / 2, yb = height / 2;
-  int xd = xg + autoResol, yh = yb + autoResol;
+  int xd = xg + autoSweepingStep, yh = yb + autoSweepingStep;
   bool agauche = true, enbas = true, adroite = true, enhaut = true;
   while (isnext && (agauche || enbas || adroite || enhaut))
   {
     if (agauche)
     {
       isnext = runMultiDetection (Pt2i (xg, 0), Pt2i (xg, height - 1));
-      xg -= autoResol;
+      xg -= autoSweepingStep;
       if (xg <= 0) agauche = false;
     }
     if (isnext && enbas)
     {
       isnext = runMultiDetection (Pt2i (0, yb), Pt2i (width - 1, yb));
-      yb -= autoResol;
+      yb -= autoSweepingStep;
       if (yb <= 0) enbas = false;
     }
     if (isnext && adroite)
     {
       isnext = runMultiDetection (Pt2i (xd, 0), Pt2i (xd, height - 1));
-      xd += autoResol;
+      xd += autoSweepingStep;
       if (xd >= width - 1) adroite = false;
     }
     if (isnext && enhaut)
     {
       isnext = runMultiDetection (Pt2i (0, yh), Pt2i (width - 1, yh));
-      yh += autoResol;
+      yh += autoSweepingStep;
       if (yh >= height - 1) enhaut = false;
     }
   }
@@ -199,7 +200,7 @@ void BSDetector::detectSelection (const Pt2i &p1, const Pt2i &p2)
     gMap->setMasking (false);
   }
   else
-    if (oldp) resultValue = olddetect (p1, p2);
+    if (staticDetOn) resultValue = staticDetect (p1, p2);
     else resultValue = detect (p1, p2);
 }
 
@@ -236,7 +237,7 @@ bool BSDetector::runMultiDetection (const Pt2i &p1, const Pt2i &p2)
       while (isnext && edgeDirection >= -1)
       {
         int res = RESULT_VOID;
-        if (oldp) res = olddetect (p1, p2, true, ptstart);
+        if (staticDetOn) res = staticDetect (p1, p2, true, ptstart);
         else res = detect (p1, p2, true, ptstart);
         if (res == RESULT_OK)
         {
@@ -255,8 +256,8 @@ bool BSDetector::runMultiDetection (const Pt2i &p1, const Pt2i &p2)
 }
 
 
-int BSDetector::olddetect (const Pt2i &p1, const Pt2i &p2,
-                           bool centralp, const Pt2i &pc)
+int BSDetector::detect (const Pt2i &p1, const Pt2i &p2,
+                        bool centralp, const Pt2i &pc)
 {
   // Entry check
   //------------
@@ -264,23 +265,61 @@ int BSDetector::olddetect (const Pt2i &p1, const Pt2i &p2,
       || ((! centralp) && p1.chessboard (p2) < BSTracker::MIN_SCAN))
     return RESULT_VOID;
 
+
   // Clearance
   //----------
+  if (prelimDetectionOn) bst0->clear ();
   bst1->clear ();
   bst2->clear ();
+  if (prefilteringOn) lsf1->clear ();
+  if (filteringOn) lsf2->clear ();
+  if (bspre != NULL) delete bspre;
+  bspre = NULL;
   if (bsini != NULL) delete bsini;
   bsini = NULL;
   if (bsf != NULL) delete bsf;
   bsf = NULL;
 
-  inip1.set (p1);
-  inip2.set (p2);
-  iniwidth = (centralp ? DEFAULT_FAST_TRACK_SCAN_WIDTH : 0);
-  inipc.set (pc);
+  prep1.set (p1);
+  prep2.set (p2);
+  prewidth = (centralp ? DEFAULT_FAST_TRACK_SCAN_WIDTH : 0);
+  prepc.set (pc);
+
+  // Preliminary based on highest gradient without orientation constraint
+  //---------------------------------------------------------------------
+  if (prelimDetectionOn)
+  {
+    bspre = bst0->fastTrack (inThick + imaxMargin,
+                             prep1, prep2, prewidth, prepc);
+    if (bspre == NULL || bspre->size () < bsMinSize)
+      return (bspre == NULL ? RESULT_PRELIM_NO_DETECTION
+                            : RESULT_PRELIM_TOO_FEW);
+
+    Vr2i v0 = bspre->getSupportVector ();
+    int l = v0.chessboard ();
+    if (l != 0)
+    {
+      Pt2i pcentral = bspre->getSegment()->centerOfIntersection (prep1, prep2);
+      int detw = 2 * (1 + bspre->minimalWidth().floor ());
+      if (detw < PRELIM_MIN_HALF_WIDTH) detw = PRELIM_MIN_HALF_WIDTH;
+      int dx = (int) ((v0.y () * detw) / l);
+      int dy = (int) (- (v0.x () * detw) / l);
+      inip1 = Pt2i (pcentral.x () + dx, pcentral.y () + dy);
+      inip2 = Pt2i (pcentral.x () - dx, pcentral.y () - dy);
+      iniwidth = 0;
+    }
+  }
+  else
+  {
+    inip1.set (p1);
+    inip2.set (p2);
+    iniwidth = (centralp ? DEFAULT_FAST_TRACK_SCAN_WIDTH : 0);
+    inipc.set (pc);
+  }
 
   // Initial detection based on highest gradient without orientation constraint
   //---------------------------------------------------------------------------
-  bsini = bst1->fastTrack (DEFAULT_FAST_TRACK_SCAN_WIDTH / 4,
+  bsini = bst1->fastTrack (inThick + imaxMargin,
                            inip1, inip2, iniwidth, inipc);
   if (bsini == NULL || bsini->size () < bsMinSize)
     return (bsini == NULL ? RESULT_INITIAL_NO_DETECTION
@@ -288,7 +327,6 @@ int BSDetector::olddetect (const Pt2i &p1, const Pt2i &p2,
 
   // Density test
   //-------------
-/*
   if (densityTestOn)
   {
     DigitalStraightLine mydsl (inip1, inip2, DigitalStraightLine::DSL_NAIVE);
@@ -299,14 +337,27 @@ int BSDetector::olddetect (const Pt2i &p1, const Pt2i &p2,
     if (bsini->size () < expansion / 2)
       return RESULT_INITIAL_TOO_SPARSE;
   }
-*/
+
+  // Filtering the initial segment
+  //------------------------------
+  if (prefilteringOn)
+  {
+    BlurredSegment *fbs = lsf1->filter (bsini);
+    if (fbs != NULL)
+    {
+      delete bsini;
+      bsini = fbs;
+    }
+    if (bsini->size () < bsMinSize)
+      return RESULT_INITIAL_TOO_MANY_OUTLIERS;
+  }
 
   // Orientation test for automatic extractions
   //-------------------------------------------
   Vr2i bsinidir = bsini->getSupportVector();
   if (bsinidir.orientedAs (inip1.vectorTo (inip2)))
     return RESULT_INITIAL_CLOSE_ORIENTATION;
-
+  
   // Gradient reference selection
   //-----------------------------
   Pt2i pCenter = bsini->getCenter ();
@@ -317,38 +368,30 @@ int BSDetector::olddetect (const Pt2i &p1, const Pt2i &p2,
   //-----------------------------
   if (recenteringOn)
     pCenter = bsini->getSegment()->centerOfIntersection (inip1, inip2);
+  int bswidth = inThick;
+  if (fittingOn)
+  {
+    DigitalStraightSegment *dss = bsini->getSegment ();
+    if (dss != NULL)
+      bswidth = 1 + dss->width () / dss->period ();
+  }
 
   // Finer detection based on gradient maxima with orientation constraint
   //---------------------------------------------------------------------
-  bsf = bstold->fineTrack (fmaxWidth, pCenter, bsinidir,
-                           4 * fmaxWidth, gRef);
+  bsf = bst2->fineTrack (bswidth, pCenter, bsinidir, 2 * bswidth, gRef);
   if (bsf == NULL || bsf->size () < bsMinSize)
     return (bsf == NULL ? RESULT_FINAL_NO_DETECTION : RESULT_FINAL_TOO_FEW);
 
-  // Scan recentering and fitting
-  //-----------------------------
-  pCenter = bsini->getCenter ();
-  if (recenteringOn)
-    pCenter = bsf->getSegment()->centerOfIntersection (inip1, inip2);
-
-  // Third detection based on gradient maxima with orientation constraint
-  //---------------------------------------------------------------------
-  BlurredSegment *bsf2 = bstold->fineTrack (fmaxWidth,
-                                            pCenter, bsf->getSupportVector(),
-                                            4 * fmaxWidth, gRef);
-  if (bsf2 == NULL || bsf2->size () < bsMinSize)
+  // Size test
+  //------------
+  if (finalSizeTestOn)
   {
-    if (bsf2 != NULL)
+    // DigitalStraightSegment *dss = bsf->getSegment ();
+    if ((int) (bsf->getAllPoints().size ()) < finalSizeMinVal)
     {
-      delete bsf2;
-      return RESULT_FINAL_TOO_FEW;
+      // nbSmallBS ++;
+      return RESULT_FINAL_TOO_SMALL;
     }
-    else return RESULT_FINAL_NO_DETECTION;
-  }
-  else
-  {
-    delete bsf;
-    bsf = bsf2;
   }
 
   // Length test
@@ -356,8 +399,9 @@ int BSDetector::olddetect (const Pt2i &p1, const Pt2i &p2,
   if (finalLengthTestOn)
   {
     DigitalStraightSegment *dss = bsf->getSegment ();
-    if (dss == NULL || (int) (bsf->getAllPoints().size ())
-                       < (10 * dss->period ()) / dss->width ())
+    if ((int) (bsf->getAllPoints().size ())
+        < (3 * dss->width ()) / dss->period ())
+    // if ((int) (bsf->getAllPoints().size ()) < 10)
       return RESULT_FINAL_TOO_SPARSE;
   }
 
@@ -370,12 +414,12 @@ int BSDetector::olddetect (const Pt2i &p1, const Pt2i &p2,
                  - mydsl.manhattan (bsf->getLastLeft ());
     if (mydrlf < 0) mydrlf = -mydrlf; // Case of horizontal P1P2
     int expansion = 1 + mydrlf;
-    if (bsf->size () < expansion / 2)
+    if (expansion < 20 && bsf->size () < (expansion * 4) / 5)
       return RESULT_FINAL_TOO_SPARSE;
   }
 
-  // Connected components analysis
-  //------------------------------
+  // Connected components analysis */
+  //------------------------------*/
   if (ccOn)
   {
     int bsccp = bsf->countOfConnectedPoints (ccMinSize);
@@ -384,17 +428,31 @@ int BSDetector::olddetect (const Pt2i &p1, const Pt2i &p2,
       return RESULT_FINAL_TOO_SPARSE;
 
 /*
-    if (bssize < 20 || bsf->countOfConnectedComponents (bssize / 4) == 0)
+    if (bssize < 20 || bsf->countOfConnectedComponents (bssize / 2) == 0)
       return RESULT_FINAL_TOO_SPARSE;
 */
   }
 
+
+  // Final filtering
+  //----------------
+  if (filteringOn)
+  {
+    BlurredSegment *fbsf = lsf2->filter (bsf);
+    if (fbsf != NULL)
+    {
+      delete bsf;
+      bsf = fbsf;
+    }
+    else return RESULT_FINAL_TOO_MANY_OUTLIERS;
+  }
+
   return RESULT_OK;
 }
 
 
-int BSDetector::detect (const Pt2i &p1, const Pt2i &p2,
-                        bool centralp, const Pt2i &pc)
+int BSDetector::staticDetect (const Pt2i &p1, const Pt2i &p2,
+                           bool centralp, const Pt2i &pc)
 {
   // Entry check
   //------------
@@ -402,61 +460,23 @@ int BSDetector::detect (const Pt2i &p1, const Pt2i &p2,
       || ((! centralp) && p1.chessboard (p2) < BSTracker::MIN_SCAN))
     return RESULT_VOID;
 
-
   // Clearance
   //----------
-  if (prelimDetectionOn) bst0->clear ();
   bst1->clear ();
   bst2->clear ();
-  if (prefilteringOn) lsf1->clear ();
-  if (filteringOn) lsf2->clear ();
-  if (bspre != NULL) delete bspre;
-  bspre = NULL;
   if (bsini != NULL) delete bsini;
   bsini = NULL;
   if (bsf != NULL) delete bsf;
   bsf = NULL;
 
-  prep1.set (p1);
-  prep2.set (p2);
-  prewidth = (centralp ? DEFAULT_FAST_TRACK_SCAN_WIDTH : 0);
-  prepc.set (pc);
-
-  // Preliminary based on highest gradient without orientation constraint
-  //---------------------------------------------------------------------
-  if (prelimDetectionOn)
-  {
-    bspre = bst0->fastTrack (fmaxWidth + imaxMargin,
-                             prep1, prep2, prewidth, prepc);
-    if (bspre == NULL || bspre->size () < bsMinSize)
-      return (bspre == NULL ? RESULT_PRELIM_NO_DETECTION
-                            : RESULT_PRELIM_TOO_FEW);
-
-    Vr2i v0 = bspre->getSupportVector ();
-    int l = v0.chessboard ();
-    if (l != 0)
-    {
-      Pt2i pcentral = bspre->getSegment()->centerOfIntersection (prep1, prep2);
-      int detw = 2 * (1 + bspre->minimalWidth().floor ());
-      if (detw < PRELIM_MIN_HALF_WIDTH) detw = PRELIM_MIN_HALF_WIDTH;
-      int dx = (int) ((v0.y () * detw) / l);
-      int dy = (int) (- (v0.x () * detw) / l);
-      inip1 = Pt2i (pcentral.x () + dx, pcentral.y () + dy);
-      inip2 = Pt2i (pcentral.x () - dx, pcentral.y () - dy);
-      iniwidth = 0;
-    }
-  }
-  else
-  {
-    inip1.set (p1);
-    inip2.set (p2);
-    iniwidth = (centralp ? DEFAULT_FAST_TRACK_SCAN_WIDTH : 0);
-    inipc.set (pc);
-  }
+  inip1.set (p1);
+  inip2.set (p2);
+  iniwidth = (centralp ? DEFAULT_FAST_TRACK_SCAN_WIDTH : 0);
+  inipc.set (pc);
 
   // Initial detection based on highest gradient without orientation constraint
   //---------------------------------------------------------------------------
-  bsini = bst1->fastTrack (fmaxWidth + imaxMargin,
+  bsini = bst1->fastTrack (DEFAULT_FAST_TRACK_SCAN_WIDTH / 4,
                            inip1, inip2, iniwidth, inipc);
   if (bsini == NULL || bsini->size () < bsMinSize)
     return (bsini == NULL ? RESULT_INITIAL_NO_DETECTION
@@ -464,6 +484,7 @@ int BSDetector::detect (const Pt2i &p1, const Pt2i &p2,
 
   // Density test
   //-------------
+/*
   if (densityTestOn)
   {
     DigitalStraightLine mydsl (inip1, inip2, DigitalStraightLine::DSL_NAIVE);
@@ -474,27 +495,14 @@ int BSDetector::detect (const Pt2i &p1, const Pt2i &p2,
     if (bsini->size () < expansion / 2)
       return RESULT_INITIAL_TOO_SPARSE;
   }
-
-  // Filtering the initial segment
-  //------------------------------
-  if (prefilteringOn)
-  {
-    BlurredSegment *fbs = lsf1->filter (bsini);
-    if (fbs != NULL)
-    {
-      delete bsini;
-      bsini = fbs;
-    }
-    if (bsini->size () < bsMinSize)
-      return RESULT_INITIAL_TOO_MANY_OUTLIERS;
-  }
+*/
 
   // Orientation test for automatic extractions
   //-------------------------------------------
   Vr2i bsinidir = bsini->getSupportVector();
   if (bsinidir.orientedAs (inip1.vectorTo (inip2)))
     return RESULT_INITIAL_CLOSE_ORIENTATION;
-  
+
   // Gradient reference selection
   //-----------------------------
   Pt2i pCenter = bsini->getCenter ();
@@ -505,30 +513,38 @@ int BSDetector::detect (const Pt2i &p1, const Pt2i &p2,
   //-----------------------------
   if (recenteringOn)
     pCenter = bsini->getSegment()->centerOfIntersection (inip1, inip2);
-  int bswidth = fmaxWidth;
-  if (fittingOn)
-  {
-    DigitalStraightSegment *dss = bsini->getSegment ();
-    if (dss != NULL)
-      bswidth = 1 + dss->width () / dss->period ();
-  }
 
   // Finer detection based on gradient maxima with orientation constraint
   //---------------------------------------------------------------------
-  bsf = bst2->fineTrack (bswidth, pCenter, bsinidir, 2 * bswidth, gRef);
+  bsf = bstold->fineTrack (inThick, pCenter, bsinidir,
+                           4 * inThick, gRef);
   if (bsf == NULL || bsf->size () < bsMinSize)
     return (bsf == NULL ? RESULT_FINAL_NO_DETECTION : RESULT_FINAL_TOO_FEW);
 
-  // Spread test
-  //------------
-  if (finalSpreadTestOn)
+  // Scan recentering and fitting
+  //-----------------------------
+  pCenter = bsini->getCenter ();
+  if (recenteringOn)
+    pCenter = bsf->getSegment()->centerOfIntersection (inip1, inip2);
+
+  // Third detection based on gradient maxima with orientation constraint
+  //---------------------------------------------------------------------
+  BlurredSegment *bsf2 = bstold->fineTrack (inThick,
+                                            pCenter, bsf->getSupportVector(),
+                                            4 * inThick, gRef);
+  if (bsf2 == NULL || bsf2->size () < bsMinSize)
   {
-    // DigitalStraightSegment *dss = bsf->getSegment ();
-    if ((int) (bsf->getAllPoints().size ()) < finalSpreadMin)
+    if (bsf2 != NULL)
     {
-      // nbSmallBS ++;
-      return RESULT_FINAL_TOO_SMALL;
+      delete bsf2;
+      return RESULT_FINAL_TOO_FEW;
     }
+    else return RESULT_FINAL_NO_DETECTION;
+  }
+  else
+  {
+    delete bsf;
+    bsf = bsf2;
   }
 
   // Length test
@@ -536,9 +552,8 @@ int BSDetector::detect (const Pt2i &p1, const Pt2i &p2,
   if (finalLengthTestOn)
   {
     DigitalStraightSegment *dss = bsf->getSegment ();
-    if ((int) (bsf->getAllPoints().size ())
-        < (3 * dss->width ()) / dss->period ())
-    // if ((int) (bsf->getAllPoints().size ()) < 10)
+    if (dss == NULL || (int) (bsf->getAllPoints().size ())
+                       < (10 * dss->period ()) / dss->width ())
       return RESULT_FINAL_TOO_SPARSE;
   }
 
@@ -551,12 +566,12 @@ int BSDetector::detect (const Pt2i &p1, const Pt2i &p2,
                  - mydsl.manhattan (bsf->getLastLeft ());
     if (mydrlf < 0) mydrlf = -mydrlf; // Case of horizontal P1P2
     int expansion = 1 + mydrlf;
-    if (expansion < 20 && bsf->size () < (expansion * 4) / 5)
+    if (bsf->size () < expansion / 2)
       return RESULT_FINAL_TOO_SPARSE;
   }
 
-  // Connected components analysis */
-  //------------------------------*/
+  // Connected components analysis
+  //------------------------------
   if (ccOn)
   {
     int bsccp = bsf->countOfConnectedPoints (ccMinSize);
@@ -565,25 +580,11 @@ int BSDetector::detect (const Pt2i &p1, const Pt2i &p2,
       return RESULT_FINAL_TOO_SPARSE;
 
 /*
-    if (bssize < 20 || bsf->countOfConnectedComponents (bssize / 2) == 0)
+    if (bssize < 20 || bsf->countOfConnectedComponents (bssize / 4) == 0)
       return RESULT_FINAL_TOO_SPARSE;
 */
   }
 
-
-  // Final filtering
-  //----------------
-  if (filteringOn)
-  {
-    BlurredSegment *fbsf = lsf2->filter (bsf);
-    if (fbsf != NULL)
-    {
-      delete bsf;
-      bsf = fbsf;
-    }
-    else return RESULT_FINAL_TOO_MANY_OUTLIERS;
-  }
-
   return RESULT_OK;
 }
 
diff --git a/Code/FBSD/BlurredSegment/bsdetector.h b/Code/FBSD/BlurredSegment/bsdetector.h
index bc8d97b..cfb1f01 100755
--- a/Code/FBSD/BlurredSegment/bsdetector.h
+++ b/Code/FBSD/BlurredSegment/bsdetector.h
@@ -123,7 +123,8 @@ public:
               bool centralp = false, const Pt2i &pc = Pt2i ());
 
   /**
-   * \brief Detects a blurred segment between two input points.
+   * \brief Detects a blurred segment between two input points in static mode.
+   *    Static mode means no adaptive scans and no assigned thickness control.
    * Step 1: For each scan line, one candidate is selected
    *         based on the gradient norm only (no direction test).
    * Step 2: For each scan line, local candidates are detected
@@ -139,8 +140,8 @@ public:
    * @param centralp Set to true if the central point is provided.
    * @param pc Initial central point.
    */
-  int olddetect (const Pt2i &p1, const Pt2i &p2,
-                 bool centralp = false, const Pt2i &pc = Pt2i ());
+  int staticDetect (const Pt2i &p1, const Pt2i &p2,
+                    bool centralp = false, const Pt2i &pc = Pt2i ());
 
   /**
    * \brief Returns the detected blurred segment at given step.
@@ -165,15 +166,15 @@ public:
   inline void preserveFormerBlurredSegments () { mbsf.clear (); }
 
   /**
-   * \brief Returns the assigned maximal width for the fine tracks.
+   * \brief Returns the assigned maximal thickness to detector.
    */
-  inline int fineTracksMaxWidth () const { return fmaxWidth; }
+  inline int assignedThickness () const { return inThick; }
 
   /**
-   * \brief Sets the assigned maximal width for the fine tracks.
-   * @param val New width value.
+   * \brief Sets the assigned maximal thickness to detector.
+   * @param val New assigned thickness value.
    */
-  inline void setFineTracksMaxWidth (int val) { if (val > 0) fmaxWidth = val; }
+  inline void setAssignedThickness (int val) { if (val > 0) inThick = val; }
 
   /**
    * \brief Returns the assigned maximal width margin for the fast tracks.
@@ -225,15 +226,15 @@ public:
     return (gMap->incGradientResolution (inc)); }
 
   /**
-   * \brief Returns the automatic detection grid resolution.
+   * \brief Returns the stroke sweeping step value for automatic detections.
    */
-  inline int getAutoGridResolution () const { return autoResol; }
+  inline int getAutoSweepingStep () const { return autoSweepingStep; }
 
   /**
-   * \brief Sets the automatic detection grid resolution.
+   * \brief Sets the stroke sweeping step value for automatic detections.
    */
-  inline void setAutoGridResolution (int number) {
-    if (number > 0 && number < gMap->getWidth () / 8) autoResol = number; }
+  inline void setAutoSweepingStep (int number) {
+    if (number > 0 && number < gMap->getWidth () / 8) autoSweepingStep = number; }
 
   /**
    * \brief Returns the pixel lack tolerence.
@@ -411,46 +412,29 @@ public:
    */
   void switchOrthoScans ();
 
-  /**
-   * \brief Switches the strict thickenning option.
-   */
-  inline void switchStrict () { bst2->switchStrict (); }
-
-  /**
-   * \brief Returns if the strict thickenning option is activated.
-   */
-  inline bool isStrictOn () const { return bst2->isStrictOn (); }
-
   /**
    * \brief Returns if the thickenning control is activated.
    */
-  inline bool isThickenningOn () const { return bst2->isThickenningOn (); }
+  inline bool isAssignedThicknessControlOn () const {
+    return bst2->isAssignedThicknessControlOn (); }
 
   /**
    * \brief Toggles the thickenning control.
    */
-  inline void toggleThickenning () { bst2->toggleThickenning (); }
+  inline void toggleAssignedThicknessControl () {
+    bst2->toggleAssignedThicknessControl (); }
 
   /**
-   * \brief Returns the thickenning limit.
+   * \brief Returns the assigned thickness control delay.
    */
-  inline int getThickenningLimit () const {
-    return bst2->getThickenningLimit (); }
+  inline int getAssignedThicknessControlDelay () const {
+    return bst2->getAssignedThicknessControlDelay (); }
 
   /**
-   * \brief Increments the thickenning limit.
+   * \brief Increments the assigned thickness control delay.
    */
-  inline void incThickenningLimit (int val) { bst2->incThickenningLimit (val); }
-
-  /**
-   * \brief Returns if the thinning is activated.
-   */
-  inline bool isThinningOn () const { return bst2->isThinningOn (); }
-
-  /**
-   * \brief Toggles the thinning strategy.
-   */
-  inline void toggleThinning () { bst2->toggleThinning (); }
+  inline void incAssignedThicknessControlDelay (int val) {
+    bst2->incAssignedThicknessControlDelay (val); }
 
   /**
    * \brief Returns if one of the filter is activated.
@@ -528,26 +512,27 @@ public:
     finalDensityTestOn = ! finalDensityTestOn; }
 
   /**
-   * \brief Returns whether the spread test at final step is set.
+   * \brief Returns whether the size test at final step is set.
    */
-  inline bool isFinalSpreadTestOn () const { return (finalSpreadTestOn); }
+  inline bool isFinalSizeTestOn () const { return (finalSizeTestOn); }
 
   /**
-   * \brief Switches on or off the final spread test modality.
+   * \brief Switches on or off the final size test modality.
    */
-  inline void switchFinalSpreadTest () {
-    finalSpreadTestOn = ! finalSpreadTestOn; }
+  inline void switchFinalSizeTest () {
+    finalSizeTestOn = ! finalSizeTestOn; }
 
   /**
-   * \brief Returns the minimal spread of final blurred segments.
+   * \brief Returns the minimal size of final blurred segments.
    */
-  inline int finalSpreadMinLength () const {
-    return (finalSpreadTestOn ? finalSpreadMin : 0); }
+  inline int finalSizeMinValue () const {
+    return (finalSizeTestOn ? finalSizeMinVal : 0); }
 
   /**
    * \brief Returns the minimal spread of final blurred segments.
    */
-  inline void setFinalSpreadMinLength (int val) { finalSpreadMin = val; }
+  inline void setFinalSizeMinValue (int val) {
+    finalSizeMinVal = (val < 0 ? 0 : val); }
 
   /**
    * \brief Returns whether the length test at final step is set.
@@ -627,34 +612,40 @@ public:
                      Pt2i &p1, Pt2i &p2, int &swidth, Pt2i &pc) const;
 
   /**
-   * \brief Retuns whether the old detector (IWCIA '09) is used.
+   * \brief Retuns whether the static detector (IWCIA '09) is used.
    */
-  inline bool oldDetectorOn () { return oldp; }
+  inline bool staticDetectorOn () { return staticDetOn; }
 
   /**
-   * \brief Toggles the detector used (between IWCIA '09 and present).
+   * \brief Sets the static detector activation (IWCIA '09).
+   * @param status Activation status.
    */
-  inline void switchDetector () { oldp = ! oldp; }
+  inline void setStaticDetector (bool status) { staticDetOn = status; }
 
-std::string version ();
+  /**
+   * \brief Returns the version number.
+   */
+  std::string version ();
 
 
 private :
 
   /** Default value for the scan width for fast tracks. */
   static const int DEFAULT_FAST_TRACK_SCAN_WIDTH;
-  /** Default value for the max segment width for fine tracks. */
-  static const int DEFAULT_FINE_TRACK_MAX_WIDTH;
+  /** Default value for the assigned thickess to detection method. */
+  static const int DEFAULT_ASSIGNED_THICKNESS;
   /** Default value for the max segment width margin for fast tracks. */
   static const int DEFAULT_FAST_TRACK_MAX_MARGIN;
   /** Default value for the minimal size of the detected blurred segment. */
   static const int DEFAULT_BS_MIN_SIZE;
   /** Absolute value for the minimal size of the detected blurred segment. */
   static const int ABSOLUTE_BS_MIN_SIZE;
+  /** Default minimal size of the final blurred segment. */
+  static const int DEFAULT_FINAL_MIN_SIZE;
   /** Default value for the minimal size of connected components. */
   static const int DEFAULT_CONNECT_MIN_SIZE;
-  /** Default value for the automatic detection grid resolution. */
-  static const int DEFAULT_AUTO_RESOLUTION;
+  /** Default value of the stroke sweeping step for automatic detections. */
+  static const int DEFAULT_AUTO_SWEEPING_STEP;
   /** Default value for the preliminary stroke half length. */
   static const int PRELIM_MIN_HALF_WIDTH;
 
@@ -684,10 +675,10 @@ private :
   bool finalDensityTestOn;
   /** Length test modality after final detection. */
   bool finalLengthTestOn;
-  /** Spread test modality after final detection. */
-  bool finalSpreadTestOn;
-  /** Spread test min value. */
-  int finalSpreadMin;
+  /** Size test modality after final detection. */
+  bool finalSizeTestOn;
+  /** Size test minimal value. */
+  int finalSizeMinVal;
   /** Count of small BS eliminated by the spread test. */
   int nbSmallBS;
   /** Segment multi-selection modality status. */
@@ -698,15 +689,15 @@ private :
   int maxtrials;
   /** Automatic detection modality. */
   bool autodet;
-  /** Grid resolution for the automatic extraction. */
-  int autoResol;
+  /** Stroke sweeping step for the automatic extraction. */
+  int autoSweepingStep;
   /** Result of the blurred segment extraction. */
   int resultValue;
-  /** Old detector (IWCIA'09) modality. */
-  bool oldp;
+  /** Activation status of static detector (IWCIA'09). */
+  bool staticDetOn;
 
-  /** Assigned maximal width of the blurred segment for fine tracks. */
-  int fmaxWidth;
+  /** Assigned maximal thickness to the detector. */
+  int inThick;
   /** Assigned maximal width margin for fast tracks. */
   int imaxMargin;
 
diff --git a/Code/FBSD/BlurredSegment/bstracker.cpp b/Code/FBSD/BlurredSegment/bstracker.cpp
index 9dce6c6..a2bebd3 100755
--- a/Code/FBSD/BlurredSegment/bstracker.cpp
+++ b/Code/FBSD/BlurredSegment/bstracker.cpp
@@ -9,12 +9,7 @@ const int BSTracker::MIN_SCAN = 8;
 const int BSTracker::DEFAULT_MAX_SCAN = 32;
 const int BSTracker::DEFAULT_FITTING_DELAY = 20;
 
-const int BSTracker::DEFAULT_THICKENNING_LIMIT = 20;
-
-const int BSTracker::DEFAULT_THINNING_DELAY = 20;
-const int BSTracker::DEFAULT_THINNING_SPEED = 2;
-const int BSTracker::DEFAULT_THINNING_REACH = 50;
-const int BSTracker::DEFAULT_THINNING_RESOLUTION = 1000;
+const int BSTracker::DEFAULT_ASSIGNED_THICKNESS_CONTROL_DELAY = 20;
 
 const int BSTracker::FAILURE_NO_START = 1;
 const int BSTracker::FAILURE_IMAGE_BOUND_ON_RIGHT = 2;
@@ -25,7 +20,6 @@ const int BSTracker::FAILURE_LOST_ORIENTATION = 32;
 
 BSTracker::BSTracker ()
 {
-  strictOn = false;
   proxTestOff = true;
   proxThreshold = DEFAULT_PROX_THRESHOLD;
   acceptedLacks = DEFAULT_ACCEPTED_LACKS;
@@ -37,13 +31,9 @@ BSTracker::BSTracker ()
   orthoScan = false;
   trackCrosswise = false;
 
-  thickenningOn = true;
-  thickenningLimit = DEFAULT_THICKENNING_LIMIT;
+  assignedThicknessControlOn = true;
+  assignedThicknessControlDelay = DEFAULT_ASSIGNED_THICKNESS_CONTROL_DELAY;
 
-  thinningOn = false;
-  thinningDelay = DEFAULT_THINNING_DELAY;
-  thinningSpeed.set (DEFAULT_THINNING_SPEED, 100);
-  thinningReach.set (100 + DEFAULT_THINNING_REACH, 100);
   gMap = NULL;
 
   maxScan = DEFAULT_MAX_SCAN;
@@ -250,14 +240,10 @@ BlurredSegment *BSTracker::fineTrack (int bsMaxWidth,
 
   BlurredSegmentProto bs (bsMaxWidth, pix[cand[0]]);
 
-  // Handles thickenning
-  bool thickenOn = thickenningOn;
+  // Handles assigned thickness control
+  bool atcOn = assignedThicknessControlOn;
   int stableWidthCount = 0;
-
-  // Handles thinning
   int count = 0;
-  AbsRat maxw (bsMaxWidth * DEFAULT_THINNING_RESOLUTION,
-               DEFAULT_THINNING_RESOLUTION);
 
   // Extends the segment
   lscan = 0;
@@ -269,40 +255,18 @@ BlurredSegment *BSTracker::fineTrack (int bsMaxWidth,
   bool added = false;
   bool scanningRight = true;
   bool scanningLeft = true;
-  bool thon = thinningOn;
 
   while (scanningRight || scanningLeft)
   {
     count ++;
     AbsRat sw = bs.strictThickness ();
 
-    // Handles thickenning
-    if (thickenOn && stableWidthCount >= thickenningLimit)
+    // Handles assigned thickness control
+    if (atcOn && stableWidthCount >= assignedThicknessControlDelay)
     {
-      AbsRat dth (sw);
-      if (! strictOn) dth = bs.digitalThickness ();
-      AbsRat finalWidth (dth.sumHalf ());
+      AbsRat finalWidth (bs.digitalThickness().sumHalf ());
       if (finalWidth.lessThan (bs.getMaxWidth ())) bs.setMaxWidth (finalWidth);
-      thickenOn = false;
-    }
-
-    // Handles thinning
-    if (thon)
-    {
-      if (count > thinningDelay)
-      {
-        AbsRat oldmaxw (maxw);
-        maxw.attractsTo (sw, thinningSpeed);
-        AbsRat msw (sw);
-        msw.mult (thinningReach);
-        if (maxw.lessThan (msw))
-        {
-          maxw.sticksTo (msw);
-          if (oldmaxw.lessThan (maxw)) maxw.set (oldmaxw);
-          thon = false;  // thinning deactivation
-        }
-        bs.setMaxWidth (maxw);
-      }
+      atcOn = false;
     }
 
     // Resets the scan stripe
@@ -360,7 +324,7 @@ BlurredSegment *BSTracker::fineTrack (int bsMaxWidth,
         stableWidthCount ++;
         if (added)
         {
-          if (thickenOn
+          if (atcOn
               && sw.lessThan (bs.strictThickness ())) stableWidthCount = 0;
           rscan = count;
           if (rstop == 0) rstart = 0;
@@ -409,7 +373,7 @@ BlurredSegment *BSTracker::fineTrack (int bsMaxWidth,
         stableWidthCount ++;
         if (added)
         {
-          if (thickenOn
+          if (atcOn
               && sw.lessThan (bs.strictThickness ())) stableWidthCount = 0;
           lscan = count;
           if (lstop == 0) lstart = 0;
diff --git a/Code/FBSD/BlurredSegment/bstracker.h b/Code/FBSD/BlurredSegment/bstracker.h
index 94a6b84..f14904e 100755
--- a/Code/FBSD/BlurredSegment/bstracker.h
+++ b/Code/FBSD/BlurredSegment/bstracker.h
@@ -179,45 +179,29 @@ public:
   inline void setDynamicScans (bool onOff) { dynamicScans = onOff; }
 
   /**
-   * \brief Returns if the thickenning control is activated.
+   * \brief Returns if the assigned thickness control is activated.
    */
-  inline bool isThickenningOn () const { return thickenningOn; }
+  inline bool isAssignedThicknessControlOn () const {
+    return assignedThicknessControlOn; }
 
   /**
-   * \brief Toggles the thickenning control.
+   * \brief Toggles the assigned thickness control.
    */
-  inline void toggleThickenning () { thickenningOn = ! thickenningOn; }
+  inline void toggleAssignedThicknessControl () {
+    assignedThicknessControlOn = ! assignedThicknessControlOn; }
 
   /**
-   * \brief Returns the thickenning limit.
+   * \brief Returns the assigned thickness control delay.
    */
-  inline int getThickenningLimit () const { return thickenningLimit; }
+  inline int getAssignedThicknessControlDelay () const {
+    return assignedThicknessControlDelay; }
 
   /**
-   * \brief Increments the thickenning limit.
+   * \brief Increments the assigned thickness control delay.
    */
-  inline void incThickenningLimit (int val) {
-    thickenningLimit += val; if (thickenningLimit < 1) thickenningLimit = 1; }
-
-  /**
-   * \brief Switches the strict thickenning option.
-   */
-  inline void switchStrict () { strictOn = ! strictOn; }
-
-  /**
-   * \brief Returns if the strict thickenning option is activated.
-   */
-  inline bool isStrictOn () const { return strictOn; }
-
-  /**
-   * \brief Returns if the thinning is activated.
-   */
-  inline bool isThinningOn () const { return thinningOn; }
-
-  /**
-   * \brief Toggles the thinning strategy.
-   */
-  inline void toggleThinning () { thinningOn = ! thinningOn; }
+  inline void incAssignedThicknessControlDelay (int val) {
+    assignedThicknessControlDelay += val;
+    if (assignedThicknessControlDelay < 1) assignedThicknessControlDelay = 1; }
 
   /**
    * \brief Switches on or off the orthogonal scanning modality.
@@ -244,21 +228,8 @@ private :
   /* Count of points before activating the fitting on the detected segment. */
   static const int DEFAULT_FITTING_DELAY;
 
-  // Width thickenning default parameters.
-  /* Maximal count of points since last minimal width growing. */
-  static const int DEFAULT_THICKENNING_LIMIT;
-
-  // Width thinning default parameters.
-  /* Count of points before activating the width thinning. */
-  static const int DEFAULT_THINNING_DELAY;
-  /** Value which controls the width thinning speed.
-   * It is the percentage of width offset withdrawn from the width tolerence.
-   * Width offset = width tolerence - blurred segment width. */
-  static const int DEFAULT_THINNING_SPEED;
-  /** Minimal value of the percentage of width offset wrt segment width. */
-  static const int DEFAULT_THINNING_REACH;
-  /** Resolution of the max segment width when thinning. */
-  static const int DEFAULT_THINNING_RESOLUTION;
+  /* Maximal count of points before activating assigned thickness control. */
+  static const int DEFAULT_ASSIGNED_THICKNESS_CONTROL_DELAY;
 
   /** Segment stop information : no start point found. */
   static const int FAILURE_NO_START;
@@ -297,20 +268,10 @@ private :
   /** Crosswise segment detection modality. */
   bool trackCrosswise;
 
-bool strictOn;
-  /** Segment thinning strategy. */
-  bool thinningOn;
-  /** Width thinning delay. */
-  int thinningDelay;
-  /** Width thinning speed : amount of thinning offset withdrawn. */
-  AbsRat thinningSpeed;
-  /** Minimal control width wrt detected segment width when thinning. */
-  AbsRat thinningReach;
-
   /** Segment thickening control modality. */
-  bool thickenningOn;
-  /** Count of expansion without width growing to stop the thickenning. */
-  int thickenningLimit;
+  bool assignedThicknessControlOn;
+  /** Count of stable point insertion before activation of ATC. */
+  int assignedThicknessControlDelay;
 
   /** Gradient map. */
   VMap *gMap;
diff --git a/Code/FBSD/ImageTools/absrat.cpp b/Code/FBSD/ImageTools/absrat.cpp
index e5a7a8c..604b5f9 100755
--- a/Code/FBSD/ImageTools/absrat.cpp
+++ b/Code/FBSD/ImageTools/absrat.cpp
@@ -3,42 +3,42 @@
 
 AbsRat::AbsRat ()
 {
-  num = 1;
-  den = 0;
+  numer = 1;
+  denom = 0;
 }
 
 
 AbsRat::AbsRat (int numerator, int denominator)
 {
-  num = (numerator < 0 ? - numerator : numerator);
-  den = (denominator < 0 ? - denominator : denominator);
+  numer = (numerator < 0 ? - numerator : numerator);
+  denom = (denominator < 0 ? - denominator : denominator);
 }
 
 
 AbsRat::AbsRat (const AbsRat &rat)
 {
-  num = rat.num;
-  den = rat.den;
+  numer = rat.numer;
+  denom = rat.denom;
 }
 
 
 void AbsRat::attractsTo (const AbsRat &val, const AbsRat &ratio)
 {
-  if (val.den != 0)
-    num = (ratio.den * num * val.den
-           - (num * val.den - den * val.num) * ratio.num)
-          / (ratio.den * val.den);
+  if (val.denom != 0)
+    numer = (ratio.denom * numer * val.denom
+           - (numer * val.denom - denom * val.numer) * ratio.numer)
+          / (ratio.denom * val.denom);
 }
 
 
 void AbsRat::sticksTo (const AbsRat &val)
 {
-  if (val.den != 0) num = (den * val.num) / val.den;
+  if (val.denom != 0) numer = (denom * val.numer) / val.denom;
 }
 
 
 void AbsRat::mult (const AbsRat &val)
 {
-  num *= val.num;
-  den *= val.den;
+  numer *= val.numer;
+  denom *= val.denom;
 }
diff --git a/Code/FBSD/ImageTools/absrat.h b/Code/FBSD/ImageTools/absrat.h
index d2b3cfb..a423f21 100755
--- a/Code/FBSD/ImageTools/absrat.h
+++ b/Code/FBSD/ImageTools/absrat.h
@@ -50,33 +50,45 @@ public:
    * @fn int numerator ()
    * \brief Returns the numerator of the absolute rational number.
    */
-  inline int numerator () const { return num; }
+  inline int numerator () const { return numer; }
 
   /**
    * @fn int denominator ()
    * \brief Returns the denominator of the absolute rational number.
    */
-  inline int denominator () const { return den; }
+  inline int denominator () const { return denom; }
+
+  /**
+   * @fn int num ()
+   * \brief Returns the numerator of the absolute rational number.
+   */
+  inline int num () const { return numer; }
+
+  /**
+   * @fn int den ()
+   * \brief Returns the denominator of the absolute rational number.
+   */
+  inline int den () const { return denom; }
 
   /**
    * @fn int floor ()
    * \brief Returns the nearest smaller integer value.
    */
-  inline int floor () const { return (num / den); }
+  inline int floor () const { return (numer / denom); }
 
   /**
    * @fn void set (const AbsRat &val)
    * \brief Sets the value of the rational number.
    * @value val New value of the rational number.
    */
-  inline void set (const AbsRat &val) { num = val.num; den = val.den; }
+  inline void set (const AbsRat &val) { numer = val.numer; denom = val.denom; }
 
   /**
    * @fn void set (int val)
    * \brief Sets the value of the rational number.
    * @value val New value of the rational number.
    */
-  inline void set (int val) { num = val; den = 1; }
+  inline void set (int val) { numer = val; denom = 1; }
 
   /**
    * @fn void set (int numerator, int denominator)
@@ -85,7 +97,7 @@ public:
    * @value denominator New denominator of the rational number.
    */
   inline void set (int numerator, int denominator) {
-    num = numerator; den = denominator; }
+    numer = numerator; denom = denominator; }
 
   /**
    * @fn bool equals (const AbsRat &r)
@@ -93,7 +105,7 @@ public:
    * @param r the given rational number.
    */
   inline bool equals (const AbsRat &r) const {
-    return (num * r.den == den * r.num); }
+    return (numer * r.denom == denom * r.numer); }
 
   /**
    * @fn bool lessThan (const AbsRat &r)
@@ -101,7 +113,7 @@ public:
    * @param r the given rational number.
    */
   inline bool lessThan (const AbsRat &r) const {
-    return (num * r.den < den * r.num); }
+    return (numer * r.denom < denom * r.numer); }
 
   /**
    * @fn bool lessEqThan (const AbsRat &r)
@@ -109,7 +121,7 @@ public:
    * @param r the given rational number.
    */
   inline bool lessEqThan (const AbsRat &r) const {
-    return (num * r.den <= den * r.num); }
+    return (numer * r.denom <= denom * r.numer); }
 
   /**
    * @fn bool greaterThan (const AbsRat &r)
@@ -117,7 +129,7 @@ public:
    * @param r the given rational number.
    */
   inline bool greaterThan (const AbsRat &r) const {
-    return (num * r.den > den * r.num); }
+    return (numer * r.denom > denom * r.numer); }
 
   /**
    * @fn bool greaterEqThan (const AbsRat &r)
@@ -125,7 +137,7 @@ public:
    * @param r the given rational number.
    */
   inline bool greaterEqThan (const AbsRat &r) const {
-    return (num * r.den >= den * r.num); }
+    return (numer * r.denom >= denom * r.numer); }
 
   /**
    * @fn void attractsTo (const AbsRat &val, const AbsRat &ratio)
@@ -159,23 +171,24 @@ public:
    * \brief Returns the sum of the rational with an integer value.
    * @param val integer value.
    */
-  inline AbsRat sum (int val) const { return (AbsRat (num + val * den, den)); }
+  inline AbsRat sum (int val) const {
+    return (AbsRat (numer + val * denom, denom)); }
 
   /**
    * @fn AbsRat sumHalf () const
    * \brief Returns the sum of the rational with 1/2.
    */
   inline AbsRat sumHalf () const {
-    return (den % 2 == 1 ? AbsRat (2 * num + den, 2 * den)
-                         : AbsRat (num + den / 2, den)); }
+    return (denom % 2 == 1 ? AbsRat (2 * numer + denom, 2 * denom)
+                         : AbsRat (numer + denom / 2, denom)); }
 
 
 protected:
 
   /** Positive numerator of the rational number. */
-  int num;
+  int numer;
   /** Positive denominator of the rational number (might be null). */
-  int den;
+  int denom;
 };
 
 #endif
diff --git a/Code/FBSD/main.cpp b/Code/FBSD/main.cpp
index cb7c041..5ac3ebe 100755
--- a/Code/FBSD/main.cpp
+++ b/Code/FBSD/main.cpp
@@ -135,13 +135,11 @@ int main (int argc, char *argv[])
         {
           dss->naiveLine (x1, y1, x2, y2);
           AbsRat th = dss->squaredEuclideanThickness ();
-          outf << (x1.numerator () / (double) x1.denominator ()) << " "
-               << (height - 1
-                   - y1.numerator () / (double) y1.denominator ()) << " "
-               << (x2.numerator () / (double) x2.denominator ()) << " "
-               << (height - 1
-                   - y2.numerator () / (double) y2.denominator ()) << " "
-               << sqrt (th.numerator () / (double) th.denominator ()) << endl;
+          outf << (x1.num () / (double) x1.den ()) << " "
+               << (height - 1 - y1.num () / (double) y1.den ()) << " "
+               << (x2.num () / (double) x2.den ()) << " "
+               << (height - 1 - y2.num () / (double) y2.den ()) << " "
+               << sqrt (th.num () / (double) th.den ()) << endl;
         }
       }
       it ++;
diff --git a/Methode/ctrl.tex b/Methode/ctrl.tex
index bef6c14..eee263d 100755
--- a/Methode/ctrl.tex
+++ b/Methode/ctrl.tex
@@ -35,7 +35,8 @@ n && Allume le segment suivant dans une d\'etection multiple \\
 o && Edite le segment d\'etect\'e (seg.txt) \\
 p && Capture la fen\^etre principale \\
 r && Ajuste la r\'esolution de la grille de d\'etection automatique \\
-s && Ajuste la longueur tol\'er\'ee pour les sauts de d\'etection \\
+s && Ajuste la taille minimale des segments flous d\'etect\'es \\
+t && Ajuste la longueur tol\'er\'ee pour les sauts de d\'etection \\
 u && Relance la d\'etection sur la derni\`ere s\'election (update) \\
 w && Ajuste la consigne d'\'epaisseur du segment flou pour le suivi fin \\
 x && Ajuste la marge de consigne d'\'epaisseur du segment flou pour le suivi rapide \\
@@ -54,7 +55,8 @@ Ctrl-o && Commute la directionnalit\'e des scans \\
 Ctrl-p && Commute la d\'etection pr\'eliminaire \\
 Ctrl-q && Commute le contr\^ole dynamique des scans \\
 Ctrl-r && Commute la dilatation du masque d'occupation \\
-Ctrl-s && Commute la gestion des reprises sur interruption (1 / longueur absence) \\
+Ctrl-s && Commute le test final de taille minimale des segments flous \\
+Ctrl-t && Commute la gestion des reprises sur interruption (1 / longueur absence) \\
 Ctrl-u && Commute l'affichage des bords des segments flous. \\
 Ctrl-v && Commute l'affichage du r\'esultat de la d\'etection en console (verbose) \\
 Ctrl-w && Commute le recentrage du scan sur le segment d\'etect\'e \\
-- 
GitLab