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