From a8b21264e63c3a60bd8bb5b7443597b22bd8af9f Mon Sep 17 00:00:00 2001
From: even <philippe.even@loria.fr>
Date: Wed, 17 Apr 2019 14:31:11 +0200
Subject: [PATCH] Missing files

---
 Article/main.tex                              |   4 +-
 Code/FBSD/BSTools/bscannyitem.cpp             | 179 +++++++++++
 Code/FBSD/BSTools/bscannyitem.h               | 113 +++++++
 Code/FBSD/BSTools/bscannyview.cpp             |  51 ++++
 Code/FBSD/BSTools/bscannyview.h               |  52 ++++
 Code/FBSD/BSTools/bsdetectionwidget.h         |   7 +-
 Code/FBSD/BSTools/bsstructureview.h           |   3 +-
 Code/FBSD/BSTools/bsyorkitem.cpp              | 283 ++++++++++++++++++
 Code/FBSD/BSTools/bsyorkitem.h                | 155 ++++++++++
 Code/FBSD/BSTools/bsyorkview.cpp              |  62 ++++
 Code/FBSD/BSTools/bsyorkview.h                |  52 ++++
 Code/FBSD/BSTools/extlines.cpp                | 186 ++++++++++++
 Code/FBSD/BSTools/extlines.h                  | 104 +++++++
 Code/FBSD/BlurredSegment/bsdetector.h         |   6 +
 Code/FBSD/FBSD.pro                            |  10 +
 Code/FBSD/ImageTools/digitalstraightline.h    |   8 +
 .../ImageTools/digitalstraightsegment.cpp     |  23 ++
 Code/FBSD/ImageTools/digitalstraightsegment.h |  19 ++
 Code/FBSD/main.cpp                            |  44 ++-
 19 files changed, 1354 insertions(+), 7 deletions(-)
 create mode 100755 Code/FBSD/BSTools/bscannyitem.cpp
 create mode 100755 Code/FBSD/BSTools/bscannyitem.h
 create mode 100755 Code/FBSD/BSTools/bscannyview.cpp
 create mode 100755 Code/FBSD/BSTools/bscannyview.h
 create mode 100755 Code/FBSD/BSTools/bsyorkitem.cpp
 create mode 100755 Code/FBSD/BSTools/bsyorkitem.h
 create mode 100755 Code/FBSD/BSTools/bsyorkview.cpp
 create mode 100755 Code/FBSD/BSTools/bsyorkview.h
 create mode 100755 Code/FBSD/BSTools/extlines.cpp
 create mode 100755 Code/FBSD/BSTools/extlines.h

diff --git a/Article/main.tex b/Article/main.tex
index 38dedd3..a562d75 100755
--- a/Article/main.tex
+++ b/Article/main.tex
@@ -51,11 +51,11 @@
 
   \end{frontmatter}
 	
-	\input{intro}
+	\input{introV2}
 	
 	\input{notions}
 	
-	\input{method}
+	\input{methodV2}
 	
 	\input{expe}
 	
diff --git a/Code/FBSD/BSTools/bscannyitem.cpp b/Code/FBSD/BSTools/bscannyitem.cpp
new file mode 100755
index 0000000..6715820
--- /dev/null
+++ b/Code/FBSD/BSTools/bscannyitem.cpp
@@ -0,0 +1,179 @@
+#include <QtGui>
+#include <iostream>
+#include <fstream>
+#include "bscannyitem.h"
+#include "pt2i.h"
+
+using namespace std;
+
+
+const int BSCannyItem::ALONE = 0;
+const int BSCannyItem::WITH_BS = 1;
+const int BSCannyItem::WITH_DSS = 2;
+const QColor BSCannyItem::BS_COLOR = Qt::blue;
+const QColor BSCannyItem::CANNY_COLOR = Qt::green;
+const QColor BSCannyItem::BOTH_COLOR = Qt::red;
+const int BSCannyItem::DEFAULT_PEN_WIDTH = 1;
+
+
+BSCannyItem::BSCannyItem (int width, int height, const QImage *im,
+                          BSDetector *detector)
+{
+  w = width;
+  h = height;
+  int size = w * h;
+  this->im = im;
+  bsmap = new bool[size];
+  clmap = new bool[size];
+  det = detector;
+  type = ALONE;
+  int nb = readCannyLines ();
+  cout << nb << " cannys" << endl;
+}
+
+
+BSCannyItem::~BSCannyItem ()
+{
+  delete [] bsmap;
+}
+
+
+QRectF BSCannyItem::boundingRect () const
+{
+  return QRectF (0, 0, w - 1, h - 1); // ZZZ
+}
+
+
+void BSCannyItem::paint (QPainter *painter,
+                         const QStyleOptionGraphicsItem *option,
+                         QWidget *widget)
+{
+  Q_UNUSED (option);
+  Q_UNUSED (widget);
+
+  if (type == WITH_BS) drawBS (painter);
+  else if (type == WITH_DSS) drawDSS (painter);
+  drawCannyLines (painter);
+  int nboth = 0, ncl = 0, nbs = 0;
+  for (int i = 0; i < w * h; i++)
+    if (clmap[i])
+      if (bsmap[i]) nboth++;
+      else ncl++;
+    else if (bsmap[i]) nbs++;
+  cout << nboth << " both, " << ncl << " canny, " << nbs << " bs" << endl;
+}
+
+
+int BSCannyItem::readCannyLines ()
+{
+  double val[5];
+  int i = 0, nb = 0;
+  ifstream input ("/home/even/cannyLinesModif/cannylines.txt", ios::in);
+  bool reading = true;
+  if (input)
+  {
+    while (reading)
+    {
+      input >> val[i];
+      if (input.eof ()) reading = false;
+      if (++i == 5)
+      {
+        CannyLine cl;
+        cl.xs = (int) (val[0] + 0.5);
+        cl.ys = h - 1 - (int) (val[1] + 0.5);
+        cl.xe = (int) (val[2] + 0.5);
+        cl.ye = h - 1 - (int) (val[3] + 0.5);
+        cl.id = (int) (val[4] + 0.5);
+        cannys.push_back (cl);
+        i = 0;
+        nb++;
+      }
+    }
+  }
+  
+return (nb);
+}
+
+
+void BSCannyItem::drawBS (QPainter *painter)
+{
+  painter->setPen (QPen (BS_COLOR, DEFAULT_PEN_WIDTH, Qt::SolidLine,
+                         Qt::RoundCap, Qt::RoundJoin));
+  for (int i = 0; i < w * h; i++) bsmap[i] = false;
+  vector<BlurredSegment *> bss = det->getBlurredSegments ();
+  if (! bss.empty ())
+  {
+    vector<BlurredSegment *>::const_iterator it = bss.begin ();
+    while (it != bss.end ())
+    {
+      if (*it != NULL) drawPoints (painter, (*it)->getAllPoints ());
+      it++;
+    }
+  }
+}
+
+
+void BSCannyItem::drawDSS (QPainter *painter)
+{
+  painter->setPen (QPen (BS_COLOR, DEFAULT_PEN_WIDTH, Qt::SolidLine,
+                         Qt::RoundCap, Qt::RoundJoin));
+  for (int i = 0; i < w * h; i++) bsmap[i] = false;
+  vector<BlurredSegment *> bss = det->getBlurredSegments ();
+  if (! bss.empty ())
+  {
+    vector<BlurredSegment *>::const_iterator it = bss.begin ();
+    while (it != bss.end ())
+    {
+      if ((*it) != NULL)
+      {
+        DigitalStraightSegment *dss = (*it)->getSegment ();
+        if (dss != NULL)
+        {
+          vector<Pt2i> pts;
+          dss->getPoints (pts);
+          drawPoints (painter, pts);
+        }  
+      }
+      it++;
+    }
+  }
+}
+
+
+void BSCannyItem::drawPoints (QPainter *painter, vector<Pt2i> pts)
+{
+  vector<Pt2i>::iterator iter = pts.begin ();
+  while (iter != pts.end ())
+  {
+    Pt2i p = *iter++;
+    if (p.x() < w && p.y() < h && p.x() >= 0 && p.y() >= 0)
+    {
+      bsmap[p.y()*w+p.x()] = true;
+      painter->drawPoint (QPoint (p.x(), h - 1 - p.y()));  // dec 1
+    }
+  }
+}
+
+
+void BSCannyItem::drawCannyLines (QPainter *painter)
+{
+  int n = 0;
+  Pt2i *pts = NULL;
+  vector<CannyLine>::iterator it = cannys.begin ();
+  while (it != cannys.end ())
+  {
+    pts = Pt2i (it->xs, it->ys).drawing (Pt2i (it->xe, it->ye), &n);
+    for (int i = 0; i < n; i++)
+    {
+      painter->setPen (QPen (bsmap[pts[i].y()*w+pts[i].x()] ?
+                             BOTH_COLOR : CANNY_COLOR,
+                         DEFAULT_PEN_WIDTH, Qt::SolidLine,
+                         Qt::RoundCap, Qt::RoundJoin));
+      painter->drawPoint (QPoint (pts[i].x (),
+                                  h - 1 - pts[i].y ()));  // dec 1
+      clmap[pts[i].y()*w+pts[i].x()] = true;
+    }
+    delete [] pts;
+    it++;
+  }
+}
diff --git a/Code/FBSD/BSTools/bscannyitem.h b/Code/FBSD/BSTools/bscannyitem.h
new file mode 100755
index 0000000..39443ca
--- /dev/null
+++ b/Code/FBSD/BSTools/bscannyitem.h
@@ -0,0 +1,113 @@
+#ifndef BS_CANNY_ITEM_H
+#define BS_CANNY_ITEM_H
+
+#include <QGraphicsItem>
+#include "bsdetector.h"
+
+using namespace std;
+
+
+/** 
+ * @class BSCannyItem bscannyitem.h
+ * \brief Blurred segment comparator with CannyLine.
+ * \author {P. Even}
+ */
+class BSCannyItem : public QGraphicsItem
+{
+public:
+
+  /**
+   * \brief Creates a CannyLine comparator.
+   */
+  BSCannyItem (int width, int height, const QImage *im, BSDetector *detector);
+
+  /**
+   * \brief Deletes the CannyLine comparator.
+   */
+  ~BSCannyItem ();
+
+  /**
+   * \brief Returns the grid area.
+   */
+  QRectF boundingRect () const;
+
+  /**
+   * \brief Redraws the CannyLine comparator grid.
+   */
+  void paint (QPainter *painter,
+              const QStyleOptionGraphicsItem *option, QWidget *widget);
+
+  /**
+   * \brief Toggles display modality.
+   */
+  inline void toggleType () { if (++type == 3) type = 0; }
+
+
+
+private:
+
+  /** Canny lines alone display modality. */
+  static const int ALONE;
+  /** With BS display modality. */
+  static const int WITH_BS;
+  /** With DSS display modality. */
+  static const int WITH_DSS;
+  /** Default color for blurred segments. */
+  static const QColor BS_COLOR;
+  /** Default color for Canny lines. */
+  static const QColor CANNY_COLOR;
+  /** Default color for both tools. */
+  static const QColor BOTH_COLOR;
+  /** Default value for pen width. */
+  static const int DEFAULT_PEN_WIDTH;
+
+  /** Aggregation of segment extraction results with initial conditions. */
+  struct CannyLine
+  {
+    /** Canny line start point X coordinate. */
+    int xs;
+    /** Canny line start point Y coordinate. */
+    int ys;
+    /** Canny line end point X coordinate. */
+    int xe;
+    /** Canny line end point Y coordinate. */
+    int ye;
+    /** Canny line identifier. */
+    int id;
+  };
+  /** List of Canny lines. */
+  vector<CannyLine> cannys;
+
+  /** Background image. */
+  const QImage *im;
+  /** Grid width. */
+  int w;
+  /** Grid height. */
+  int h;
+  /** Segment detector. */
+  BSDetector *det;
+  /** Blurred segments map */
+  bool *bsmap;
+  /** Canny lines map */
+  bool *clmap;
+  /** Display modality */
+  int type;
+
+  /** Reads Canny lines file */
+  int readCannyLines ();
+
+  /** Displays blurred segments points */
+  void drawBS (QPainter *painter);
+
+  /** Displays blurred segments DSS */
+  void drawDSS (QPainter *painter);
+
+  /** Displays a set of points */
+  void drawPoints (QPainter *painter, vector<Pt2i> pts);
+
+  /** Displays Canny lines */
+  void drawCannyLines (QPainter *painter);
+
+};
+
+#endif
diff --git a/Code/FBSD/BSTools/bscannyview.cpp b/Code/FBSD/BSTools/bscannyview.cpp
new file mode 100755
index 0000000..f12bc68
--- /dev/null
+++ b/Code/FBSD/BSTools/bscannyview.cpp
@@ -0,0 +1,51 @@
+#include <QtGui>
+#include <iostream>
+#include "bscannyview.h"
+#include "math.h"
+
+using namespace std;
+
+
+BSCannyView::BSCannyView (QImage *im, BSDetector *sd)
+{
+  int w = im->width ();
+  int h = im->height ();
+  image = im;
+  setScene (new QGraphicsScene (0, 0, w, h));
+  canny = new BSCannyItem (w, h, image, sd);
+  //setBackgroundBrush (QBrush (*image));
+  scene()->addItem (canny);
+  setWindowTitle ("CannyLine comparator");
+}
+
+
+BSCannyView::~BSCannyView ()
+{
+  scene()->removeItem (canny);
+  delete canny;
+}
+
+
+void BSCannyView::paint (QPainter *painter,
+                         const QStyleOptionGraphicsItem *option,
+                         QWidget *widget)
+{
+  Q_UNUSED (painter);
+  Q_UNUSED (option);
+  Q_UNUSED (widget);
+}
+
+
+bool BSCannyView::processKeyEvent (QKeyEvent *event)
+{
+  bool processed = false;
+  switch (event->key ())
+  {
+    case Qt::Key_I : // Info
+      canny->toggleType ();
+      scene()->update ();
+      update ();
+      break;
+  }
+  return processed;
+}
diff --git a/Code/FBSD/BSTools/bscannyview.h b/Code/FBSD/BSTools/bscannyview.h
new file mode 100755
index 0000000..16ce9ca
--- /dev/null
+++ b/Code/FBSD/BSTools/bscannyview.h
@@ -0,0 +1,52 @@
+#ifndef BS_CANNY_VIEW_H
+#define BS_CANNY_VIEW_H
+
+#include <QGraphicsView>
+#include <QImage>
+#include "bscannyitem.h"
+
+
+/** 
+ * @class BSCannyView bscannyview.h
+ * \brief A Qt window to compare detected segments with CannyLines.
+ * \author {P. Even}
+ */
+class BSCannyView : public QGraphicsView
+{
+
+public:
+
+  /**
+   * \brief Creates a CannyLine comparator view.
+   */
+  BSCannyView (QImage *im, BSDetector *sd);
+
+  /**
+   * \brief Deletes the CannyLine comparator view.
+   */
+  ~BSCannyView ();
+
+  /**
+   * \brief Redraws the CannyLine comparator view.
+   */
+  void paint (QPainter *painter,
+              const QStyleOptionGraphicsItem *option, QWidget *widget);
+
+  /**
+   * \brief Processes key pressed events.
+   */
+  bool processKeyEvent (QKeyEvent *event);
+
+
+protected:
+
+private:
+
+  /** Pointer to the blurred segment structure graphics item. */
+  BSCannyItem *canny;
+  /** Pointer to the displayed image. */
+  QImage *image;
+
+};
+
+#endif
diff --git a/Code/FBSD/BSTools/bsdetectionwidget.h b/Code/FBSD/BSTools/bsdetectionwidget.h
index 1ea42d0..53dad09 100755
--- a/Code/FBSD/BSTools/bsdetectionwidget.h
+++ b/Code/FBSD/BSTools/bsdetectionwidget.h
@@ -12,7 +12,8 @@
 #include "bsstructureview.h"
 #include "bsprofileview.h"
 #include "bsidetview.h"
-//#include "bscannyview.h"
+#include "bscannyview.h"
+#include "bsyorkview.h"
 
 using namespace std;
 
@@ -304,7 +305,9 @@ private:
   /** Blurred segment contents view. */
   BSStructureView *strucview;
   /** CannyLine comparator view. */
-  // BSCannyView *cannyview;
+  BSCannyView *cannyview;
+  /** YorkLine comparator view. */
+  BSYorkView *yorkview;
 
   /** Aggregation of segment extraction results with initial conditions. */
   struct ExtractedSegment
diff --git a/Code/FBSD/BSTools/bsstructureview.h b/Code/FBSD/BSTools/bsstructureview.h
index 72df9db..dd784e2 100755
--- a/Code/FBSD/BSTools/bsstructureview.h
+++ b/Code/FBSD/BSTools/bsstructureview.h
@@ -75,8 +75,7 @@ private:
   int blevel;
 
   /**
-   
-* Updates the background image.
+   * Updates the background image.
    */
   void updateBackground ();
 
diff --git a/Code/FBSD/BSTools/bsyorkitem.cpp b/Code/FBSD/BSTools/bsyorkitem.cpp
new file mode 100755
index 0000000..38f7c13
--- /dev/null
+++ b/Code/FBSD/BSTools/bsyorkitem.cpp
@@ -0,0 +1,283 @@
+#include <QtGui>
+#include <iostream>
+#include <fstream>
+#include "bsyorkitem.h"
+#include "pt2i.h"
+
+using namespace std;
+
+
+const int BSYorkItem::YORK_ALONE = 0;
+const int BSYorkItem::CANNY_ALONE = 1;
+const int BSYorkItem::DILATED_CANNY_ALONE = 2;
+const int BSYorkItem::YORK_OVER_CANNY = 3;
+const int BSYorkItem::YORK_OVER_BS = 4;
+const int BSYorkItem::YORK_OVER_DSS = 5;
+const int BSYorkItem::YORK_WITH_CANNY = 6;
+const int BSYorkItem::YORK_WITH_DSS = 7;
+const int BSYorkItem::NO_INFO = 8;
+const QColor BSYorkItem::OVER_COLOR = Qt::lightGray;
+const QColor BSYorkItem::UNDER_COLOR = Qt::yellow;
+const QColor BSYorkItem::BOTH_COLOR = Qt::black;
+const int BSYorkItem::DEFAULT_PEN_WIDTH = 1;
+
+
+BSYorkItem::BSYorkItem (int width, int height, const QImage *im,
+                          BSDetector *detector)
+{
+  w = width;
+  h = height;
+  int size = w * h;
+  this->im = im;
+  bsmap = new bool[size];
+  clmap = new bool[size];
+  det = detector;
+  type = YORK_ALONE;
+  cannyDilation = 0;
+  yorks = new ExtLines ("yorklines.txt", w, h);
+  cannys = new ExtLines ("cannylines.txt", w, h, 5);
+}
+
+
+BSYorkItem::~BSYorkItem ()
+{
+  delete [] bsmap;
+}
+
+
+QRectF BSYorkItem::boundingRect () const
+{
+  return QRectF (0, 0, w - 1, h - 1); // ZZZ
+}
+
+
+void BSYorkItem::paint (QPainter *painter,
+                         const QStyleOptionGraphicsItem *option,
+                         QWidget *widget)
+{
+  Q_UNUSED (option);
+  Q_UNUSED (widget);
+
+  for (int i = 0; i < w * h; i++) bsmap[i] = false;
+  if (type == YORK_ALONE) drawYorkLines (painter);
+  else if (type == CANNY_ALONE) drawCannyLines (painter);
+  else if (type == DILATED_CANNY_ALONE) drawDilatedCannyLines (painter);
+  else if (type == YORK_OVER_CANNY)
+  {
+    drawCannyLines (painter);
+    drawYorkLines (painter);
+  }
+  else if (type == YORK_OVER_BS)
+  {
+    drawBS (painter);
+    drawYorkLines (painter);
+  }
+  else if (type == YORK_OVER_DSS)
+  {
+    drawDSS (painter);
+    drawYorkLines (painter);
+  }
+  else if (type == YORK_WITH_CANNY)
+  {
+    drawCannyLines (painter, false);
+    drawYorkLines (painter);
+  }
+  else if (type == YORK_WITH_DSS)
+  {
+    drawDSS (painter, false);
+    drawYorkLines (painter);
+  }
+  else drawYorkLines (painter);
+  int nboth = 0, ncl = 0, nbs = 0;
+  for (int i = 0; i < w * h; i++)
+    if (clmap[i])
+      if (bsmap[i]) nboth++;
+      else ncl++;
+    else if (bsmap[i]) nbs++;
+  cout << nboth << " both, " << ncl << " york, " << nbs << " bs" << endl;
+}
+
+
+void BSYorkItem::drawBS (QPainter *painter)
+{
+  painter->setPen (QPen (UNDER_COLOR, DEFAULT_PEN_WIDTH, Qt::SolidLine,
+                         Qt::RoundCap, Qt::RoundJoin));
+  vector<BlurredSegment *> bss = det->getBlurredSegments ();
+  if (! bss.empty ())
+  {
+    vector<BlurredSegment *>::const_iterator it = bss.begin ();
+    while (it != bss.end ())
+    {
+      if (*it != NULL) drawPoints (painter, (*it)->getAllPoints ());
+      it++;
+    }
+  }
+}
+
+
+void BSYorkItem::drawDSS (QPainter *painter, bool disp)
+{
+  painter->setPen (QPen (UNDER_COLOR, DEFAULT_PEN_WIDTH, Qt::SolidLine,
+                         Qt::RoundCap, Qt::RoundJoin));
+  vector<BlurredSegment *> bss = det->getBlurredSegments ();
+  if (! bss.empty ())
+  {
+    vector<BlurredSegment *>::const_iterator it = bss.begin ();
+    while (it != bss.end ())
+    {
+      if ((*it) != NULL)
+      {
+        DigitalStraightSegment *dss = (*it)->getSegment ();
+        if (dss != NULL)
+        {
+          vector<Pt2i> pts;
+          dss->getPoints (pts);
+          drawPoints (painter, pts, disp);
+        }  
+      }
+      it++;
+    }
+  }
+}
+
+
+void BSYorkItem::drawPoints (QPainter *painter, vector<Pt2i> pts, bool disp)
+{
+  vector<Pt2i>::iterator iter = pts.begin ();
+  while (iter != pts.end ())
+  {
+    Pt2i p = *iter++;
+    if (p.x() < w && p.y() < h && p.x() >= 0 && p.y() >= 0)
+    {
+      bsmap[p.y()*w+p.x()] = true;
+      if (disp) painter->drawPoint (QPoint (p.x(), h - 1 - p.y()));  // dec 1
+    }
+  }
+}
+
+
+void BSYorkItem::drawYorkLines (QPainter *painter)
+{
+  int n = 0;
+  Pt2i *pts = NULL;
+  int nb = yorks->countOfLines ();
+  for (int i = 0; i < nb; i++)
+  {
+    pts = Pt2i (yorks->xStart (i), yorks->yStart (i)).drawing (
+          Pt2i (yorks->xEnd (i), yorks->yEnd (i)), &n);
+    for (int i = 0; i < n; i++)
+    {
+      if (pts[i].x () >= 0 && pts[i].x () < w
+          && pts[i].y () >= 0 && pts[i].y () < h)
+      {
+        painter->setPen (QPen (bsmap[pts[i].y()*w+pts[i].x()] ?
+                               BOTH_COLOR : OVER_COLOR,
+                           DEFAULT_PEN_WIDTH, Qt::SolidLine,
+                           Qt::RoundCap, Qt::RoundJoin));
+        painter->drawPoint (QPoint (pts[i].x (),
+                                    h - 1 - pts[i].y ()));  // dec 1
+        clmap[pts[i].y()*w+pts[i].x()] = true;
+      }
+    }
+    delete [] pts;
+  }
+}
+
+
+void BSYorkItem::drawCannyLines (QPainter *painter, bool disp) {
+  int n = 0;
+  Pt2i *pts = NULL;
+  int nb = cannys->countOfLines ();
+  for (int i = 0; i < nb; i++)
+  {
+    pts = Pt2i (cannys->xStart (i), cannys->yStart (i)).drawing (
+          Pt2i (cannys->xEnd (i), cannys->yEnd (i)), &n);
+    for (int i = 0; i < n; i++)
+    {
+      if (pts[i].x () >= 0 && pts[i].x () < w
+          && pts[i].y () >= 0 && pts[i].y () < h)
+      {
+        if (disp)
+        {
+          painter->setPen (QPen (UNDER_COLOR,
+                             DEFAULT_PEN_WIDTH, Qt::SolidLine,
+                             Qt::RoundCap, Qt::RoundJoin));
+          painter->drawPoint (QPoint (pts[i].x (),
+                                      h - 1 - pts[i].y ()));  // dec 1
+        }
+        bsmap[pts[i].y()*w+pts[i].x()] = true;
+      }
+    }
+    delete [] pts;
+  }
+}
+
+
+void BSYorkItem::drawDilatedCannyLines (QPainter *painter, bool disp)
+{
+  int nb = cannys->countOfLines ();
+  for (int i = 0; i < nb; i++)
+  {
+    int xs = cannys->xStart (i);
+    int ys = cannys->yStart (i);
+    int xe = cannys->xEnd (i);
+    int ye = cannys->yEnd (i);
+    int minx = (xe < xs ? xe : xs);
+    int miny = (ye < ys ? ye : ys);
+    int maxx = (xe < xs ? xs : xe);
+    int maxy = (ye < ys ? ys : ye);
+    DigitalStraightSegment *dss = new DigitalStraightSegment (
+      Pt2i (xs, ys), Pt2i (xe, ye),
+      DigitalStraightLine::DSL_NAIVE, minx, miny, maxx, maxy);
+    vector<Pt2i> points;
+    if (cannyDilation > 0)
+    {
+      int dil = 0;
+      if (cannyDilation == 1) dil = dss->period ();
+      else if (cannyDilation == 2) dil = dss->standard ();
+      else if (cannyDilation == 3) dil = 2 * dss->period ();
+cout << "Dilation of " << dil << endl;
+      dss->dilate (dil);
+    }
+    dss->getPoints (points);
+    vector<Pt2i>::iterator pit = points.begin ();
+    while (pit != points.end ())
+    {
+      if (pit->x () >= 0 && pit->x () < w && pit->y () >= 0 && pit->y () < h)
+      {
+        if (disp)
+        {
+          painter->setPen (QPen (UNDER_COLOR,
+                             DEFAULT_PEN_WIDTH, Qt::SolidLine,
+                             Qt::RoundCap, Qt::RoundJoin));
+          painter->drawPoint (QPoint (pit->x (), h - 1 - pit->y ()));
+        }
+        bsmap[pit->y()*w+pit->x()] = true;
+      }
+      pit ++;
+    }
+    delete dss;
+  }
+}
+
+
+void BSYorkItem::computeBScovering ()
+{
+  det->detectAll ();
+  double fbsdCov = yorks->covering (det->getBlurredSegments ());
+  cout << "FBSD covering : " << fbsdCov << endl;
+  int nb;
+  double lg;
+  double cannyCov = yorks->cannyLineCovering (
+                      "/home/even/tmp/FBSD/cannylines.txt",
+                      nb, lg, det->finalSpreadMinLength ());
+  cout << "Canny lines covering : " << cannyCov << endl;
+
+}
+
+
+bool BSYorkItem::toggleCannyDilation ()
+{
+  if (++cannyDilation == 4) cannyDilation = 0;
+  return (type == DILATED_CANNY_ALONE);
+}
diff --git a/Code/FBSD/BSTools/bsyorkitem.h b/Code/FBSD/BSTools/bsyorkitem.h
new file mode 100755
index 0000000..694be46
--- /dev/null
+++ b/Code/FBSD/BSTools/bsyorkitem.h
@@ -0,0 +1,155 @@
+#ifndef BS_YORK_ITEM_H
+#define BS_YORK_ITEM_H
+
+#include <QGraphicsItem>
+#include "bsdetector.h"
+#include "extlines.h"
+
+using namespace std;
+
+
+/** 
+ * @class BSYorkItem bsyorkitem.h
+ * \brief Blurred segment comparator with YorkLine.
+ * \author {P. Even}
+ */
+class BSYorkItem : public QGraphicsItem
+{
+public:
+
+  /**
+   * \brief Creates a YorkLine comparator.
+   */
+  BSYorkItem (int width, int height, const QImage *im, BSDetector *detector);
+
+  /**
+   * \brief Deletes the YorkLine comparator.
+   */
+  ~BSYorkItem ();
+
+  /**
+   * \brief Returns the grid area.
+   */
+  QRectF boundingRect () const;
+
+  /**
+   * \brief Redraws the YorkLine comparator grid.
+   */
+  void paint (QPainter *painter,
+              const QStyleOptionGraphicsItem *option, QWidget *widget);
+
+  /**
+   * \brief Toggles display modality.
+   */
+  inline void toggleType (bool back) {
+    if (back) { if (--type < 0) type = NO_INFO - 1; }
+    else if (++type == NO_INFO) type = 0; }
+
+  /**
+   * \brief Toggles canny dilation.
+   * Returns if the display should be updated.
+   */
+  bool toggleCannyDilation ();
+
+  /**
+   * \brief Cpomputes and displays blurred segment covering.
+   */
+  void computeBScovering ();
+
+  /**
+   * \brief Returns the displayed information title.
+   */
+  inline QString itemTitle () const {
+    if (type == YORK_ALONE)
+      return ("York Urban DB ground truth");
+    else if (type == DILATED_CANNY_ALONE)
+      return ("Dilated_Canny lines");
+    else if (type == CANNY_ALONE)
+      return ("Canny lines");
+    else if (type == YORK_OVER_CANNY)
+      return ("York over Canny lines");
+    else if (type == YORK_OVER_BS)
+      return ("York over blurred segments points");
+    else if (type == YORK_OVER_DSS)
+      return ("York over digital straight segments");
+    else if (type == YORK_WITH_CANNY)
+      return ("York blend with Canny lines");
+    else if (type == YORK_WITH_DSS)
+      return ("York blend with digital straight lines");
+    else return ("No info");
+  }
+
+
+
+private:
+
+  /** York lines alone display modality. */
+  static const int YORK_ALONE;
+  /** Canny lines alone display modality. */
+  static const int CANNY_ALONE;
+  /** Dilated Canny lines alone display modality. */
+  static const int DILATED_CANNY_ALONE;
+  /** York over Canny display modality. */
+  static const int YORK_OVER_CANNY;
+  /** York over BS display modality. */
+  static const int YORK_OVER_BS;
+  /** York over DSS display modality. */
+  static const int YORK_OVER_DSS;
+  /** York with Canny display modality. */
+  static const int YORK_WITH_CANNY;
+  /** York with DSS display modality. */
+  static const int YORK_WITH_DSS;
+  /** No info display modality. */
+  static const int NO_INFO;
+  /** Default color for first drawn lines. */
+  static const QColor UNDER_COLOR;
+  /** Default color for further drawn lines. */
+  static const QColor OVER_COLOR;
+  /** Default color for both tools. */
+  static const QColor BOTH_COLOR;
+  /** Default value for pen width. */
+  static const int DEFAULT_PEN_WIDTH;
+
+  /** Set of York lines. */
+  ExtLines *yorks;
+  /** Set of Canny lines. */
+  ExtLines *cannys;
+
+  /** Background image. */
+  const QImage *im;
+  /** Grid width. */
+  int w;
+  /** Grid height. */
+  int h;
+  /** Segment detector. */
+  BSDetector *det;
+  /** Blurred segments map */
+  bool *bsmap;
+  /** York lines map */
+  bool *clmap;
+  /** Display modality */
+  int type;
+  /** Type of dilation for Canny lines */
+  int cannyDilation;
+
+  /** Displays blurred segments pixels */
+  void drawBS (QPainter *painter);
+
+  /** Displays blurred segments DSS */
+  void drawDSS (QPainter *painter, bool disp = true);
+
+  /** Displays a set of points */
+  void drawPoints (QPainter *painter, vector<Pt2i> pts, bool disp = true);
+
+  /** Displays York lines */
+  void drawYorkLines (QPainter *painter);
+
+  /** Displays Canny lines */
+  void drawCannyLines (QPainter *painter, bool disp = true);
+
+  /** Displays dilated Canny lines */
+  void drawDilatedCannyLines (QPainter *painter, bool disp = true);
+
+};
+
+#endif
diff --git a/Code/FBSD/BSTools/bsyorkview.cpp b/Code/FBSD/BSTools/bsyorkview.cpp
new file mode 100755
index 0000000..76db756
--- /dev/null
+++ b/Code/FBSD/BSTools/bsyorkview.cpp
@@ -0,0 +1,62 @@
+#include <QtGui>
+#include <iostream>
+#include "bsyorkview.h"
+#include "math.h"
+
+using namespace std;
+
+
+BSYorkView::BSYorkView (QImage *im, BSDetector *sd)
+{
+  int w = im->width ();
+  int h = im->height ();
+  image = im;
+  setScene (new QGraphicsScene (0, 0, w, h));
+  york = new BSYorkItem (w, h, image, sd);
+  //setBackgroundBrush (QBrush (*image));
+  scene()->addItem (york);
+  setWindowTitle (york->itemTitle ());
+}
+
+
+BSYorkView::~BSYorkView ()
+{
+  scene()->removeItem (york);
+  delete york;
+}
+
+
+void BSYorkView::paint (QPainter *painter,
+                         const QStyleOptionGraphicsItem *option,
+                         QWidget *widget)
+{
+  Q_UNUSED (painter);
+  Q_UNUSED (option);
+  Q_UNUSED (widget);
+}
+
+
+bool BSYorkView::processKeyEvent (QKeyEvent *event)
+{
+  bool processed = false;
+  switch (event->key ())
+  {
+    case Qt::Key_I : // Info
+      york->toggleType (event->modifiers () & Qt::ShiftModifier);
+      scene()->update ();
+      update ();
+      setWindowTitle (york->itemTitle ());
+      break;
+    case Qt::Key_D : // Canny dilation
+      if (york->toggleCannyDilation ())
+      {
+        scene()->update ();
+        update ();
+      }
+      break;
+    case Qt::Key_J : // Info
+      york->computeBScovering ();
+      break;
+  }
+  return processed;
+}
diff --git a/Code/FBSD/BSTools/bsyorkview.h b/Code/FBSD/BSTools/bsyorkview.h
new file mode 100755
index 0000000..1739f67
--- /dev/null
+++ b/Code/FBSD/BSTools/bsyorkview.h
@@ -0,0 +1,52 @@
+#ifndef BS_YORK_VIEW_H
+#define BS_YORK_VIEW_H
+
+#include <QGraphicsView>
+#include <QImage>
+#include "bsyorkitem.h"
+
+
+/** 
+ * @class BSYorkView bsyorkview.h
+ * \brief A Qt window to compare detected segments with York Urban image base.
+ * \author {P. Even}
+ */
+class BSYorkView : public QGraphicsView
+{
+
+public:
+
+  /**
+   * \brief Creates a York Urban image database comparator view.
+   */
+  BSYorkView (QImage *im, BSDetector *sd);
+
+  /**
+   * \brief Deletes the York comparator view.
+   */
+  ~BSYorkView ();
+
+  /**
+   * \brief Redraws the York comparator view.
+   */
+  void paint (QPainter *painter,
+              const QStyleOptionGraphicsItem *option, QWidget *widget);
+
+  /**
+   * \brief Processes key pressed events.
+   */
+  bool processKeyEvent (QKeyEvent *event);
+
+
+protected:
+
+private:
+
+  /** Pointer to the blurred segment structure graphics item. */
+  BSYorkItem *york;
+  /** Pointer to the displayed image. */
+  QImage *image;
+
+};
+
+#endif
diff --git a/Code/FBSD/BSTools/extlines.cpp b/Code/FBSD/BSTools/extlines.cpp
new file mode 100755
index 0000000..14a599f
--- /dev/null
+++ b/Code/FBSD/BSTools/extlines.cpp
@@ -0,0 +1,186 @@
+#include <iostream>
+#include <fstream>
+#include <cmath>
+#include "extlines.h"
+
+using namespace std;
+
+
+const int ExtLines::COV_DILATION = 4;
+
+
+ExtLines::ExtLines (const char * name, int width, int height, int nbinfo)
+{
+  this->width = width;
+  this->height = height;
+
+  double val[nbinfo];
+  int i = 0, nb = 0;
+  ifstream input (name, ios::in);
+  bool reading = true;
+  if (input)
+  {
+    while (reading)
+    {
+      input >> val[i];
+      if (input.eof ()) reading = false;
+      if (++i == nbinfo)
+      {
+        ExtLine cl;
+        cl.sx = val[0];
+        cl.sy = height - 1 - val[1];
+        cl.ex = val[2];
+        cl.ey = height - 1 - val[3];
+        exts.push_back (cl);
+        i = 0;
+        nb++;
+      }
+    }
+  }
+}
+
+
+ExtLines::~ExtLines ()
+{
+}
+
+
+double ExtLines::covering (const vector<BlurredSegment *> &segs) const
+{
+  bool cmap[width * height];
+  for (int i = 0; i < width * height; i++) cmap[i] = false;
+  vector<BlurredSegment *>::const_iterator it = segs.begin ();
+  while (it != segs.end ())
+  {
+    DigitalStraightSegment *dss1 = (*it)->getSegment ();
+    if (dss1 != NULL)
+    {
+      DigitalStraightSegment *dss = dss1->dilation (dss1->standard ());
+      vector<Pt2i> points;
+      dss->getPoints (points);
+      vector<Pt2i>::iterator pit = points.begin ();
+      while (pit != points.end ())
+      {
+        if (pit->x () >= 0 && pit->x () < width
+            && pit->y () >= 0 && pit->y () < height)
+          cmap[pit->x() + pit->y() * width] = true;
+        pit++;
+      }
+      delete (dss);
+    }
+    it++;
+  }
+
+  int nbext = 0;
+  int nbextin = 0;
+  int nbextout = 0;
+  int n = 0;
+  Pt2i *pts = NULL;
+  vector<ExtLine>::const_iterator yit = exts.begin ();
+  while (yit != exts.end ())
+  {
+    n = 0;
+    pts = Pt2i ((int) (yit->sx + 0.5), (int) (yit->sy + 0.5)).drawing (
+          Pt2i ((int) (yit->ex + 0.5), (int) (yit->ey + 0.5)), &n);
+    for (int i = 0; i < n; i++)
+      if (cmap[pts[i].y () * width + pts[i].x ()]) nbextin ++;
+      else nbextout ++;
+    nbext += n;
+    yit++;
+    delete [] pts;
+  }
+  return (nbextin / (double) nbext);
+}
+
+
+double ExtLines::cannyLineCovering (const char *name,
+                                    int &nb, double &lg, double minl) const
+{
+  // 1. Reading canny lines file
+  vector<ExtLine> cannys;
+  double val[5];
+  double clLength = 0.;
+  int i = 0;
+  nb = 0;
+  lg = 0.;
+  ifstream input (name, ios::in);
+  bool reading = true;
+  if (input)
+  {
+    while (reading)
+    {
+      input >> val[i];
+      if (input.eof ()) reading = false;
+      if (++i == 5)
+      {
+        ExtLine cl;
+        cl.sx = val[0];
+        cl.sy = height - 1 - val[1];
+        cl.ex = val[2];
+        cl.ey = height - 1 - val[3];
+        cannys.push_back (cl);
+        clLength = sqrt ((cl.sx - cl.ex) * (cl.sx - cl.ex)
+                         + (cl.sy - cl.ey) * (cl.sy - cl.ey));
+        if (clLength > minl)
+        {
+          lg += clLength;
+          nb++;
+        }
+        i = 0;
+      }
+    }
+  }
+
+  // 2. Spreading canny lines
+  bool cmap[width * height];
+  for (int i = 0; i < width * height; i++) cmap[i] = false;
+  vector<ExtLine>::iterator it = cannys.begin ();
+  while (it != cannys.end ())
+  {
+    int xs = (int) (it->sx + 0.5);
+    int ys = (int) (it->sy + 0.5);
+    int xe = (int) (it->ex + 0.5);
+    int ye = (int) (it->ey + 0.5);
+    int minx = (xe < xs ? xe : xs);
+    int miny = (ye < ys ? ye : ys);
+    int maxx = (xe < xs ? xs : xe);
+    int maxy = (ye < ys ? ys : ye);
+    DigitalStraightSegment *dss = new DigitalStraightSegment (
+      Pt2i (xs, ys), Pt2i (xe, ye),
+      DigitalStraightLine::DSL_NAIVE, minx, miny, maxx, maxy);
+    dss->dilate (dss->standard ());
+    vector<Pt2i> points;
+    dss->getPoints (points);
+    vector<Pt2i>::iterator pit = points.begin ();
+    while (pit != points.end ())
+    {
+      if (pit->x () >= 0 && pit->x () < width
+          && pit->y () >= 0 && pit->y () < height)
+        cmap[pit->x() + pit->y() * width] = true;
+      pit++;
+    }
+    delete (dss);
+    it++;
+  }
+
+  // 3. Covering external lines
+  int nbext = 0;
+  int nbextin = 0;
+  int nbextout = 0;
+  int n = 0;
+  Pt2i *pts = NULL;
+  vector<ExtLine>::const_iterator yit = exts.begin ();
+  while (yit != exts.end ())
+  {
+    n = 0;
+    pts = Pt2i ((int) (yit->sx + 0.5), (int) (yit->sy + 0.5)).drawing (
+          Pt2i ((int) (yit->ex + 0.5), (int) (yit->ey + 0.5)), &n);
+    for (int i = 0; i < n; i++)
+      if (cmap[pts[i].y () * width + pts[i].x ()]) nbextin ++;
+      else nbextout ++;
+    nbext += n;
+    yit++;
+    delete [] pts;
+  }
+  return (nbextin / (double) nbext);
+}
diff --git a/Code/FBSD/BSTools/extlines.h b/Code/FBSD/BSTools/extlines.h
new file mode 100755
index 0000000..2f9b355
--- /dev/null
+++ b/Code/FBSD/BSTools/extlines.h
@@ -0,0 +1,104 @@
+#ifndef EXT_LINES_H
+#define EXT_LINES_H
+
+
+#include <QString>
+#include <vector>
+#include "blurredsegment.h"
+
+using namespace std;
+
+
+/** 
+ * @class ExtLines extlines.h
+ * \brief Comparable lines set from an external tool.
+ */
+class ExtLines
+{
+public:
+
+  /**
+   * \brief Creates an external lines set.
+   */
+  ExtLines (const char *name, int width, int height, int nbinfos = 4);
+
+  /**
+   * \brief Deletes the external lines set.
+   */
+  ~ExtLines ();
+
+  /**
+   * \brief Returns the count of lines in the set.
+   */
+  inline int countOfLines () const { return ((int) exts.size ()); }
+
+  /**
+   * \brief Returns the start point X coordinate of a line.
+   */
+  inline int xStart (int index) const {
+    return ((int) (exts[index].sx + 0.5)); }
+
+  /**
+   * \brief Returns the start point Y coordinate of a line.
+   */
+  inline int yStart (int index) const {
+    return ((int) (exts[index].sy + 0.5)); }
+
+  /**
+   * \brief Returns the end point X coordinate of a line.
+   */
+  inline int xEnd (int index) const {
+    return ((int) (exts[index].ex + 0.5)); }
+
+  /**
+   * \brief Returns the end point Y coordinate of a line.
+   */
+  inline int yEnd (int index) const {
+    return ((int) (exts[index].ey + 0.5)); }
+
+  /**
+   * \brief Returns the covering ratio of given blurred segments.
+   */
+  double covering (const vector<BlurredSegment *> &segs) const;
+
+  /**
+   * \brief Returns the covering ratio of CannyLine segments.
+   * @param name Output file name.
+   * @param nb Extracted number of lines.
+   * @param lb Extracted total length of lines.
+   * @param minl Minimal length of extarcted lines.
+   */
+  double cannyLineCovering (const char *name,
+                            int &nb, double &lg, double minl) const;
+
+
+
+private:
+
+  /** Dilation distance for lines covering estimation. */
+  static const int COV_DILATION;
+
+ /** Aggregation of segment extraction results with initial conditions. */
+  struct ExtLine
+  {
+    /** External line start point X coordinate. */
+    double sx;
+    /** External line start point Y coordinate. */
+    double sy;
+    /** External line end point X coordinate. */
+    double ex;
+    /** External line end point Y coordinate. */
+    double ey;
+  };
+
+  /** Set of recorded external lines. */
+  vector<ExtLine> exts;
+
+  /** Image width */
+  int width;
+  /** Image height */
+  int height;
+
+};
+
+#endif
diff --git a/Code/FBSD/BlurredSegment/bsdetector.h b/Code/FBSD/BlurredSegment/bsdetector.h
index 24d4fd9..96935e7 100755
--- a/Code/FBSD/BlurredSegment/bsdetector.h
+++ b/Code/FBSD/BlurredSegment/bsdetector.h
@@ -517,6 +517,12 @@ public:
   inline void switchFinalDensityTest () {
     finalDensityTestOn = ! finalDensityTestOn; }
 
+  /**
+   * \brief Returns the minimal spread of final blurred segments.
+   */
+  inline int finalSpreadMinLength () const {
+    return (finalSpreadTestOn ? finalSpreadMin : 0); }
+
   /**
    * \brief Returns whether the length test at final step is set.
    */
diff --git a/Code/FBSD/FBSD.pro b/Code/FBSD/FBSD.pro
index 635c56e..d4a2c20 100644
--- a/Code/FBSD/FBSD.pro
+++ b/Code/FBSD/FBSD.pro
@@ -20,6 +20,8 @@ HEADERS += BlurredSegment/biptlist.h \
            BlurredSegment/bsdetector.h \
            BlurredSegment/bsfilter.h \
            BlurredSegment/bstracker.h \
+           BSTools/bscannyitem.h \
+           BSTools/bscannyview.h \
            BSTools/bsdetectionwidget.h \
            BSTools/bsidetitem.h \
            BSTools/bsidetview.h \
@@ -29,6 +31,9 @@ HEADERS += BlurredSegment/biptlist.h \
            BSTools/bsstructureitem.h \
            BSTools/bsstructureview.h \
            BSTools/bswindow.h \
+           BSTools/bsyorkitem.h \
+           BSTools/bsyorkview.h \
+           BSTools/extlines.h \
            ConvexHull/antipodal.h \
            ConvexHull/chvertex.h \
            ConvexHull/convexhull.h \
@@ -60,6 +65,8 @@ SOURCES += main.cpp \
            BlurredSegment/bsdetector.cpp \
            BlurredSegment/bsfilter.cpp \
            BlurredSegment/bstracker.cpp \
+           BSTools/bscannyitem.cpp \
+           BSTools/bscannyview.cpp \
            BSTools/bsdetectionwidget.cpp \
            BSTools/bsidetitem.cpp \
            BSTools/bsidetview.cpp \
@@ -69,6 +76,9 @@ SOURCES += main.cpp \
            BSTools/bsstructureitem.cpp \
            BSTools/bsstructureview.cpp \
            BSTools/bswindow.cpp \
+           BSTools/bsyorkitem.cpp \
+           BSTools/bsyorkview.cpp \
+           BSTools/extlines.cpp \
            ConvexHull/antipodal.cpp \
            ConvexHull/chvertex.cpp \
            ConvexHull/convexhull.cpp \
diff --git a/Code/FBSD/ImageTools/digitalstraightline.h b/Code/FBSD/ImageTools/digitalstraightline.h
index 64b4abf..23982d9 100755
--- a/Code/FBSD/ImageTools/digitalstraightline.h
+++ b/Code/FBSD/ImageTools/digitalstraightline.h
@@ -109,6 +109,14 @@ public:
     return (a < absb ? absb : a);
   }
 
+  /**
+   * \brief Returns the standard width : |a| + |b|.
+   */
+  inline int standard () const
+  {
+    return (a + (b < 0 ? -b : b));
+  }
+
   /**
    * \brief Returns the lower of the digital straight line : min (|a|,|b|).
    */
diff --git a/Code/FBSD/ImageTools/digitalstraightsegment.cpp b/Code/FBSD/ImageTools/digitalstraightsegment.cpp
index 5880343..c0bb5b0 100755
--- a/Code/FBSD/ImageTools/digitalstraightsegment.cpp
+++ b/Code/FBSD/ImageTools/digitalstraightsegment.cpp
@@ -177,3 +177,26 @@ DigitalStraightSegment *DigitalStraightSegment::erosion (int num, int den) const
   return (new DigitalStraightSegment (a, b, c + (nu - newwidth) / 2,
                                       newwidth, min, max));
 }
+
+
+DigitalStraightSegment *DigitalStraightSegment::dilation (
+                                                   int num, int den) const
+{
+  int newwidth = nu + (num * period ()) / den;
+  return (new DigitalStraightSegment (a, b, c + (nu - newwidth) / 2,
+                                      newwidth, min, max));
+}
+
+
+DigitalStraightSegment *DigitalStraightSegment::dilation (int radius) const
+{
+  return (new DigitalStraightSegment (a, b, c - radius,
+                                      nu + 2 * radius, min, max));
+}
+
+
+void DigitalStraightSegment::dilate (int radius)
+{
+  nu += 2 * radius;
+  c -= radius;
+}
diff --git a/Code/FBSD/ImageTools/digitalstraightsegment.h b/Code/FBSD/ImageTools/digitalstraightsegment.h
index 38c612e..65964e0 100755
--- a/Code/FBSD/ImageTools/digitalstraightsegment.h
+++ b/Code/FBSD/ImageTools/digitalstraightsegment.h
@@ -74,6 +74,25 @@ public:
    */
   DigitalStraightSegment *erosion (int num, int den) const;
 
+  /**
+   * \brief Returns a dilation of the segment.
+   * @param num Dilation value numerator.
+   * @param den Dilation value denominator.
+   */
+  DigitalStraightSegment *dilation (int num, int den) const;
+
+  /**
+   * \brief Returns a dilated segment of the given radius.
+   * @param radius Dilation radius.
+   */
+  DigitalStraightSegment *dilation (int radius) const;
+
+  /**
+   * \brief Dilates the segment of the given radius.
+   * @param radius Dilation radius.
+   */
+  void dilate (int radius);
+
 
 protected:
 
diff --git a/Code/FBSD/main.cpp b/Code/FBSD/main.cpp
index 98c90c2..48adc43 100755
--- a/Code/FBSD/main.cpp
+++ b/Code/FBSD/main.cpp
@@ -1,5 +1,6 @@
 #include <QApplication>
 #include <string>
+#include <cmath>
 #include "bswindow.h"
 #include "bsrandomtester.h"
 // #include "scanwindow.h"
@@ -9,7 +10,7 @@ int main (int argc, char *argv[])
 {
   int val = 0;
   int imageName = 0;
-  bool random = false, testing = false;
+  bool random = false, testing = false, york = false;
   QApplication app (argc, argv);
 
 /*
@@ -34,6 +35,7 @@ int main (int argc, char *argv[])
       // Test command : time ./Seg -test ../Images/couloir.jpg
       else if (string(argv[i]) == string ("-test")) testing = true;
       else if (string(argv[i]) == string ("-random")) random = true;
+      else if (string(argv[i]) == string ("-york")) york = true;
       else if (string(argv[i]) == string ("-sobel3x3"))
         window.useGradient (VMap::TYPE_SOBEL_3X3);
       else if (string(argv[i]) == string ("-sobel5x5"))
@@ -72,6 +74,46 @@ int main (int argc, char *argv[])
     delete tester;
     return (EXIT_SUCCESS);
   }
+  if (york)
+  {
+    QImage im;
+    im.load ("york.jpg");
+    int width = im.width ();
+    int height = im.height ();
+    BSDetectionWidget bsdw;
+    BSDetector detector;
+    detector.setGradientMap (new VMap (width, height, bsdw.getBitmap (im),
+                                       VMap::TYPE_SOBEL_5X5));
+    int ncl, nbs;
+    double lcl, lbs;
+    detector.detectAll ();
+    ExtLines yl ("yorklines.txt", width, height);
+    vector<BlurredSegment *> bss = detector.getBlurredSegments ();
+    double covFBSD = yl.covering (bss);
+    double covCL = yl.cannyLineCovering ("cannylines.txt", ncl, lcl, 30.);
+    ofstream outf ("cmpcov.txt", ios::out);
+    outf << covCL << " " << covFBSD << endl;
+    outf.close ();
+
+    nbs = (int) bss.size ();
+    lbs = 0.;
+    vector<BlurredSegment *>::iterator it = bss.begin ();
+    while (it != bss.end ())
+    {
+      Pt2i lastleft = (*it)->getLastLeft ();
+      Pt2i lastright = (*it)->getLastRight ();
+      lbs += sqrt ((lastleft.x () - lastright.x ())
+                   * (lastleft.x () - lastright.x ())
+                   + (lastleft.y () - lastright.y ())
+                   * (lastleft.y () - lastright.y ()));
+      it ++;
+    }
+    ofstream outl ("cmplines.txt", ios::out);
+    outl << ncl << " " << lcl << " " << (lcl / ncl) << " "
+         << nbs << " " << lbs << " " << (lbs / nbs) << endl;
+    outl.close ();
+    return (EXIT_SUCCESS);
+  }
   else
   {
     if (imageName != 0) window.setFile (QString (argv[imageName]));
-- 
GitLab