diff --git a/Code/Seg/BSTools/bsdetectionwidget.cpp b/Code/Seg/BSTools/bsdetectionwidget.cpp index 34b153457c4fd1ef805f7a6b4373d48ffee0fbf1..85b7745ae39074417de82e54340a3c8560d89ba7 100755 --- a/Code/Seg/BSTools/bsdetectionwidget.cpp +++ b/Code/Seg/BSTools/bsdetectionwidget.cpp @@ -363,6 +363,15 @@ void BSDetectionWidget::keyPressEvent (QKeyEvent *event) if (p1.equals (p2)) displayBackground (); else displayDetectionResult (); } + else + { + // Tunes the gradient resolution for gradient local max filtering + detector.incGradientResolution ( + (event->modifiers () & Qt::ShiftModifier ? -1 : 1)); + cout << "Gradient resolution = " + << detector.getGradientResolution () << endl; + extract (); + } break; case Qt::Key_C : diff --git a/Code/Seg/BlurredSegment/bsdetector.h b/Code/Seg/BlurredSegment/bsdetector.h index b7afd53c880ecb1424b1547b4c4b54641c3a371a..7d4f93f7a32495680f76bc7c6d2ebdc704ec5c3d 100755 --- a/Code/Seg/BlurredSegment/bsdetector.h +++ b/Code/Seg/BlurredSegment/bsdetector.h @@ -194,6 +194,19 @@ public: inline void incGradientThreshold (int inc) { return (gMap->incGradientThreshold (inc)); } + /** + * \brief Returns the gradient threshold used for local max filtering. + */ + inline int getGradientResolution () const { + return (gMap->getGradientResolution ()); } + + /** + * \brief Increments the gradient threshold used for local maximal filtering. + * @param inc Increment value. + */ + inline void incGradientResolution (int inc) { + return (gMap->incGradientResolution (inc)); } + /** * \brief Returns the automatic detection grid resolution. */ diff --git a/Code/Seg/BlurredSegment/bstracker.cpp b/Code/Seg/BlurredSegment/bstracker.cpp index e185a4e0f83f3369e88da1864561d7afdeb701ea..6ac9c1c22cfcd90ce0ce472e9fb6fc8141f89f42 100755 --- a/Code/Seg/BlurredSegment/bstracker.cpp +++ b/Code/Seg/BlurredSegment/bstracker.cpp @@ -275,7 +275,7 @@ BlurredSegment *BSTracker::fineTrack (const Pt2i ¢er, const Vr2i &scandir, // Handles thickenning if (thickenOn && stableWidthCount >= thickenningLimit) { - AbsRat finalWidth (sw.sum (1)); + AbsRat finalWidth (sw.sumHalf ()); if (finalWidth.lessThan (bs.getMaxWidth ())) bs.setMaxWidth (finalWidth); thickenOn = false; } diff --git a/Code/Seg/ImageTools/absrat.h b/Code/Seg/ImageTools/absrat.h index 2ed9b922ff5ee4836e88da04757180d77a374536..84e2eeebcc631d243aa9d426e181578c534c9d80 100755 --- a/Code/Seg/ImageTools/absrat.h +++ b/Code/Seg/ImageTools/absrat.h @@ -162,6 +162,14 @@ public: */ inline AbsRat sum (int val) const { return (AbsRat (num + val * den, den)); } + /** + * @fn AbsRat sumHalf () const + * \brief Returns the sum of the rational with 1/2. + */ + inline AbsRat sumHalf () const { + return (den % 2 == 1 ? AbsRat (2 * num + den, 2 * den) + : AbsRat (num + den / 2, den)); } + protected: diff --git a/Code/Seg/ImageTools/vmap.cpp b/Code/Seg/ImageTools/vmap.cpp index 5df08bdd353faeb058331a8ba93769fabff57699..142b3b5a64522eb17d8d8ddaf53dc07ca7700243 100755 --- a/Code/Seg/ImageTools/vmap.cpp +++ b/Code/Seg/ImageTools/vmap.cpp @@ -1,4 +1,4 @@ -#include <iostream> +// #include <iostream> #include "vmap.h" #include "math.h" @@ -16,12 +16,14 @@ const int VMap::TYPE_FULL_MORPHO = 7; 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; 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; @@ -125,6 +127,7 @@ 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; @@ -478,6 +481,59 @@ int VMap::keepFreeElementsIn (const vector<Pt2i> &pix, int n, int *ind) const } +int VMap::keepContrastedMax (int *lmax, int n, int *in) const +{ + int min[n-1]; + bool fired[n]; + int nbfired = 0; + int sleft = 0; + + // Clears the list of fired max + for (int i = 0; i < n; i++) fired[i] = false; + + // Computes the ponds depth + for (int i = 0; i < n - 1; i++) + { + min[i] = in[lmax[i]]; + for (int j = lmax[i] + 1; j < lmax[i+1]; j++) + if (in[j] < min[i]) min[i] = in[j]; + } + // For each ponds + for (int i = 0; i < n - 1; i++) + { + // if the right summit is lower + if (in[lmax[i+1]] < in[lmax[sleft]]) + { + if (in[lmax[i+1]] - min[i] < gradres) // gradient resolution + { + fired[i+1] = true; + nbfired ++; + if (i < n - 2) if (min[i+1] < min[i]) min[i+1] = min[i]; + } + } + // if the left summit is lower + else + { + if (in[lmax[sleft]] - min[i] < gradres) // gradient resolution + { + fired[sleft] = true; + nbfired ++; + sleft = i + 1; + } + } + } + // Pruning + int i = 0, j = 0; + while (i < n && ! fired[i++]) j++; + while (i < n) + { + while (i < n && fired[i]) i++; + if (i < n) lmax[j++] = lmax[i++]; + } + return (n - nbfired); +} + + int VMap::keepOrientedElementsIn (const vector<Pt2i> &pix, const Vr2i &ref, int n, int *ind) const { @@ -529,6 +585,9 @@ int VMap::localMax (int *lmax, const vector<Pt2i> &pix) const // Gets the local maxima int count = searchLocalMax (lmax, n, gn); + // Prunes the low contrasted local maxima + count = keepContrastedMax (lmax, count, gn); + // Prunes the already selected candidates count = keepFreeElementsIn (pix, count, lmax); diff --git a/Code/Seg/ImageTools/vmap.h b/Code/Seg/ImageTools/vmap.h index 0d55928ddca75d52f0280497d01aa9a8082e50a9..4c43e13fb0ef67940964b171e4e09709848941db 100755 --- a/Code/Seg/ImageTools/vmap.h +++ b/Code/Seg/ImageTools/vmap.h @@ -154,6 +154,15 @@ public: */ int keepFreeElementsIn (const vector<Pt2i> &pix, int n, int *ind) const; + /** + * \brief Searches local gradient maxima values. + * Returns the count of perceptible local maxima found. + * @param lmax Local max index array. + * @param n Count of input max values. + * @param in Array of input values. + */ + int keepContrastedMax (int *lmax, int n, int *in) const; + /** * Keeps elements that are oriented along a reference vector * in a selection of points. @@ -213,6 +222,18 @@ public: if (gtype <= TYPE_SOBEL_5X5) gmagThreshold *= gradientThreshold; } + /** + * \brief Returns the gradient resolution value used for maxima filtering. + */ + inline int getGradientResolution () const { return (gradres); } + + /** + * \brief Increments the gradient resolution value used for maxima filtering. + */ + inline void incGradientResolution (int inc) { + gradres += inc * 5; + if (gradres < 0) gradres = 0; } + /** * \brief Switches the direction constraint for local maxima selection. */ @@ -252,6 +273,8 @@ private: int angleThreshold; /** Default threshold value for the gradient selection. */ static const int DEFAULT_GRADIENT_THRESHOLD; + /** Default threshold value for the gradient resolution (filtering). */ + static const int DEFAULT_GRADIENT_RESOLUTION; /** Image width. */ int width; @@ -272,6 +295,8 @@ private: int gradientThreshold; /** Gradient magnitude threshold for highest value detection. */ int gmagThreshold; + /** Gradient resolution threshold for local max filtering. */ + int gradres; /** Direction constraint for local gradient maxima. */ bool orientedGradient; diff --git a/Methode/ctrl.tex b/Methode/ctrl.tex index ede83d9fab5c1afbd90c7b482764d6c709a3801d..8510a56d1ec03e2f35b43ef36759b4ae7a8a3bd9 100755 --- a/Methode/ctrl.tex +++ b/Methode/ctrl.tex @@ -24,6 +24,7 @@ \hline \multicolumn{3}{|l|}{Contr\^ole de l'extraction :} \\ a/q/c &\spa & Enregistre / Affiche / Supprime les segments \\ +b && Ajuste la r\'esolution du gradient pour le filtrage des max locaux \\ e && Inverse la direction de r\'ef\'erence (autre bord) \\ g && Ajuste le seuil du gradient \\ n && Allume le segment suivant dans une d\'etection multiple \\