From c05dce56820b4e2ff9128844b3e346e88c601a81 Mon Sep 17 00:00:00 2001 From: even <philippe.even@loria.fr> Date: Sat, 22 Dec 2018 23:58:42 +0100 Subject: [PATCH] occ mask dilation and both edges in multidetection --- Code/Seg/BSTools/bsdetectionwidget.cpp | 16 +++-- Code/Seg/BlurredSegment/bsdetector.cpp | 34 ++++++++-- Code/Seg/BlurredSegment/bsdetector.h | 3 +- Code/Seg/BlurredSegment/bstracker.h | 2 +- Code/Seg/ImageTools/vmap.cpp | 90 +++++++++++++++----------- Code/Seg/ImageTools/vmap.h | 28 ++++++-- 6 files changed, 115 insertions(+), 58 deletions(-) diff --git a/Code/Seg/BSTools/bsdetectionwidget.cpp b/Code/Seg/BSTools/bsdetectionwidget.cpp index 06f0acf..67a6ae5 100755 --- a/Code/Seg/BSTools/bsdetectionwidget.cpp +++ b/Code/Seg/BSTools/bsdetectionwidget.cpp @@ -52,6 +52,7 @@ BSDetectionWidget::BSDetectionWidget (QWidget *parent) bsHighColor = Qt::yellow; bsPointsVisible = true; boundColor = Qt::green; + //boundHighColor = Qt::black; boundHighColor = Qt::magenta; } @@ -594,11 +595,11 @@ void BSDetectionWidget::keyPressEvent (QKeyEvent *event) case Qt::Key_R : if (event->modifiers () & Qt::ControlModifier) { - // Switches the occupancy mask dilation modality - gMap->switchMaskDilation (); + // Toggles the occupancy mask dilation type + gMap->toggleMaskDilation (); extract (); - cout << "Occupancy mask dilation : " - << (gMap->isMaskDilationOn () ? "on" : "off") << endl; + cout << "Occupancy mask dilation size : " + << gMap->getMaskDilation () << endl; } else { @@ -635,11 +636,11 @@ void BSDetectionWidget::keyPressEvent (QKeyEvent *event) { // Switches the progressive thinning detector.toggleThinning (); - if (detector.isThinningActivated () && detector.isThickenningOn ()) + if (detector.isThinningOn () && detector.isThickenningOn ()) detector.toggleThickenning (); extract (); cout << "Thinning " - << (detector.isThinningActivated () ? "on" : "off") << endl; + << (detector.isThinningOn () ? "on" : "off") << endl; } break; @@ -730,7 +731,7 @@ void BSDetectionWidget::keyPressEvent (QKeyEvent *event) { // Switches the thickenning control detector.toggleThickenning (); - if (detector.isThickenningOn () && detector.isThinningActivated ()) + if (detector.isThickenningOn () && detector.isThinningOn ()) detector.toggleThinning (); extract (); cout << "Thickenning " @@ -996,6 +997,7 @@ void BSDetectionWidget::displaySavedSegments () else if (background == BACK_WHITE) augmentedImage.fill (qRgb (255, 255, 255)); else if (background == BACK_IMAGE) augmentedImage = loadedImage; else augmentedImage = gradImage; + lighten (augmentedImage); QPainter painter (&augmentedImage); if (! extractedSegments.empty ()) { diff --git a/Code/Seg/BlurredSegment/bsdetector.cpp b/Code/Seg/BlurredSegment/bsdetector.cpp index 27510ed..5cf09f3 100755 --- a/Code/Seg/BlurredSegment/bsdetector.cpp +++ b/Code/Seg/BlurredSegment/bsdetector.cpp @@ -38,7 +38,7 @@ BSDetector::BSDetector () bst2 = new BSTracker (); bstold = new BSTracker (); if (bstold->dynamicScansOn ()) bstold->toggleDynamicScans (); - if (bstold->isThinningActivated ()) bstold->toggleThinning (); + if (bstold->isThinningOn ()) bstold->toggleThinning (); if (bstold->isThickenningOn ()) bstold->toggleThickenning (); oldp = false; @@ -203,13 +203,20 @@ bool BSDetector::runMultiDetection (const Pt2i &p1, const Pt2i &p2) Pt2i ptstart = pts.at (locmax[i]); if (gMap->isFree (ptstart)) { - detect (p1, p2, true, ptstart); - if (bsf != NULL) + int oldEdgeDir = edgeDirection; + if (edgeDirection != 0) edgeDirection = 1; + while (edgeDirection >= -1) { - gMap->setMask (bsf->getAllPoints ()); - mbsf.push_back (bsf); - bsf = NULL; // to avoid BS deletion + detect (p1, p2, true, ptstart); + if (bsf != NULL) + { + gMap->setMask (bsf->getAllPoints ()); + mbsf.push_back (bsf); + bsf = NULL; // to avoid BS deletion + } + edgeDirection -= 2; } + edgeDirection = oldEdgeDir; if (++nbtrials == nbmaxtrials) isnext = false; } } @@ -320,6 +327,21 @@ void BSDetector::olddetect (const Pt2i &p1, const Pt2i &p2, bsf = bsf2; } + // Connected components analysis */ + //------------------------------*/ + if (ccOn) + { + int bsccp = bsf->countOfConnectedPoints (ccMinSize); + int bssize = bsf->getAllPoints().size (); + if (bsccp < bssize / 2) + { + resultValue = RESULT_FINAL_TOO_SPARSE; + delete bsf; + bsf = NULL; + return; + } + } + lastTrialOk = true; resultValue = RESULT_OK; } diff --git a/Code/Seg/BlurredSegment/bsdetector.h b/Code/Seg/BlurredSegment/bsdetector.h index 8944d97..dcbf930 100755 --- a/Code/Seg/BlurredSegment/bsdetector.h +++ b/Code/Seg/BlurredSegment/bsdetector.h @@ -414,8 +414,7 @@ public: /** * \brief Returns if the thinning is activated. */ - inline bool isThinningActivated () const { - return bst2->isThinningActivated (); } + inline bool isThinningOn () const { return bst2->isThinningOn (); } /** * \brief Toggles the thinning strategy. diff --git a/Code/Seg/BlurredSegment/bstracker.h b/Code/Seg/BlurredSegment/bstracker.h index 309953e..26a8b3c 100755 --- a/Code/Seg/BlurredSegment/bstracker.h +++ b/Code/Seg/BlurredSegment/bstracker.h @@ -213,7 +213,7 @@ public: /** * \brief Returns if the thinning is activated. */ - inline bool isThinningActivated () const { return thinningOn; } + inline bool isThinningOn () const { return thinningOn; } /** * \brief Toggles the thinning strategy. diff --git a/Code/Seg/ImageTools/vmap.cpp b/Code/Seg/ImageTools/vmap.cpp index 26a82ee..b2b5f70 100755 --- a/Code/Seg/ImageTools/vmap.cpp +++ b/Code/Seg/ImageTools/vmap.cpp @@ -18,12 +18,13 @@ const int VMap::NEAR_SQ_ANGLE = 80; // 80% (roughly 25 degrees) const int VMap::DEFAULT_GRADIENT_THRESHOLD = 30; const int VMap::DEFAULT_GRADIENT_RESOLUTION = 100; +const int VMap::MAX_BOWL = 20; +const int VMap::NB_DILATIONS = 5; +const int VMap::DEFAULT_DILATION = 4; + VMap::VMap (int width, int height, int *data, int type) { - gradientThreshold = DEFAULT_GRADIENT_THRESHOLD; - gmagThreshold = gradientThreshold; - gradres = DEFAULT_GRADIENT_RESOLUTION; this->width = width; this->height = height; this->gtype = type; @@ -114,21 +115,12 @@ VMap::VMap (int width, int height, int *data, int type) imap[i] = (int) sqrt (map[i].norm2 ()); gmagThreshold *= gradientThreshold; } - - mask = new bool[width * height]; - for (int i = 0; i < width * height; i++) mask[i] = false; - masking = false; - maskDilationOn = true; - angleThreshold = NEAR_SQ_ANGLE; - orientedGradient = false; + init (); } VMap::VMap (int width, int height, int **data, int type) { - gradientThreshold = DEFAULT_GRADIENT_THRESHOLD; - gmagThreshold = gradientThreshold; - gradres = DEFAULT_GRADIENT_RESOLUTION; this->width = width; this->height = height; this->gtype = type; @@ -219,13 +211,7 @@ VMap::VMap (int width, int height, int **data, int type) imap[i] = (int) sqrt (map[i].norm2 ()); gmagThreshold *= gradientThreshold; } - - mask = new bool[width * height]; - for (int i = 0; i < width * height; i++) mask[i] = false; - masking = false; - maskDilationOn = true; - angleThreshold = NEAR_SQ_ANGLE; - orientedGradient = false; + init (); } @@ -234,6 +220,49 @@ VMap::~VMap () delete map; delete imap; delete mask; + delete [] dilations; + delete [] bowl; +} + + +void VMap::init () +{ + gradientThreshold = DEFAULT_GRADIENT_THRESHOLD; + gmagThreshold = gradientThreshold; + gradres = DEFAULT_GRADIENT_RESOLUTION; + mask = new bool[width * height]; + for (int i = 0; i < width * height; i++) mask[i] = false; + masking = false; + angleThreshold = NEAR_SQ_ANGLE; + orientedGradient = false; + bowl = new Vr2i[MAX_BOWL]; + bowl[0] = Vr2i (1, 0); + bowl[1] = Vr2i (0, 1); + bowl[2] = Vr2i (-1, 0); + bowl[3] = Vr2i (0, -1); + bowl[4] = Vr2i (1, 1); + bowl[5] = Vr2i (1, -1); + bowl[6] = Vr2i (-1, -1); + bowl[7] = Vr2i (-1, 1); + bowl[8] = Vr2i (2, 0); + bowl[9] = Vr2i (0, 2); + bowl[10] = Vr2i (-2, 0); + bowl[11] = Vr2i (0, -2); + bowl[12] = Vr2i (2, 1); + bowl[13] = Vr2i (1, 2); + bowl[14] = Vr2i (-1, 2); + bowl[15] = Vr2i (-2, 1); + bowl[16] = Vr2i (-2, -1); + bowl[17] = Vr2i (-1, -2); + bowl[18] = Vr2i (1, -2); + bowl[19] = Vr2i (2, -1); + dilations = new int[NB_DILATIONS]; + dilations[0] = 0; + dilations[1] = 4; + dilations[2] = 8; + dilations[3] = 12; + dilations[4] = 20; + maskDilation = DEFAULT_DILATION; } @@ -702,23 +731,12 @@ void VMap::setMask (const vector<Pt2i> &pts) { Pt2i pt = *it++; mask[pt.y () * width + pt.x ()] = true; - if (maskDilationOn) + for (int i = 0; i < dilations[maskDilation]; i++) { - int x = pt.x (), y = pt.y (); - if (x > 0) - { - mask[y * width + x - 1] = true; - if (y > 0) mask[(y - 1) * width + x - 1] = true; - if (y + 1 < height) mask[(y + 1) * width + x - 1] = true; - } - if (x + 1 < width) - { - mask[y * width + x + 1] = true; - if (y > 0) mask[(y - 1) * width + x + 1] = true; - if (y + 1 < height) mask[(y + 1) * width + x + 1] = true; - } - if (y > 0) mask[(y - 1) * width + x] = true; - if (y + 1 < height) mask[(y + 1) * width + x] = true; + int x = pt.x () + bowl[i].x (); + int y = pt.y () + bowl[i].y (); + if (x >= 0 && x < width && y >= 0 && y < height) + mask[y * width + x] = true; } } } diff --git a/Code/Seg/ImageTools/vmap.h b/Code/Seg/ImageTools/vmap.h index 9f76483..f31a507 100755 --- a/Code/Seg/ImageTools/vmap.h +++ b/Code/Seg/ImageTools/vmap.h @@ -259,14 +259,15 @@ public: inline void setMasking (bool status) { masking = status; } /** - * \brief Retuns the mask dilation modality. + * \brief Retuns the mask dilation size. */ - inline bool isMaskDilationOn () const { return (maskDilationOn); } + inline int getMaskDilation () const { return (dilations[maskDilation]); } /** - * \brief Sets mask activation on or off. + * \brief Toggles the mask dilation size. */ - inline void switchMaskDilation () { maskDilationOn = ! maskDilationOn; } + inline void toggleMaskDilation () { + if (++maskDilation == NB_DILATIONS) maskDilation = 0; } /** * \brief Tests the occupancy of a mask cell. @@ -286,6 +287,12 @@ private: static const int DEFAULT_GRADIENT_THRESHOLD; /** Default threshold value for the gradient resolution (filtering). */ static const int DEFAULT_GRADIENT_RESOLUTION; + /** Size of the maximal dilation bowl. */ + static const int MAX_BOWL; + /** Number of dilation types. */ + static const int NB_DILATIONS; + /** Default dilation for the points added to the mask. */ + static const int DEFAULT_DILATION; /** Image width. */ int width; @@ -302,8 +309,12 @@ private: bool *mask; /** Flag indicating whether the occupancy mask is in use. */ bool masking; - /** Flag indicating whether input points should be dilated. */ - bool maskDilationOn; + /** Type of dilation applied to the points added to the mask. */ + int maskDilation; + /** Number of neighbours in the applied dilation. */ + int *dilations; + /** Dilation bowl. */ + Vr2i *bowl; /** Standardized gradient threshold for highest value detection. */ int gradientThreshold; /** Gradient magnitude threshold for highest value detection. */ @@ -314,6 +325,11 @@ private: bool orientedGradient; + /** + * \brief Initializes the internal data of the vector map. + */ + void init (); + /** * \brief Builds the vector map as a gradient map from provided data. * Uses a Sobel 3x3 kernel. -- GitLab