From 0546902a71a7b4f09370eb190d0c152591ad2424 Mon Sep 17 00:00:00 2001
From: even <philippe.even@loria.fr>
Date: Thu, 22 Nov 2018 00:18:37 +0100
Subject: [PATCH] Initial detection analysis window

---
 Code/Seg/BSTools/bsdetectionwidget.cpp        |  44 ++++
 Code/Seg/BSTools/bsdetectionwidget.h          |  13 +
 Code/Seg/BSTools/bsidetitem.cpp               | 235 ++++++++++++++++++
 Code/Seg/BSTools/bsidetitem.h                 | 148 +++++++++++
 Code/Seg/BSTools/bsidetview.cpp               |  82 ++++++
 Code/Seg/BSTools/bsidetview.h                 |  58 +++++
 Code/Seg/BSTools/bsprofileitem.cpp            |  14 +-
 Code/Seg/BSTools/bswindow.cpp                 |   4 +
 Code/Seg/BSTools/bswindow.h                   |   6 +
 .../DirectionalScanner/directionalscanner.cpp |  12 +-
 .../DirectionalScanner/directionalscanner.h   |  12 +-
 .../directionalscannero1.cpp                  |  95 +++++++
 .../DirectionalScanner/directionalscannero1.h |   8 +
 .../directionalscannero2.cpp                  |  94 +++++++
 .../DirectionalScanner/directionalscannero2.h |   8 +
 .../directionalscannero7.cpp                  |  94 +++++++
 .../DirectionalScanner/directionalscannero7.h |   8 +
 .../directionalscannero8.cpp                  |  94 +++++++
 .../DirectionalScanner/directionalscannero8.h |   8 +
 Code/Seg/Seg.pro                              |   4 +
 Code/Seg/main.cpp                             |   2 +
 Methode/ctrl.tex                              |   1 +
 22 files changed, 1031 insertions(+), 13 deletions(-)
 create mode 100755 Code/Seg/BSTools/bsidetitem.cpp
 create mode 100755 Code/Seg/BSTools/bsidetitem.h
 create mode 100755 Code/Seg/BSTools/bsidetview.cpp
 create mode 100755 Code/Seg/BSTools/bsidetview.h

diff --git a/Code/Seg/BSTools/bsdetectionwidget.cpp b/Code/Seg/BSTools/bsdetectionwidget.cpp
index cfb29e2..a80d399 100755
--- a/Code/Seg/BSTools/bsdetectionwidget.cpp
+++ b/Code/Seg/BSTools/bsdetectionwidget.cpp
@@ -28,6 +28,7 @@ BSDetectionWidget::BSDetectionWidget (QWidget *parent)
   accuview = NULL;
   strucview = NULL;
   profileview = NULL;
+  idetview = NULL;
 
   alternate = 0;
   verbose = false;
@@ -65,6 +66,7 @@ QSize BSDetectionWidget::openImage (const QString &fileName, int type)
   detector.setGradientMap (gMap);
  
   update ();
+  if (idetview != NULL) idetview->setImage (&loadedImage, gMap);
   if (profileview != NULL) profileview->setImage (&loadedImage, gMap);
   if (strucview != NULL) strucview->setGradientMap (gMap);
 
@@ -146,6 +148,17 @@ void BSDetectionWidget::closeProfileAnalyzer ()
 }
 
 
+void BSDetectionWidget::closeIdetAnalyzer ()
+{
+  if (idetview != NULL)
+  {
+    idetview->close ();
+    delete idetview;
+    idetview = NULL;
+  }
+}
+
+
 void BSDetectionWidget::switchAccuAnalyzer ()
 {
   if (accuview != NULL)
@@ -197,6 +210,24 @@ void BSDetectionWidget::switchProfileAnalyzer ()
 }
 
 
+void BSDetectionWidget::switchIdetAnalyzer ()
+{
+  if (idetview != NULL)
+  {
+    idetview->close ();
+    delete idetview;
+    idetview = NULL;
+  }
+  else
+  {
+    idetview = new BSIdetView (&detector);
+    idetview->setImage (&loadedImage, gMap);
+    if (! p1.equals (p2)) idetview->buildScans (p1, p2);
+    idetview->show ();
+  }
+}
+
+
 void BSDetectionWidget::mousePressEvent (QMouseEvent *event)
 {
   this->p1 = Pt2i (event->pos().x (), height - 1 - event->pos().y());
@@ -466,6 +497,10 @@ void BSDetectionWidget::keyPressEvent (QKeyEvent *event)
       switchProfileAnalyzer ();
       break;
 
+    case Qt::Key_4 :
+      switchIdetAnalyzer ();
+      break;
+
     case Qt::Key_8 :
       alternateTest ();
       break;
@@ -490,6 +525,10 @@ void BSDetectionWidget::keyPressEvent (QKeyEvent *event)
   {
     if (profileview->processKeyEvent (event)) extract ();
   }
+  else if (idetview != NULL && idetview->isActiveWindow ())
+  {
+    if (idetview->processKeyEvent (event)) extract ();
+  }
 }
 
 
@@ -618,6 +657,11 @@ void BSDetectionWidget::displayDetectionResult (bool aux, int hnum)
   // Update auxiliary view if not dragging
   if (aux)
   {
+    if (idetview != NULL)
+    {
+      idetview->buildScans (p1, p2);
+      idetview->scene()->update ();
+    }
     if (profileview != NULL)
     {
       profileview->buildScans (p1, p2);
diff --git a/Code/Seg/BSTools/bsdetectionwidget.h b/Code/Seg/BSTools/bsdetectionwidget.h
index 37f4ecd..942c32f 100755
--- a/Code/Seg/BSTools/bsdetectionwidget.h
+++ b/Code/Seg/BSTools/bsdetectionwidget.h
@@ -11,6 +11,7 @@
 #include "bsaccumulatorview.h"
 #include "bsstructureview.h"
 #include "bsprofileview.h"
+#include "bsidetview.h"
 
 using namespace std;
 
@@ -75,6 +76,11 @@ public:
    */
   void closeProfileAnalyzer ();
 
+  /**
+   * \brief Requires the initial detection analysis window closure.
+   */
+  void closeIdetAnalyzer ();
+
   /**
    * \brief Switches the pixel display window on or off.
    */
@@ -90,6 +96,11 @@ public:
    */
   void switchProfileAnalyzer ();
 
+  /**
+   * \brief Switches the initial detection display window on or off.
+   */
+  void switchIdetAnalyzer ();
+
   /**
    * \brief Switches the extraction result display on or off.
    */
@@ -193,6 +204,8 @@ private:
 
   /** Blurred segment detector. */
   BSDetector detector;
+  /** Initial detection graphics view. */
+  BSIdetView *idetview;
   /** Scanned profile graphics view. */
   BSProfileView *profileview;
   /** Filter accumulator view. */
diff --git a/Code/Seg/BSTools/bsidetitem.cpp b/Code/Seg/BSTools/bsidetitem.cpp
new file mode 100755
index 0000000..efcf48d
--- /dev/null
+++ b/Code/Seg/BSTools/bsidetitem.cpp
@@ -0,0 +1,235 @@
+#include <cstdlib>
+#include <iostream>
+#include <QtGui>
+#include "bsidetitem.h"
+#include "directionalscanner.h"
+
+using namespace std;
+
+
+
+const int BSIdetItem::DISPLAY_INTENSITY = 1;
+const int BSIdetItem::DISPLAY_MIN = DISPLAY_INTENSITY;
+const int BSIdetItem::DISPLAY_MAX = DISPLAY_INTENSITY;
+
+const int BSIdetItem::MIN_SCAN = 8;
+
+
+
+BSIdetItem::BSIdetItem (BSDetector *detector)
+{
+  margin = 5;
+  resol = 4;
+  width = 800;
+  height = 200;
+
+  image = NULL;
+  imageWidth = 0;
+  imageHeight = 0;
+  gMap = NULL;
+
+  displayItem = DISPLAY_INTENSITY;
+  det = detector;
+  ds = NULL;
+}
+
+
+QRectF BSIdetItem::boundingRect () const
+{
+  return QRectF (0, 0, width + 40, height + 40);
+}
+
+
+void BSIdetItem::paint (QPainter *painter,
+                           const QStyleOptionGraphicsItem *option,
+                           QWidget *widget)
+{
+  Q_UNUSED (option);
+  Q_UNUSED (widget);
+
+  paintStripes (painter);
+}
+
+
+void BSIdetItem::setImage (QImage *image, VMap *idata)
+{
+  this->image = image;
+  this->gMap = idata;
+  this->imageWidth = image->width ();
+  this->imageHeight = image->height ();
+}
+
+
+void BSIdetItem::buildScans (Pt2i p1, Pt2i p2)
+{
+  if (ds != NULL) delete ds;
+
+  // Updates the central scan end points for parallel display
+  this->pt1 = p1;
+  this->pt2 = p2;
+
+  // Resets the idets
+  rightscan.clear ();
+  leftscan.clear ();
+  offx = 0;
+  offy = 0;
+
+  // Gets a scan iterator
+  ds = scanp.getScanner (p1, p2, 0, 0, imageWidth, imageHeight);
+
+  // Extracts the left scan (with central one)
+  vector<Pt2i> pix;
+  if (ds->first (pix) < MIN_SCAN) { delete ds; return;}
+  leftscan.push_back (pix);
+  int sw = pix.size ();
+
+  bool leftScanOn = true;
+  maxStripe = 0;
+  while (leftScanOn)
+  {
+    vector<Pt2i> scan;
+    if (ds->nextOnLeft (scan) < sw - 1) leftScanOn = false;
+    else
+    {
+      leftscan.push_back (scan);
+      maxStripe ++;
+    }
+  }
+
+  // Extracts the right scans
+  bool rightScanOn = true;
+  minStripe = 1;
+  while (rightScanOn)
+  {
+    vector<Pt2i> scan;
+    if (ds->nextOnRight (scan) < sw - 1) rightScanOn = false;
+    else
+    {
+      rightscan.push_back (scan);
+      minStripe --;
+    }
+  }
+}
+
+
+void BSIdetItem::incX (int inc)
+{
+  offx += inc;
+}
+
+
+void BSIdetItem::incY (int inc)
+{
+  offy += inc;
+  if (offy > 0) offy = 0;
+}
+
+
+void BSIdetItem::toggleDisplay (bool next)
+{
+  displayItem += (next ? 1 : -1);
+  if (displayItem > DISPLAY_MAX) displayItem = DISPLAY_MIN;
+  else if (displayItem < DISPLAY_MIN) displayItem = DISPLAY_MAX;
+}
+
+
+
+
+void BSIdetItem::paintStripes (QPainter *painter)
+{
+if (pt1.equals (pt2)) return;
+  int lowpos = height - margin - resol * (offy + 1);
+  int cpos = width / 2 - resol / 2 + resol * offx;
+  int py = lowpos, px = cpos;
+  vector <vector <Pt2i> >::iterator bigit;
+
+  // Central scan (in yellow)
+  if (leftscan.size ())
+  {
+    bigit = leftscan.begin ();
+    vector<Pt2i> scan = *bigit; 
+    vector<Pt2i>::iterator it = scan.begin (); 
+    while (py >= margin + resol && it != scan.end ())
+    {
+      int col = qRed (image->pixel ((*it).x (), imageHeight - 1 - (*it).y ()));
+      painter->fillRect (px, py, resol, resol,
+                         QBrush (qRgb (col, col, 0)));
+      it ++;
+      py -= resol;
+    }
+
+    // Left side
+    px -= resol;
+    bigit ++;
+    while (px >= resol + 1 && bigit != leftscan.end ())
+    {
+      py = lowpos;
+      scan = *bigit;
+      it = scan.begin ();
+      while (py >= margin + resol && it != scan.end ())
+      {
+        painter->fillRect (px, py, resol, resol,
+          QBrush (image->pixel ((*it).x (), imageHeight - 1 - (*it).y ())));
+        it ++;
+        py -= resol;
+      }
+      bigit ++;
+      px -= resol;
+    }
+  }
+
+  // Right side
+  if (rightscan.size ())
+  {
+    px = cpos + resol;
+    bigit = rightscan.begin ();
+    while (px <= width - margin - resol
+           && bigit != rightscan.end ())
+    {
+      py = lowpos;
+      vector<Pt2i> scan = *bigit;
+      vector<Pt2i>::iterator it = scan.begin ();
+      while (py >= margin + resol && it != scan.end ())
+      {
+        painter->fillRect (px, py, resol, resol,
+          QBrush (image->pixel ((*it).x (), imageHeight - 1 - (*it).y ())));
+        it ++;
+        py -= resol;
+      }
+      bigit ++;
+      px += resol;
+    }
+  }
+
+  BlurredSegment *bs = det->getBlurredSegment (BSDetector::STEP_INITIAL);
+  if (bs != NULL)
+  {
+//    const vector<Pt2i> *pts = bs->getLeftPoints ();
+//    vector<Pt2i>::const_iterator it = pts->begin ();
+//    while (it != pts->end ())
+    vector<Pt2i> pts = bs->getAllPoints ();
+    vector<Pt2i>::iterator it = pts.begin ();
+    while (it != pts.end ())
+    {
+      Pt2i pt = ds->locate (*it);
+      int posx = cpos + resol * pt.x ();
+      int posy = lowpos - resol * pt.y ();
+if (pt.x () <= 0)
+{
+Pt2i pini = leftscan.at(-pt.x ()).at(pt.y ());
+if (it->x () != pini.x () || it->y () != pini.y ())
+cout << "IT (" << it->x () << ", " << it->y () << ") -> ("
+<< pini.x () << ", " << pini.y () << ")" << endl;
+}
+else
+{
+Pt2i pini = rightscan.at(pt.x () - 1).at(pt.y ());
+if (it->x () != pini.x () || it->y () != pini.y ())
+cout << "IT (" << it->x () << ", " << it->y () << ") -> ("
+<< pini.x () << ", " << pini.y () << ")" << endl;
+}
+      painter->fillRect (posx, posy, resol, resol, QBrush (Qt::blue));
+      it++;
+    }
+  }
+}
diff --git a/Code/Seg/BSTools/bsidetitem.h b/Code/Seg/BSTools/bsidetitem.h
new file mode 100755
index 0000000..b8cf42d
--- /dev/null
+++ b/Code/Seg/BSTools/bsidetitem.h
@@ -0,0 +1,148 @@
+#ifndef BS_IDET_ITEM_H
+#define BS_IDET_ITEM_H
+
+#include <QGraphicsItem>
+#include <QImage>
+#include <QKeyEvent>
+#include "vmap.h"
+#include "scannerprovider.h"
+#include "bsdetector.h"
+
+
+/** 
+ * @class BSIdetItem bsidetitem.h
+ * \brief Initial detection view and controller.
+ * \author {P. Even}
+ */
+class BSIdetItem : public QGraphicsItem
+{
+
+public:
+
+
+  /**
+   * \brief Creates an initial detection analysis widget.
+   */
+  BSIdetItem (BSDetector *detector);
+
+  /**
+   * \brief Declares the image to be analysed.
+   */
+  void setImage (QImage *image, VMap *idata);
+
+  /**
+   * \brief Sets the image scan area from an initial scan.
+   * The initial scan is a straight segment from p1 to p2.
+   */
+  void buildScans (Pt2i p1, Pt2i p2);
+
+  /**
+   * \brief Returns the widget size.
+   * Nominally the image size.
+   */
+  QRectF boundingRect () const;
+
+  /**
+   * \brief Updates the widget display.
+   */
+  void paint (QPainter *painter,
+              const QStyleOptionGraphicsItem *option, QWidget *widget);
+
+  /**
+   * \brief Returns the displayed information title.
+   */
+  inline QString itemTitle () const
+  {
+    if (displayItem == DISPLAY_INTENSITY)
+      return ("Initial detection");
+    else return ("No info");
+  }
+
+  /**
+   * \brief Increments the current stripe index.
+   * @param inc Direction (1 for rightwards, -1 for leftwards)
+   */
+  void incX (int inc);
+
+  /**
+   * \brief Increments the current stripe index.
+   * @param inc Direction (1 for upwards, -1 for downwards)
+   */
+  void incY (int inc);
+
+  /**
+   * \brief Toggles the displayed information.
+   * @param next Get next information if true, previous on otherwise.
+   */
+  void toggleDisplay (bool next);
+
+
+protected:
+
+private:
+
+  /** Available information : intensity idets. */
+  static const int DISPLAY_INTENSITY;
+  /** Number of the first information. */
+  static const int DISPLAY_MIN;
+  /** Number of the last information. */
+  static const int DISPLAY_MAX;
+
+  /** Analysis widget height. */
+  int height;
+  /** Analysis widget width. */
+  int width;
+  /** Stripe area margin width. */
+  int margin;
+  /** Stripe points zoom factor. */
+  int resol;
+  /** Stripe area horizontal offset. */
+  int offx;
+  /** Stripe area vertical offset. */
+  int offy;
+
+  /** Analysed image. */
+  QImage *image;
+  /* Analysed image width. */
+  int imageWidth;
+  /** Analyzed image height. */
+  int imageHeight;
+  /** Gradient map. */
+  VMap *gMap;
+
+  /** Central scan start point. */
+  Pt2i pt1;
+  /** Central scan start point. */
+  Pt2i pt2;
+  /** Directional scanner to analyse. */
+  DirectionalScanner *ds;
+  /** Central and left scans. */
+  vector <vector <Pt2i> > leftscan;
+  /** Right scans. */
+  vector <vector <Pt2i> > rightscan;
+  /** Minimum scan length allowed. */
+  static const int MIN_SCAN;
+
+  /** Displayed information (intensity, gradient, correlation). */
+  int displayItem;
+  /** Current stripe index. */
+  int stripe;
+  /** Min stripe index (right scan size). */
+  int minStripe;
+  /** Max stripe index (left scan size). */
+  int maxStripe;
+
+  /** Scanner provider. */
+  ScannerProvider scanp;
+  /** Reference to the associated detector. */
+  BSDetector *det;
+
+
+  /**
+   * \brief Draws the scan strip.
+   */
+  void paintStripes (QPainter *painter);
+
+};
+
+#endif
diff --git a/Code/Seg/BSTools/bsidetview.cpp b/Code/Seg/BSTools/bsidetview.cpp
new file mode 100755
index 0000000..d38c78b
--- /dev/null
+++ b/Code/Seg/BSTools/bsidetview.cpp
@@ -0,0 +1,82 @@
+#include <QtGui>
+#include <iostream>
+#include <cstdlib>
+#include "bsidetview.h"
+
+using namespace std;
+
+
+
+BSIdetView::BSIdetView (BSDetector *detector)
+{
+  // CAUTION : don't activate antialiasing here !!!
+  setBackgroundBrush (QBrush (Qt::white));
+  setScene (new QGraphicsScene (0, 0, 800, 200));
+  idet = new BSIdetItem (detector);
+  scene()->addItem (idet);
+  setWindowTitle (idet->itemTitle ());
+  resize (QSize (816, 216));
+}
+
+
+BSIdetView::~BSIdetView ()
+{
+  scene()->removeItem (idet);
+  delete idet;
+}
+
+
+void BSIdetView::paint (QPainter *painter,
+                           const QStyleOptionGraphicsItem *option,
+                           QWidget *widget)
+{
+  Q_UNUSED (option);
+  Q_UNUSED (widget);
+  Q_UNUSED (painter);
+}
+
+
+void BSIdetView::setImage (QImage *image, VMap *idata)
+{
+  idet->setImage (image, idata);
+}
+
+
+void BSIdetView::buildScans (Pt2i p1, Pt2i p2)
+{
+  idet->buildScans (p1, p2);
+}
+
+
+bool BSIdetView::processKeyEvent (QKeyEvent *event)
+{
+  switch (event->key ())
+  {
+    case Qt::Key_I :
+      idet->toggleDisplay ((event->modifiers () & Qt::ShiftModifier) == 0);
+      setWindowTitle (idet->itemTitle ());
+      idet->update ();
+      break;
+
+    case Qt::Key_Left :
+      idet->incX (-1);
+      idet->update ();
+      break;
+
+    case Qt::Key_Right :
+      idet->incX (1);
+      idet->update ();
+      break;
+
+    case Qt::Key_Up :
+      idet->incY (1);
+      idet->update ();
+      break;
+
+    case Qt::Key_Down :
+      idet->incY (-1);
+      idet->update ();
+      break;
+  }
+  return false;
+}
diff --git a/Code/Seg/BSTools/bsidetview.h b/Code/Seg/BSTools/bsidetview.h
new file mode 100755
index 0000000..18182af
--- /dev/null
+++ b/Code/Seg/BSTools/bsidetview.h
@@ -0,0 +1,58 @@
+#ifndef BS_IDET_VIEW_H
+#define BS_IDET_VIEW_H
+
+#include <QGraphicsView>
+#include "bsidetitem.h"
+
+
+/** 
+ * @class BSIdetView bsidetview.h
+ * \brief A Qt window containing informations about initial detection.
+ * \author {P. Even}
+ */
+class BSIdetView : public QGraphicsView
+{
+
+public:
+
+  /**
+   * \brief Creates a initial detection analysis window.
+   */
+  BSIdetView (BSDetector *detector);
+
+  /**
+   * \brief Deletes the initial detection analysis window.
+   */
+  ~BSIdetView ();
+
+  /**
+   * \brief Updates the initial detection analysis window display.
+   */
+  void paint (QPainter *painter,
+              const QStyleOptionGraphicsItem *option, QWidget *widget);
+
+  /**
+   * \brief Declares the image to be analysed.
+   */
+  void setImage (QImage *image, VMap *idata);
+
+  /**
+   * \brief Sets the image scan area from an initial scan.
+   * The initial scan is a straight segment from p1 to p2.
+   */
+  void buildScans (Pt2i p1, Pt2i p2);
+
+  /**
+   * \brief Processes key pressed events.
+   */
+  bool processKeyEvent (QKeyEvent *event);
+
+
+private:
+
+  /** Initial detection analysis widget. */
+  BSIdetItem *idet;
+
+};
+
+#endif
diff --git a/Code/Seg/BSTools/bsprofileitem.cpp b/Code/Seg/BSTools/bsprofileitem.cpp
index d6133ca..f0aaa03 100755
--- a/Code/Seg/BSTools/bsprofileitem.cpp
+++ b/Code/Seg/BSTools/bsprofileitem.cpp
@@ -675,16 +675,14 @@ void BSProfileItem::getLocalMinimaIndices (vector<int> &indices,
 
 void BSProfileItem::paintStripes (QPainter *painter)
 {
-  int lx = 80;
-  int cx, cy = widHeight / 2;
+  int lx = profileWidth + stripeMargin + stripeWidth / 2 - stripeResol / 2;
+  int cx = 0, cy = widHeight / 2;
   vector <vector <Pt2i> >::iterator bigit;
 
   if (rightscan.size ())
-    lx = profileWidth + stripeMargin + stripeWidth / 2
-             - stripeResol / 2 - rightscan.at(0).size () * stripeResol / 2;
+    lx -= rightscan.at(0).size () * stripeResol / 2;
   else if (leftscan.size ())
-    lx = profileWidth + stripeMargin + stripeWidth / 2
-             - stripeResol / 2 - leftscan.at(0).size () * stripeResol / 2;
+    lx -= leftscan.at(0).size () * stripeResol / 2;
   painter->setPen (QPen (Qt::red, 2));
   painter->drawRect (profileWidth + stripeMargin - 1, stripeMargin - 1,
                      stripeWidth + 2, widHeight - 2 * stripeMargin + 2);
@@ -693,7 +691,7 @@ void BSProfileItem::paintStripes (QPainter *painter)
   if (rightscan.size ())
   {
     bigit = rightscan.begin ();
-    while (cy <= widWidth - stripeMargin - stripeResol
+    while (cy <= widHeight - stripeMargin - stripeResol
            && bigit != rightscan.end ())
     {
       cx = lx;
@@ -717,7 +715,7 @@ void BSProfileItem::paintStripes (QPainter *painter)
   {
     cy = widHeight / 2 - 2 * stripeResol;
     bigit = leftscan.begin ();
-    while (cy >= 5 && bigit != leftscan.end ())
+    while (cy >= stripeResol + 1 && bigit != leftscan.end ())
     {
       cx = lx;
       vector<Pt2i> scan = *bigit;
diff --git a/Code/Seg/BSTools/bswindow.cpp b/Code/Seg/BSTools/bswindow.cpp
index 5c848f9..e5836fd 100755
--- a/Code/Seg/BSTools/bswindow.cpp
+++ b/Code/Seg/BSTools/bswindow.cpp
@@ -9,6 +9,7 @@
 BSWindow::BSWindow (int *val)
 {
   Q_UNUSED (val);
+  showIdet = false;
   showProf = false;
   showAccu = false;
   showSeg = false;
@@ -25,6 +26,7 @@ BSWindow::BSWindow (int *val)
 
 BSWindow::BSWindow ()
 {
+  showIdet = false;
   showProf = false;
   showAccu = false;
   showSeg = false;
@@ -47,6 +49,7 @@ void BSWindow::setFile (QString fileName)
 
 void BSWindow::runOptions ()
 {
+  if (showIdet) detectionWidget->switchIdetAnalyzer ();
   if (showProf) detectionWidget->switchProfileAnalyzer ();
   if (showAccu) detectionWidget->switchAccuAnalyzer ();
   if (showSeg) detectionWidget->switchPixelAnalyzer ();
@@ -61,6 +64,7 @@ void BSWindow::runTest ()
 
 void BSWindow::closeEvent (QCloseEvent *event)
 {
+  detectionWidget->closeIdetAnalyzer ();
   detectionWidget->closeProfileAnalyzer ();
   detectionWidget->closeAccuAnalyzer ();
   detectionWidget->closePixelAnalyzer ();
diff --git a/Code/Seg/BSTools/bswindow.h b/Code/Seg/BSTools/bswindow.h
index c9afa16..b570016 100755
--- a/Code/Seg/BSTools/bswindow.h
+++ b/Code/Seg/BSTools/bswindow.h
@@ -32,6 +32,11 @@ public:
    */
   void setFile (QString fileName);
 
+  /**
+   * Switches the initial detection analysis window on or off.
+   */
+  inline void toggleIdetWindow () { showIdet = ! showIdet; }
+
   /**
    * Switches the profile analysis window on or off.
    */
@@ -77,6 +82,7 @@ private:
 
   /** Blurred segment detection widget. */
   BSDetectionWidget *detectionWidget;
+  bool showIdet;
   bool showProf;
   bool showAccu;
   bool showSeg;
diff --git a/Code/Seg/DirectionalScanner/directionalscanner.cpp b/Code/Seg/DirectionalScanner/directionalscanner.cpp
index 2c94dbd..b936b16 100755
--- a/Code/Seg/DirectionalScanner/directionalscanner.cpp
+++ b/Code/Seg/DirectionalScanner/directionalscanner.cpp
@@ -3,6 +3,13 @@
 
 
 
+DirectionalScanner::~DirectionalScanner ()
+{
+  if (steps != NULL) delete steps;
+  steps = NULL;
+}
+
+
 void DirectionalScanner::bindTo (int a, int b, int c)
 {
   (void) a;
@@ -11,8 +18,7 @@ void DirectionalScanner::bindTo (int a, int b, int c)
 }
 
 
-DirectionalScanner::~DirectionalScanner ()
+Pt2i DirectionalScanner::locate (const Pt2i & pt) const
 {
-  if (steps != NULL) delete steps;
-  steps = NULL;
+  return (Pt2i (0, 0));
 }
diff --git a/Code/Seg/DirectionalScanner/directionalscanner.h b/Code/Seg/DirectionalScanner/directionalscanner.h
index d7a6870..40287ce 100755
--- a/Code/Seg/DirectionalScanner/directionalscanner.h
+++ b/Code/Seg/DirectionalScanner/directionalscanner.h
@@ -60,6 +60,14 @@ public:
    */
   virtual void bindTo (int a, int b, int c);
 
+  /**
+   * @fn Pt2i locate (const Pt2i &pt) const
+   * \brief Returns the scanner coordinates of the givent point.
+   * Scanner coordinates are the stripe index and the position in the stripe.
+   * @param pt Image coordinates of the point.
+   */
+  virtual Pt2i locate (const Pt2i &pt) const;
+
 
 protected:
 
@@ -76,7 +84,7 @@ protected:
   bool *steps, *fs;
 
   /** Start position of a scan for both directions. */
-  int lcx, lcy, rcx, rcy;
+  int ccx, ccy, lcx, lcy, rcx, rcy;
 
   /** Current step in scan direction. */
   bool *lst2, *rst2;
@@ -103,7 +111,7 @@ protected:
                       int nb, bool* st, int sx, int sy)
              : xmin (xmini), ymin (ymini), xmax (xmaxi), ymax (ymaxi),
                nbs (nb), steps (st),
-               lcx (sx), lcy (sy), rcx (sx), rcy (sy) { }
+               ccx (sx), ccy (sy), lcx (sx), lcy (sy), rcx (sx), rcy (sy) { }
 
 };
 
diff --git a/Code/Seg/DirectionalScanner/directionalscannero1.cpp b/Code/Seg/DirectionalScanner/directionalscannero1.cpp
index a31f310..d3a216d 100755
--- a/Code/Seg/DirectionalScanner/directionalscannero1.cpp
+++ b/Code/Seg/DirectionalScanner/directionalscannero1.cpp
@@ -221,3 +221,98 @@ int DirectionalScannerO1::nextOnRight (vector<Pt2i> &scan)
   }
   return ((int) (scan.size ()));
 }
+
+
+Pt2i DirectionalScannerO1::locate (const Pt2i &pt) const
+{
+  int x = ccx, y = ccy;      // Current position coordinates
+  bool *nst = steps;         // Current step in scan direction (jpts)
+  int cx = 0, cy = pt.y () - y;
+  bool *st1 = steps;
+  bool *st2 = steps;
+  
+  if (cy >= 0)
+  {
+    // Climbs the first scan up
+    while (y < pt.y ())
+    {
+      if (*nst) x--;
+      y++;
+      if (++nst >= fs) nst = steps;
+    }
+  }
+  else
+  {
+    // Climbs the first scan down
+    while (y > pt.y ())
+    {
+      y--;
+      if (--nst < steps) nst = fs -1;
+      if (*nst) x++;
+    }
+  }
+  cx = pt.x () - x;
+
+  // Comes back to scan origin
+  x = ccx;
+  y = ccy;
+  int nx = cx;
+  bool trans = false;
+  while (nx != 0)
+  {
+    // Jumps leftwards along scan bound
+    if (cx < 0)
+    {
+      if (trans)
+      {
+        y --;
+        if (--st2 < steps) st2 = fs - 1;
+        trans = false;
+      }
+      else
+      {
+        if (--st1 < steps) st1 = fs - 1;
+        x --;
+        if (*st1)
+        {
+          y --;
+          if (--st2 < steps) st2 = fs - 1;
+          if (*st2)
+          {
+            if (++st2 >= fs) st2 = steps;
+            y ++;
+            trans = true;
+          }
+        }
+      }
+      nx ++;
+    }
+    else
+    // Jumps rightwards along scan bound
+    {
+      if (trans)
+      {
+        x ++;
+        trans = false;
+      }
+      else
+      {
+        x ++;
+        if (*st1)
+        {
+          if (*st2)
+          { 
+            x --;
+            trans = true;
+          }
+          y ++;
+          if (++st2 >= fs) st2 = steps;
+        }
+        if (++st1 >= fs) st1 = steps;
+      }
+      nx --;
+    }
+  }
+
+  return (Pt2i (cx, pt.y () - y));
+}
diff --git a/Code/Seg/DirectionalScanner/directionalscannero1.h b/Code/Seg/DirectionalScanner/directionalscannero1.h
index ee48df7..05f9e13 100755
--- a/Code/Seg/DirectionalScanner/directionalscannero1.h
+++ b/Code/Seg/DirectionalScanner/directionalscannero1.h
@@ -112,6 +112,14 @@ public:
    */
   int nextOnRight (vector<Pt2i> &scan);
 
+  /**
+   * @fn Pt2i locate (const Pt2i &pt) const
+   * \brief Returns the scanner coordinates of the givent point.
+   * Scanner coordinates are the stripe index and the position in the stripe.
+   * @param pt Image coordinates of the point.
+   */
+  virtual Pt2i locate (const Pt2i &pt) const;
+
 private:
 
   /** Current step in strip direction */
diff --git a/Code/Seg/DirectionalScanner/directionalscannero2.cpp b/Code/Seg/DirectionalScanner/directionalscannero2.cpp
index 5d6ff02..424f435 100755
--- a/Code/Seg/DirectionalScanner/directionalscannero2.cpp
+++ b/Code/Seg/DirectionalScanner/directionalscannero2.cpp
@@ -220,3 +220,97 @@ int DirectionalScannerO2::nextOnRight (vector<Pt2i> &scan)
   }
   return ((int) (scan.size ()));
 }
+
+
+Pt2i DirectionalScannerO2::locate (const Pt2i &pt) const
+{
+  int x = ccx, y = ccy;      // Current position coordinates
+  bool *nst = steps;         // Current step in scan direction (jpts)
+  int cx = pt.x () - x, cy = 0;
+  bool *st1 = steps;
+  bool *st2 = steps;
+  
+  if (cx <= 0)
+  {
+    // Climbs the first scan up
+    while (x > pt.x ())
+    {
+      if (*nst) y++;
+      x--;
+      if (++nst >= fs) nst = steps;
+    }
+  }
+  else
+  {
+    // Climbs the first scan down
+    while (x < pt.x ())
+    {
+      x++;
+      if (--nst < steps) nst = fs - 1;
+      if (*nst) y--;
+    }
+  }
+  cy = pt.y () - y;
+
+  // Comes back to scan origin
+  x = ccx;
+  y = ccy;
+  int ny = cy;
+  bool trans = false;
+  while (ny != 0)
+  {
+    // Jumps leftwards along scan bound
+    if (cy < 0)
+    {
+      if (trans)
+      {
+        y --;
+        trans = false;
+      }
+      else
+      {
+        if (--st1 < steps) st1 = fs - 1;
+        y --;
+        if (*st1)
+        {
+          x --;
+          if (*st2)
+          {
+            y ++;
+            trans = true;
+          }
+          if (++st2 >= fs) st2 = steps;
+        }
+      }
+      ny ++;
+    }
+    else
+    // Jumps rightwards along scan bound
+    {
+      if (trans)
+      {
+        x ++;
+        if (--st2 < steps) st2 = fs - 1;
+        trans = false;
+      }
+      else
+      {
+        y ++;
+        if (*st1)
+        {
+          if (--st2 < steps) st2 = fs - 1;
+          if (*st2)
+          {
+            if (++st2 >= fs) st2 = steps;
+            trans = true;
+          }
+          else x ++;
+        }
+        if (++st1 >= fs) st1 = steps;
+      }
+      ny --;
+    }
+  }
+
+  return (Pt2i (cy, x - pt.x ()));
+}
diff --git a/Code/Seg/DirectionalScanner/directionalscannero2.h b/Code/Seg/DirectionalScanner/directionalscannero2.h
index 6e06b5d..6ac98a4 100755
--- a/Code/Seg/DirectionalScanner/directionalscannero2.h
+++ b/Code/Seg/DirectionalScanner/directionalscannero2.h
@@ -112,6 +112,14 @@ public:
    */
   int nextOnRight (vector<Pt2i> &scan);
 
+  /**
+   * @fn Pt2i locate (const Pt2i &pt) const
+   * \brief Returns the scanner coordinates of the givent point.
+   * Scanner coordinates are the stripe index and the position in the stripe.
+   * @param pt Image coordinates of the point.
+   */
+  virtual Pt2i locate (const Pt2i &pt) const;
+
 private:
 
   /** Current step in strip direction */
diff --git a/Code/Seg/DirectionalScanner/directionalscannero7.cpp b/Code/Seg/DirectionalScanner/directionalscannero7.cpp
index c62fb53..9d4296f 100755
--- a/Code/Seg/DirectionalScanner/directionalscannero7.cpp
+++ b/Code/Seg/DirectionalScanner/directionalscannero7.cpp
@@ -221,3 +221,97 @@ int DirectionalScannerO7::nextOnRight (vector<Pt2i> &scan)
   }
   return ((int) (scan.size ()));
 }
+
+
+Pt2i DirectionalScannerO7::locate (const Pt2i &pt) const
+{
+  int x = ccx, y = ccy;      // Current position coordinates
+  bool *nst = steps;         // Current step in scan direction (jpts)
+  int cx = pt.x () - x, cy = 0;
+  bool *st1 = steps;
+  bool *st2 = steps;
+  
+  if (cx >= 0)
+  {
+    // Climbs the first scan up
+    while (x < pt.x ())
+    {
+      if (*nst) y++;
+      x++;
+      if (++nst >= fs) nst = steps;
+    }
+  }
+  else
+  {
+    // Climbs the first scan down
+    while (x < pt.x ())
+    {
+      x--;
+      if (--nst < steps) nst = fs - 1;
+      if (*nst) y--;
+    }
+  }
+  cy = y - pt.y ();
+
+  // Comes back to scan origin
+  x = ccx;
+  y = ccy;
+  int ny = cy;
+  bool trans = false;
+  while (ny != 0)
+  {
+    // Jumps leftwards along scan bound
+    if (cy < 0)
+    {
+      if (trans)
+      {
+        y --;
+        trans = false;
+      }
+      else
+      {
+        if (--st1 < steps) st1 = fs - 1;
+        y --;
+        if (*st1)
+        {
+          x --;
+          if (*st2)
+          {
+            y ++;
+            trans = true;
+          }
+          if (++st2 >= fs) st2 = steps;
+        }
+      }
+      ny ++;
+    }
+    else
+    // Jumps rightwards along scan bound
+    {
+      if (trans)
+      {
+        x ++;
+        if (--st2 < steps) st2 = fs - 1;
+        trans = false;
+      }
+      else
+      {
+        y ++;
+        if (*st1)
+        {
+          if (--st2 < steps) st2 = fs - 1;
+          if (*st2)
+          {
+            if (++st2 >= fs) st2 = steps;
+            trans = true;
+          }
+          else x ++;
+        }
+        if (++st1 >= fs) st1 = steps;
+      }
+      ny --;
+    }
+  }
+
+  return (Pt2i (cy, pt.x () - x));
+}
diff --git a/Code/Seg/DirectionalScanner/directionalscannero7.h b/Code/Seg/DirectionalScanner/directionalscannero7.h
index 404338d..07f4948 100755
--- a/Code/Seg/DirectionalScanner/directionalscannero7.h
+++ b/Code/Seg/DirectionalScanner/directionalscannero7.h
@@ -112,6 +112,14 @@ public:
    */
   int nextOnRight (vector<Pt2i> &scan);
 
+  /**
+   * @fn Pt2i locate (const Pt2i &pt) const
+   * \brief Returns the scanner coordinates of the givent point.
+   * Scanner coordinates are the stripe index and the position in the stripe.
+   * @param pt Image coordinates of the point.
+   */
+  virtual Pt2i locate (const Pt2i &pt) const;
+
 private:
 
   /** Current step in strip direction */
diff --git a/Code/Seg/DirectionalScanner/directionalscannero8.cpp b/Code/Seg/DirectionalScanner/directionalscannero8.cpp
index 3b78148..eaadecd 100755
--- a/Code/Seg/DirectionalScanner/directionalscannero8.cpp
+++ b/Code/Seg/DirectionalScanner/directionalscannero8.cpp
@@ -221,3 +221,97 @@ int DirectionalScannerO8::nextOnRight (vector<Pt2i> &scan)
   }
   return ((int) (scan.size ()));
 }
+
+
+Pt2i DirectionalScannerO8::locate (const Pt2i &pt) const
+{
+  int x = ccx, y = ccy;      // Current position coordinates
+  bool *nst = steps;         // Current step in scan direction (jpts)
+  int cx = 0, cy = pt.y () - y;
+  bool *st1 = steps;
+  bool *st2 = steps;
+  
+  if (cy >= 0)
+  {
+    // Climbs the first scan up
+    while (y < pt.y ())
+    {
+      if (*nst) x++;
+      y++;
+      if (++nst >= fs) nst = steps;
+    }
+  }
+  else
+  {
+    // Climbs the first scan down
+    while (y > pt.y ())
+    {
+      y--;
+      if (--nst < steps) nst = fs -1;
+      if (*nst) x--;
+    }
+  }
+  cx = pt.x () - x;
+
+  // Comes back to scan origin
+  x = ccx;
+  y = ccy;
+  int nx = cx;
+  bool trans = false;
+  while (nx != 0)
+  {
+    // Jumps leftwards along scan bound
+    if (cx < 0)
+    {
+      if (trans)
+      {
+        x --;
+        trans = false;
+      }
+      else
+      {
+        if (--st1 < steps) st1 = fs - 1;
+        x --;
+        if (*st1)
+        {
+          y ++;
+          if (*st2)
+          {
+            x ++;
+            trans = true;
+          }
+          if (++st2 >= fs) st2 = steps;
+        }
+      }
+      nx ++;
+    }
+    else
+    // Jumps rightwards along scan bound
+    {
+      if (trans)
+      {
+        y --;
+        if (--st2 < steps) st2 = fs - 1;
+        trans = false;
+      }
+      else
+      { 
+        x ++;
+        if (*st1)
+        {
+          if (--st2 < steps) st2 = fs - 1;
+          if (*st2)
+          {
+            if (++st2 >= fs) st2 = steps;
+            trans = true;
+          }
+          else y --;
+        }
+        if (++st1 >= fs) st1 = steps;
+      }
+      nx --;
+    }
+  }
+
+  return (Pt2i (cx, pt.y () - y));
+}
diff --git a/Code/Seg/DirectionalScanner/directionalscannero8.h b/Code/Seg/DirectionalScanner/directionalscannero8.h
index 0e8bea1..a844476 100755
--- a/Code/Seg/DirectionalScanner/directionalscannero8.h
+++ b/Code/Seg/DirectionalScanner/directionalscannero8.h
@@ -112,6 +112,14 @@ public:
    */
   int nextOnRight (vector<Pt2i> &scan);
 
+  /**
+   * @fn Pt2i locate (const Pt2i &pt) const
+   * \brief Returns the scanner coordinates of the givent point.
+   * Scanner coordinates are the stripe index and the position in the stripe.
+   * @param pt Image coordinates of the point.
+   */
+  virtual Pt2i locate (const Pt2i &pt) const;
+
 private:
 
   /** Current step in strip direction */
diff --git a/Code/Seg/Seg.pro b/Code/Seg/Seg.pro
index c73224c..028b9e8 100644
--- a/Code/Seg/Seg.pro
+++ b/Code/Seg/Seg.pro
@@ -23,6 +23,8 @@ HEADERS += BlurredSegment/biptlist.h \
            BSTools/bsaccumulatoritem.h \
            BSTools/bsaccumulatorview.h \
            BSTools/bsdetectionwidget.h \
+           BSTools/bsidetitem.h \
+           BSTools/bsidetview.h \
            BSTools/bsprofileitem.h \
            BSTools/bsprofileview.h \
            BSTools/bsstructureitem.h \
@@ -62,6 +64,8 @@ SOURCES += main.cpp \
            BSTools/bsaccumulatoritem.cpp \
            BSTools/bsaccumulatorview.cpp \
            BSTools/bsdetectionwidget.cpp \
+           BSTools/bsidetitem.cpp \
+           BSTools/bsidetview.cpp \
            BSTools/bsprofileitem.cpp \
            BSTools/bsprofileview.cpp \
            BSTools/bsstructureitem.cpp \
diff --git a/Code/Seg/main.cpp b/Code/Seg/main.cpp
index db9e83d..30aa3b5 100755
--- a/Code/Seg/main.cpp
+++ b/Code/Seg/main.cpp
@@ -29,6 +29,7 @@ int main (int argc, char *argv[])
       if (string(argv[i]) == string ("-profile")) window.toggleProfWindow ();
       else if (string(argv[i]) == string ("-accu")) window.toggleAccuWindow ();
       else if (string(argv[i]) == string ("-seg")) window.toggleSegWindow ();
+      else if (string(argv[i]) == string ("-idet")) window.toggleIdetWindow ();
       // Test command : time ./Seg -test ../Images/couloir.jpg
       else if (string(argv[i]) == string ("-test")) testing = true;
       else if (string(argv[i]) == string ("-sobel3x3"))
@@ -56,6 +57,7 @@ int main (int argc, char *argv[])
           if (carac == 'p') window.toggleProfWindow ();
           else if (carac == 'a') window.toggleAccuWindow ();
           else if (carac == 's') window.toggleSegWindow ();
+          else if (carac == 'i') window.toggleIdetWindow ();
         }
       }
     }
diff --git a/Methode/ctrl.tex b/Methode/ctrl.tex
index d8d0a05..a19ebc1 100755
--- a/Methode/ctrl.tex
+++ b/Methode/ctrl.tex
@@ -57,6 +57,7 @@ Ctrl-p && Edite la derni\`ere d\'etection dans un fichier seg.txt \\
 1 && Commute la visu des segments (pixels) \\
 2 && Commute la visu de l'accumulateur \\
 3 && Commute la visu des profils \\
+4 && Commute la visu de la d\'etection initiale \\
 0 && Test avec $P_1$ et $P_2$ impos\'es \\
 9 && Test de performance sur la derni\`ere barre trac\'ee \\
 8 && Tests comparatifs sur diff\'erents contextes de d\'etection \\
-- 
GitLab