From bede6e171de2f56d7a5a929706f77557c08ad529 Mon Sep 17 00:00:00 2001
From: even <philippe.even@loria.fr>
Date: Sat, 17 Nov 2018 15:55:28 +0100
Subject: [PATCH] Gradient maps displayed

---
 Code/Seg/BSTools/bsdetectionwidget.cpp |  4 +-
 Code/Seg/BSTools/bsprofileitem.cpp     |  6 +--
 Code/Seg/BSTools/bsstructureview.cpp   | 69 ++++++++++++++++++++++----
 Code/Seg/BSTools/bsstructureview.h     | 48 ++++++++++++------
 Code/Seg/ImageTools/vmap.cpp           |  2 +-
 Code/Seg/ImageTools/vmap.h             |  6 +--
 Methode/ctrl.tex                       |  1 +
 Methode/methode.tex                    | 10 ++++
 8 files changed, 112 insertions(+), 34 deletions(-)

diff --git a/Code/Seg/BSTools/bsdetectionwidget.cpp b/Code/Seg/BSTools/bsdetectionwidget.cpp
index 513df2c..fc57ea0 100755
--- a/Code/Seg/BSTools/bsdetectionwidget.cpp
+++ b/Code/Seg/BSTools/bsdetectionwidget.cpp
@@ -66,7 +66,7 @@ QSize BSDetectionWidget::openImage (const QString &fileName, int type)
  
   update ();
   if (profileview != NULL) profileview->setImage (&loadedImage, gMap);
-  if (strucview != NULL) strucview->setGradientImage (gMap);
+  if (strucview != NULL) strucview->setGradientMap (gMap);
 
   return newSize;
 }
@@ -173,7 +173,7 @@ void BSDetectionWidget::switchPixelAnalyzer ()
   else
   {
     strucview = new BSStructureView (&loadedImage, &detector);
-    strucview->setGradientImage (gMap);
+    strucview->setGradientMap (gMap);
     strucview->show ();
   }
 }
diff --git a/Code/Seg/BSTools/bsprofileitem.cpp b/Code/Seg/BSTools/bsprofileitem.cpp
index 29d1832..d6133ca 100755
--- a/Code/Seg/BSTools/bsprofileitem.cpp
+++ b/Code/Seg/BSTools/bsprofileitem.cpp
@@ -817,7 +817,7 @@ void BSProfileItem::paintGradientProfile (QPainter *painter)
              << imageHeight - 1 - (*it).y () << ")" << endl;
       else
       {
-        h = (gMap->sqNorm ((*it).x (), (*it).y ()) - gradientLow)
+        h = (gMap->magn ((*it).x (), (*it).y ()) - gradientLow)
             / gradientUnRatio;
         if (h < 0) h = 0;
         else if (h > widHeight) h = widHeight;
@@ -830,14 +830,14 @@ void BSProfileItem::paintGradientProfile (QPainter *painter)
     painter->setPen (QPen (Qt::black, 2));
     scan = leftscan.at (0);
     it = scan.begin ();
-    prevh = (gMap->sqNorm ((*it).x (), (*it).y ()) - gradientLow)
+    prevh = (gMap->magn ((*it).x (), (*it).y ()) - gradientLow)
             / gradientUnRatio;
     if (prevh < 0) prevh = 0;
     else if (prevh > widWidth) prevh = widWidth;
     cx = 0;
     while (it != scan.end ())
     {
-      h = (gMap->sqNorm ((*it).x (), (*it).y ()) - gradientLow)
+      h = (gMap->magn ((*it).x (), (*it).y ()) - gradientLow)
           / gradientUnRatio;
       if (h < 0) h = 0;
       else if (h > widWidth) h = widWidth;
diff --git a/Code/Seg/BSTools/bsstructureview.cpp b/Code/Seg/BSTools/bsstructureview.cpp
index 983eea1..443a178 100755
--- a/Code/Seg/BSTools/bsstructureview.cpp
+++ b/Code/Seg/BSTools/bsstructureview.cpp
@@ -14,13 +14,15 @@ BSStructureView::BSStructureView (QImage *im, BSDetector *sd)
   int w = im->width ();
   int h = im->height ();
   imageInBack = true;
+  gradDir = 0;
+  gMap = NULL;
   gradImage = NULL;
   gradInBack = false;
   setBackgroundBrush (QBrush (*currentImage));
   setScene (new QGraphicsScene (0, 0, w, h));
   grid = new BSStructureItem (w, h, im, sd);
   scene()->addItem (grid);
-  setWindowTitle (grid->itemTitle ());
+  setWindowTitle (grid->itemTitle () + backgroundSource ());
 }
 
 
@@ -32,26 +34,44 @@ BSStructureView::~BSStructureView ()
 }
 
 
-void BSStructureView::setGradientImage (VMap *gMap)
+void BSStructureView::setGradientMap (VMap *gmap)
 {
+  this->gMap = gmap;
+}
+
+
+void BSStructureView::updateGradientImage ()
+{
+  if (gMap == NULL) return;
   if (gradImage != NULL) delete gradImage;
   int w = gMap->getWidth ();
   int h = gMap->getHeight ();
   double gn[w * h];
   for (int j = 0; j < h; j++)
     for (int i = 0; i < w; i++)
-      gn[j * w + i] = gMap->cmpNorm (i, j);
-      // gn[j * w + i] = sqrt (gMap->sqNorm (i, j));
-  double max = 0;
-  for (int i = 0; i < w * h; i++) if (max < gn[i]) max = gn[i];
+    {
+      if (gradDir == 2)
+        gn[j * w + i] = gMap->getValue(i,j).y ();
+      else if (gradDir == 1)
+        gn[j * w + i] = gMap->getValue(i,j).x ();
+      else
+        gn[j * w + i] = gMap->magn (i, j);
+    }
+  double min = gn[0];
+  double max = gn[0];
+  for (int i = 1; i < w * h; i++)
+  {
+    if (max < gn[i]) max = gn[i];
+    if (min > gn[i]) min = gn[i]; 
+  }
   gradImage = new QImage (w, h, QImage::Format_RGB32);
   for (int j = 0; j < h; j++)
     for (int i = 0; i < w; i++)
     {
-      uint val = (uint) (gn[(h - 1 - j) * w + i] * 255 / max);
+      int val = (int) ((gn[(h - 1 - j) * w + i] - min) * 255 / (max - min));
       gradImage->setPixel (i, j, val + val * 256 + val * 256 * 256);
     }
-  // gradImage->save ("gradient.png");
+  // gradImage->save ("hgradient.png");
 }
 
 
@@ -83,7 +103,33 @@ void BSStructureView::toggleBackground ()
 void BSStructureView::toggleGradient ()
 {
   if (currentImage == gradImage) currentImage = graylevelImage;
-  else if (gradImage != NULL) currentImage = gradImage;
+  else
+  {
+    if (gradImage == NULL) updateGradientImage ();
+    currentImage = gradImage;
+  }
+  setWindowTitle (grid->itemTitle () + backgroundSource ());
+}
+
+
+void BSStructureView::toggleGradientType ()
+{
+  if (++gradDir == 3) gradDir = 0;
+  if (currentImage == gradImage)
+  {
+    updateGradientImage ();
+    currentImage = gradImage;
+  }
+  setWindowTitle (grid->itemTitle () + backgroundSource ());
+}
+
+
+QString BSStructureView::backgroundSource () const
+{
+    if (currentImage != gradImage) return ("");
+    else if (gradDir == 2) return (" (on gradient Y)");
+    else if (gradDir == 1) return (" (on gradient X)");
+    return (" (on gradient Magn)");
 }
 
 
@@ -105,7 +151,7 @@ bool BSStructureView::processKeyEvent (QKeyEvent *event)
     case Qt::Key_I : // Info
       if (event->modifiers () & Qt::ControlModifier) grid->switchScanDisplay ();
       else grid->toggleDisplay ((event->modifiers () & Qt::ShiftModifier) == 0);
-      setWindowTitle (grid->itemTitle ());
+      setWindowTitle (grid->itemTitle () + backgroundSource ());
       scene()->update ();
       update ();
       processed = false;
@@ -119,7 +165,8 @@ bool BSStructureView::processKeyEvent (QKeyEvent *event)
       break;
 
     case Qt::Key_B : // Background
-      if (event->modifiers () & Qt::ShiftModifier) toggleGradient ();
+      if (event->modifiers () & Qt::ControlModifier) toggleGradientType ();
+      else if (event->modifiers () & Qt::ShiftModifier) toggleGradient ();
       else toggleBackground ();
       updateBackground (true);
       scene()->update ();
diff --git a/Code/Seg/BSTools/bsstructureview.h b/Code/Seg/BSTools/bsstructureview.h
index 2c905a0..81ea5a9 100755
--- a/Code/Seg/BSTools/bsstructureview.h
+++ b/Code/Seg/BSTools/bsstructureview.h
@@ -22,25 +22,16 @@ public:
   ~BSStructureView ();
 
   /**
-   * Sets the gradient image.
+   * Sets the reference to the used gradient map.
+   * @param gMap Reference to the used gradient map.
    */
-  void setGradientImage (VMap *gMap);
+  void setGradientMap (VMap *gMap);
 
   /**
    * Sets the examined segment from a multi-selection.
    */
   inline void setExamined (int index) { grid->setExamined (index); }
 
-  /**
-   * Toggles the window background between the current image or plain white.
-   */
-  void toggleBackground ();
-
-  /**
-   * Toggles the current image between gray level or gradient image.
-   */
-  void toggleGradient ();
-
   /**
    * \brief Redraws the pixel analyzer.
    */
@@ -67,10 +58,14 @@ private:
   QImage image;
   /** Background image display modality. */
   bool imageInBack;
-  /** Pointer to the gradient image. */
-  QImage *currentImage;
   /** Pointer to the currently displayed image. */
+  QImage *currentImage;
+  /** Reference to the used gradient map. */
+  VMap *gMap;
+  /** Pointer to the gradient image. */
   QImage *gradImage;
+  /** Type of gradient image displayed (magnitude, horizontal or vertical). */
+  int gradDir;
   /** Gradient image display modality. */
   bool gradInBack;
 
@@ -80,6 +75,31 @@ private:
    */
   void updateBackground (bool zoomChanged);
 
+  /**
+   * Gets the background source
+   */
+  QString backgroundSource () const;
+
+  /**
+   * Updates the gradient image according to gradient type displayed.
+   */
+  void updateGradientImage ();
+
+  /**
+   * Toggles the window background between the current image or plain white.
+   */
+  void toggleBackground ();
+
+  /**
+   * Toggles the current image between gray level or gradient image.
+   */
+  void toggleGradient ();
+
+  /**
+   * Toggles the displayed gradient image (magnitude, horizontal or vertical).
+   */
+  void toggleGradientType ();
+
 };
 
 #endif
diff --git a/Code/Seg/ImageTools/vmap.cpp b/Code/Seg/ImageTools/vmap.cpp
index e25e805..b2839d6 100755
--- a/Code/Seg/ImageTools/vmap.cpp
+++ b/Code/Seg/ImageTools/vmap.cpp
@@ -518,7 +518,7 @@ int VMap::localMax (int *lmax, const vector<Pt2i> &pix, const Vr2i &gref) const
   int *gn = new int[n];
   int i = 0;
   vector<Pt2i>::const_iterator it = pix.begin ();
-  while (it != pix.end ()) gn[i++] = cmpNorm (*it++);
+  while (it != pix.end ()) gn[i++] = magn (*it++);
 
   // Gets the local maxima
   int count = searchLocalMax (lmax, n, gn);
diff --git a/Code/Seg/ImageTools/vmap.h b/Code/Seg/ImageTools/vmap.h
index bb3f6e7..6d9e724 100755
--- a/Code/Seg/ImageTools/vmap.h
+++ b/Code/Seg/ImageTools/vmap.h
@@ -128,13 +128,13 @@ public:
    * @param i Column number.
    * @param j Line number.
    */
-  inline int cmpNorm (int i, int j) const { return (imap[j * width + i]); }
+  inline int magn (int i, int j) const { return (imap[j * width + i]); }
 
   /**
    * \brief Returns the comparable norm of the vector magnitude at given point.
    * @param p Point position.
    */
-  inline int cmpNorm (Pt2i p) const { return (imap[p.y () * width + p.x ()]); }
+  inline int magn (Pt2i p) const { return (imap[p.y () * width + p.x ()]); }
 
   /** 
    * \brief Returns the index of the largest vector at given positions.
@@ -246,7 +246,7 @@ private:
   int height;
   /** Vector map. */
   Vr2i *map;
-  /** Intensity map (squarred norm or morphologicalgradient). */
+  /** Magnitude map (squarred norm or morphologicalgradient). */
   int *imap;
 
   /** Occupancy mask. */
diff --git a/Methode/ctrl.tex b/Methode/ctrl.tex
index 51f8c44..d8d0a05 100755
--- a/Methode/ctrl.tex
+++ b/Methode/ctrl.tex
@@ -69,6 +69,7 @@ v && Commute l'affichage du texte \\
 Ctrl-i && Commute le type d'affichage des scans \\
 b && Commute l'affichage de l'image de fond \\
 B && Commute l'image d'intensit\'e avec celle du gradient \\
+Ctrl-b && Commute le type de gradient affich\'e (magnitude, X ou Y) \\
 c && Incr\'emente la longueur minimale des composantes connexes \\
 + -- && Zoom \\
 $< \wedge > \vee$ && D\'ecalage de l'observation \\
diff --git a/Methode/methode.tex b/Methode/methode.tex
index 6fc8e93..ce9290f 100755
--- a/Methode/methode.tex
+++ b/Methode/methode.tex
@@ -216,4 +216,14 @@ isol\'es \`a l'\'ecart du segment.
 \end{itemize}
 \end{itemize}
 
+\subsection*{Epaisseurs consid\'er\'ees}
+
+Les \'epaisseurs de segments d\'efinies sont la plus petite valeur de
+l'\'epaisseur verticale ou de l'\'epaisseur horizontale.
+Les droites discr\`etes \'etant d\'efinies par
+$c \leq ax + by < c + \nu$, cette \'epaisseur se d\'efinit par
+$\epsilon = \nu / max (|a|, |b|)$.
+C'est aussi la plus petite valeur des \'epaisseurs des paires antipodales.
+A ne pas confondre avec la largeur des barres de balayage ({\it scans}).
+
 \end{document}
-- 
GitLab