From f76153872e4fcb9e64e4922c715056785bee1fbc Mon Sep 17 00:00:00 2001 From: even <philippe.even@loria.fr> Date: Wed, 10 Apr 2019 17:42:22 +0200 Subject: [PATCH] Update code for ICIAP --- Code/FBSD/BSTools/bsdetectionwidget.cpp | 174 ++++++++++++++++------- Code/FBSD/BSTools/bsdetectionwidget.h | 25 +++- Code/FBSD/BSTools/bsrandomtester.cpp | 120 +++++++++------- Code/FBSD/BSTools/bsrandomtester.h | 27 ++-- Code/FBSD/BlurredSegment/bsdetector.cpp | 178 +++++++++--------------- Code/FBSD/BlurredSegment/bsdetector.h | 20 ++- Code/FBSD/ImageTools/vmap.cpp | 8 +- 7 files changed, 313 insertions(+), 239 deletions(-) diff --git a/Code/FBSD/BSTools/bsdetectionwidget.cpp b/Code/FBSD/BSTools/bsdetectionwidget.cpp index 130ddbc..0d5fd29 100755 --- a/Code/FBSD/BSTools/bsdetectionwidget.cpp +++ b/Code/FBSD/BSTools/bsdetectionwidget.cpp @@ -1,8 +1,8 @@ -#include <QtGui> #include <iostream> #include <fstream> #include <cstdlib> #include <ctime> +#include <cmath> #include "bsdetectionwidget.h" using namespace std; @@ -35,10 +35,11 @@ BSDetectionWidget::BSDetectionWidget (QWidget *parent) strucview = NULL; profileview = NULL; idetview = NULL; + cannyview = NULL; // Sets initial user outputs parameters verbose = false; - stats = false; + statsOn = false; background = BACK_IMAGE; bsBoundsVisible = false; blevel = 0; @@ -69,6 +70,7 @@ BSDetectionWidget::~BSDetectionWidget () if (strucview != NULL) delete strucview; if (profileview != NULL) delete profileview; if (idetview != NULL) delete idetview; + if (cannyview != NULL) delete cannyview; } @@ -392,13 +394,14 @@ void BSDetectionWidget::mouseMoveEvent (QMouseEvent *event) void BSDetectionWidget::keyPressEvent (QKeyEvent *event) { + int count = 0; if (isActiveWindow ()) switch (event->key ()) { case Qt::Key_A : // Registers the last extracted blurred segment - if (saveExtractedSegment ()) - cout << "Last blurred segment(s) registered" << endl; - else cout << "No last segment(s) to register" << endl; + count = saveExtractedSegment (); + cout << count << " new segment(s) -> " + << extractedSegments.size () << " segments registered" << endl; break; case Qt::Key_B : @@ -422,8 +425,8 @@ void BSDetectionWidget::keyPressEvent (QKeyEvent *event) case Qt::Key_C : // Clears the registered blurred segments + cout << "Withdraws registered segments" << endl; clearSavedSegments (); - cout << "Registered segments withdrawn" << endl; break; case Qt::Key_D : @@ -431,9 +434,9 @@ void BSDetectionWidget::keyPressEvent (QKeyEvent *event) { // Switches density test at initial step detector.switchDensityTest (); - extract (); cout << "Density test : " << (detector.isDensityTestOn () ? "on" : "off") << endl; + extract (); } break; @@ -474,9 +477,9 @@ void BSDetectionWidget::keyPressEvent (QKeyEvent *event) { // Switches length test at final step detector.switchFinalLengthTest (); - extract (); cout << "Final length test : " << (detector.isFinalLengthTestOn () ? "on" : "off") << endl; + extract (); } else { @@ -547,9 +550,9 @@ void BSDetectionWidget::keyPressEvent (QKeyEvent *event) { // Switches density test at final step detector.switchFinalDensityTest (); - extract (); cout << "Final density test : " << (detector.isFinalDensityTestOn () ? "on" : "off") << endl; + extract (); } else { @@ -575,8 +578,8 @@ void BSDetectionWidget::keyPressEvent (QKeyEvent *event) // Runs an automatic detection udef = false; detector.resetMaxDetections (); + cout << "Detects all segments" << endl; extract (); - cout << "All segments detected" << endl; } break; @@ -585,9 +588,9 @@ void BSDetectionWidget::keyPressEvent (QKeyEvent *event) { // Switches the initial detection extension limitation detector.switchInitialBounding (); - extract (); cout << "Initial step max extension = " << detector.initialDetectionMaxExtent () << endl; + extract (); } else { @@ -596,9 +599,9 @@ void BSDetectionWidget::keyPressEvent (QKeyEvent *event) if (! bsl.empty ()) { detector.incMaxDetections (event->modifiers () & Qt::ShiftModifier); - extract (); cout << "Selection of segment " << detector.getMaxDetections () << endl; + extract (); } } break; @@ -615,15 +618,15 @@ void BSDetectionWidget::keyPressEvent (QKeyEvent *event) else { // Outputs the detected segment + cout << "Outputs detection result" << endl; writeDetectionResult (); - cout << "Detection result output" << endl; } break; case Qt::Key_P : if (event->modifiers () & Qt::ControlModifier) { - // Switches the preliminary detection + // Switchues the preliminary detection detector.switchPreliminary (); cout << "Initial detection duplication " << (detector.isPreliminary () ? "on" : "off") << endl; @@ -632,8 +635,8 @@ void BSDetectionWidget::keyPressEvent (QKeyEvent *event) else { // Captures main window + cout << "Saves main window in capture.png" << endl; augmentedImage.save ("capture.png"); - cout << "Main window shot in capture.png" << endl; } break; @@ -649,8 +652,8 @@ void BSDetectionWidget::keyPressEvent (QKeyEvent *event) else { // Displays registered blurred segments + cout << "Displays all registered segments" << endl; displaySavedSegments (); - cout << "All registered segments displayed" << endl; } break; @@ -659,9 +662,9 @@ void BSDetectionWidget::keyPressEvent (QKeyEvent *event) { // Toggles the occupancy mask dilation type gMap->toggleMaskDilation (); - extract (); cout << "Occupancy mask dilation size : " << gMap->getMaskDilation () << endl; + extract (); } else { @@ -678,18 +681,18 @@ void BSDetectionWidget::keyPressEvent (QKeyEvent *event) { // Switches the interruption handling detector.switchAutoRestart (); - extract (); cout << "Segment continuation after = " << detector.getRestartOnLack () << " pixels" << endl; + extract (); } else { // Tunes the pixel lack tolerence value detector.setPixelLackTolerence (detector.getPixelLackTolerence () + (event->modifiers () & Qt::ShiftModifier ? -1 : 1)); - extract (); cout << "Tolerence to detection lacks = " << detector.getPixelLackTolerence () << " pixels" << endl; + extract (); } break; @@ -700,9 +703,9 @@ void BSDetectionWidget::keyPressEvent (QKeyEvent *event) detector.toggleThinning (); if (detector.isThinningOn () && detector.isThickenningOn ()) detector.toggleThickenning (); - extract (); cout << "Thinning " << (detector.isThinningOn () ? "on" : "off") << endl; + extract (); } break; @@ -744,9 +747,9 @@ void BSDetectionWidget::keyPressEvent (QKeyEvent *event) // Tunes the assigned max width margin for fine tracks detector.setFastTracksMaxMargin (detector.fastTracksMaxMargin () + (event->modifiers () & Qt::ShiftModifier ? -1 : 1)); - extract (); cout << "Fast tracks max width margin = " << detector.fastTracksMaxMargin () << endl; + extract (); } break; @@ -764,9 +767,9 @@ void BSDetectionWidget::keyPressEvent (QKeyEvent *event) // Tunes the assigned max width for fast tracks detector.setFineTracksMaxWidth (detector.fineTracksMaxWidth () + (event->modifiers () & Qt::ShiftModifier ? -1 : 1)); - extract (); cout << "Initial assigned width = " << detector.fineTracksMaxWidth () << endl; + extract (); } break; @@ -783,8 +786,8 @@ void BSDetectionWidget::keyPressEvent (QKeyEvent *event) { // Tunes the background image black level incBlackLevel ((event->modifiers () & Qt::ShiftModifier) ? -1 : 1); - displayDetectionResult (); cout << "Background black level = " << getBlackLevel () << endl; + displayDetectionResult (); } break; @@ -795,38 +798,75 @@ void BSDetectionWidget::keyPressEvent (QKeyEvent *event) detector.toggleThickenning (); if (detector.isThickenningOn () && detector.isThinningOn ()) detector.toggleThinning (); - extract (); cout << "Assigned width control " << (detector.isThickenningOn () ? "on" : "off") << endl; + extract (); } else { // Tunes the thickenning limit detector.incThickenningLimit ( (event->modifiers () & Qt::ShiftModifier) ? -1 : 1); - extract (); cout << "Thickenning limit = " << detector.getThickenningLimit () << " pixels" << endl; + extract (); } break; case Qt::Key_Exclam : switchHighlightColors (); + cout << "Highlight colors " + << (isHighlightColorsOn () ? "on" : "off") << endl; displayDetectionResult (); break; case Qt::Key_Equal : switchArlequin (); + cout << "Random coloring " << (isArlequinOn () ? "on" : "off") << endl; displayDetectionResult (); break; case Qt::Key_Asterisk : switchStats (); + cout << "Stats display " << (isStatsOn () ? "on" : "off") << endl; displayDetectionResult (); break; case Qt::Key_Dollar : writeTest (); + cout << "Selection stroke saved" << endl; + break; + + case Qt::Key_Percent : +/* + cout << "CannyLine compares BS" << endl; + detector.detectAll (); + if (cannyview == NULL) + { + cannyview = new BSCannyView (&loadedImage, &detector); + } + cannyview->testBS (); + cannyview->show (); + cannyview->update (); + displayDetectionResult (); + cout << "CannyLine compares BS" << endl; +*/ + break; + + case Qt::Key_Ugrave : +/* + cout << "CannyLine compares DSS" << endl; + detector.detectAll (); + if (cannyview == NULL) + { + cannyview = new BSCannyView (&loadedImage, &detector); + } + cannyview->testDSS (); + cannyview->show (); + cannyview->update (); + displayDetectionResult (); + cout << "CannyLine compares DSS" << endl; +*/ break; case Qt::Key_Plus : @@ -835,6 +875,7 @@ void BSDetectionWidget::keyPressEvent (QKeyEvent *event) zoom /= 2; xShift = xShift * 2 - maxWidth / 2; yShift = yShift * 2 - maxHeight / 2; + cout << "Zoom : " << zoom << endl; displayDetectionResult (); } break; @@ -851,6 +892,7 @@ void BSDetectionWidget::keyPressEvent (QKeyEvent *event) if (yShift > 0) yShift = 0; if ((maxHeight - yShift) * zoom > height) yShift = maxHeight - height / zoom; + cout << "Zoom : " << zoom << endl; displayDetectionResult (); } break; @@ -858,6 +900,7 @@ void BSDetectionWidget::keyPressEvent (QKeyEvent *event) case Qt::Key_Left : xShift += 50; if (xShift > 0) xShift = 0; + cout << "X-shift : " << xShift << endl; displayDetectionResult (); break; @@ -865,12 +908,14 @@ void BSDetectionWidget::keyPressEvent (QKeyEvent *event) xShift -= 50; if ((maxWidth - xShift) * zoom > width) xShift = maxWidth - width / zoom; + cout << "X-shift : " << xShift << endl; displayDetectionResult (); break; case Qt::Key_Up : yShift += 50; if (yShift > 0) yShift = 0; + cout << "Y-shift : " << yShift << endl; displayDetectionResult (); break; @@ -878,6 +923,7 @@ void BSDetectionWidget::keyPressEvent (QKeyEvent *event) yShift -= 50; if ((maxHeight - yShift) * zoom > height) yShift = maxHeight - height / zoom; + cout << "Y-shift : " << yShift << endl; displayDetectionResult (); break; @@ -1175,7 +1221,7 @@ void BSDetectionWidget::displayDetectionResult () strucview->repaint (); } if (verbose) writeDetectionStatus (); - if (stats) writeStats (); + if (statsOn) writeStats (); } } @@ -1202,12 +1248,26 @@ void BSDetectionWidget::displaySavedSegments () } -bool BSDetectionWidget::saveExtractedSegment () +int BSDetectionWidget::saveExtractedSegment () { - if (detector.isMultiSelection ()) + int count = 0; + vector<BlurredSegment *> bss = detector.getBlurredSegments (); + if (bss.empty ()) + { + BlurredSegment *bs = detector.getBlurredSegment (); + if (bs != NULL) + { + ExtractedSegment es; + es.bs = bs; + es.p1 = p1; + es.p2 = p2; + extractedSegments.push_back (es); + detector.preserveFormerBlurredSegment (); + count = 1; + } + } + else { - vector<BlurredSegment *> bss = detector.getBlurredSegments (); - if (bss.empty ()) return false; vector<BlurredSegment *>::const_iterator it = bss.begin (); while (it != bss.end ()) { @@ -1218,19 +1278,9 @@ bool BSDetectionWidget::saveExtractedSegment () extractedSegments.push_back (es); } detector.preserveFormerBlurredSegments (); + count = (int) (bss.size ()); } - else - { - BlurredSegment *bs = detector.getBlurredSegment (); - if (bs == NULL) return false; - ExtractedSegment es; - es.bs = bs; - es.p1 = p1; - es.p2 = p2; - extractedSegments.push_back (es); - detector.preserveFormerBlurredSegment (); - } - return true; + return count; } @@ -1334,6 +1384,9 @@ void BSDetectionWidget::writeDetectionStatus () else if (res == BSDetector::RESULT_FINAL_TOO_SPARSE) cout << "Extraction : unsuccessful density test at final detection." << endl; + else if (res == BSDetector::RESULT_FINAL_TOO_SMALL) + cout << "Extraction : unsuccessful spread test at final detection." + << endl; else if (res == BSDetector::RESULT_FINAL_TOO_MANY_OUTLIERS) cout << "Extraction : unsuccessful filter test at final detection." << endl; @@ -1493,13 +1546,36 @@ void BSDetectionWidget::performanceTest () { if (p1.equals (p2)) { - // No stroke -> automatic - cout << "Automatic extraction test" << endl; - clock_t start = clock (); - for (int i = 0; i < 100; i++) detector.detectAll (); - double diff = (clock () - start) / (double) CLOCKS_PER_SEC; - cout << "Test run : " << diff << endl; - extract (); +/* + if (cannyview) + { + // Canny compare -> automatic + cout << "Automatic extraction test" << endl; + clock_t start = clock (); + for (int i = 0; i < 100; i++) + { + if (gMap != NULL) delete gMap; + gMap = new VMap (width, height, getBitmap (augmentedImage), + VMap::TYPE_SOBEL_5X5); + detector.setGradientMap (gMap); + buildGradientImage (0); + detector.detectAll (); + } + double diff = (clock () - start) / (double) CLOCKS_PER_SEC; + cout << "Test run : " << diff << endl; + extract (); + } + else + { +*/ + // No stroke -> automatic + cout << "Automatic extraction test" << endl; + clock_t start = clock (); + for (int i = 0; i < 100; i++) detector.detectAll (); + double diff = (clock () - start) / (double) CLOCKS_PER_SEC; + cout << "Test run : " << diff << endl; + extract (); +// } } else { diff --git a/Code/FBSD/BSTools/bsdetectionwidget.h b/Code/FBSD/BSTools/bsdetectionwidget.h index c5b2775..1cf240e 100755 --- a/Code/FBSD/BSTools/bsdetectionwidget.h +++ b/Code/FBSD/BSTools/bsdetectionwidget.h @@ -12,6 +12,7 @@ #include "bsstructureview.h" #include "bsprofileview.h" #include "bsidetview.h" +#include "bscannyview.h" using namespace std; @@ -117,20 +118,34 @@ public: */ void switchIdetAnalyzer (); + /** + * \brief Return whether the blurred segment highlight colors are set. + */ + inline bool isHighlightColorsOn () const { return darkHighlightOn; } + /** * \brief Switches the blurred segment highlight colors. */ void switchHighlightColors (); + /** + * \brief Returns whether random color display modality is set. + */ + inline bool isArlequinOn () const { return arlequinOn; } + /** * \brief Switches the random color display modality. */ void switchArlequin (); + /** + * \brief Returns whether extraction stats are displayed. */ + inline bool isStatsOn () const { return statsOn; } + /** * \brief Switches the extraction stats display on or off. */ - inline void switchStats () { stats = ! stats; } + inline void switchStats () { statsOn = ! statsOn; } /** * \brief Switches the extraction result display on or off. @@ -246,7 +261,7 @@ private: /** Black level used to lighten background images. */ int blevel; /** Flag indicating whether detection stats should be output. */ - bool stats; + bool statsOn; /** Flag indicating whether detection result should be output. */ bool verbose; @@ -288,6 +303,8 @@ private: // BSAccumulatorView *accuview; /** Blurred segment contents view. */ BSStructureView *strucview; + /** CannyLine comparator view. */ + BSCannyView *cannyview; /** Aggregation of segment extraction results with initial conditions. */ struct ExtractedSegment @@ -403,9 +420,9 @@ private: /** * \brief Registers the last extracted blurred segment. - * Returns whether something is saved or not. + * Returns the count of registered segments more. */ - bool saveExtractedSegment (); + int saveExtractedSegment (); /** * \brief Clears off the saved blurred segments. diff --git a/Code/FBSD/BSTools/bsrandomtester.cpp b/Code/FBSD/BSTools/bsrandomtester.cpp index 84551ec..ab2d4c5 100755 --- a/Code/FBSD/BSTools/bsrandomtester.cpp +++ b/Code/FBSD/BSTools/bsrandomtester.cpp @@ -52,10 +52,9 @@ BSRandomTester::BSRandomTester () c_ldet = new int[nbt]; c_unmatch = new int[nbt]; c_undet = new int[nbt]; - c_trueArea = new int[nbt]; - c_falseArea = new int[nbt]; - c_redetArea = new int[nbt]; + c_true = new int[nbt]; c_false = new int[nbt]; + c_redet = new int[nbt]; m_precision = new double[nbt]; m_recall = new double[nbt]; @@ -69,6 +68,7 @@ BSRandomTester::BSRandomTester () m_absadiff = new double[nbt]; m_long_absadiff = new double[nbt]; + gMap = NULL; detectors = new BSDetector[nbdets]; for (int i = 0; i < nbdets; i++) { @@ -103,10 +103,9 @@ BSRandomTester::~BSRandomTester () delete [] m_fmeasure; delete [] m_recall; delete [] m_precision; + delete [] c_redet; delete [] c_false; - delete [] c_redetArea; - delete [] c_falseArea; - delete [] c_trueArea; + delete [] c_true; delete [] c_undet; delete [] c_unmatch; delete [] c_ldet; @@ -166,7 +165,7 @@ void BSRandomTester::randomTest () for (int i = 0; i < nbsegs; i++) rbs[i].clear (); c_unmatch[num] = 0; int nbdssnul = 0; - c_ldet[run] = 0; + c_ldet[num] = 0; double nomatchlength = 0.; vector<BlurredSegment *> bss = detectors[det].getBlurredSegments (); vector<BlurredSegment *>::iterator bsit = bss.begin (); @@ -214,11 +213,13 @@ void BSRandomTester::randomTest () { double denom = rdir[si].norm2 () * dssdir.norm2 (); score[si] = rdir[si].squaredScalarProduct (dssdir) / denom; - Vr2i bsac = rp1[si].vectorTo (bsc); - denom = rdir[si].norm2 () * bsac.norm2 (); - score[si] *= rdir[si].squaredScalarProduct (bsac) / denom; - if (rdir[si].scalarProduct (bsac) < 0) score[si] = 0.; + Vr2i bsca = rp1[si].vectorTo (bsc); Vr2i bscb = bsc.vectorTo (rp2[si]); + Vr2i *bsac = (rp1[si].chessboard (bsc) < sminlength / 2 ? + &bscb : &bsca); + denom = rdir[si].norm2 () * bsac->norm2 (); + score[si] *= rdir[si].squaredScalarProduct (*bsac) / denom; + if (rdir[si].scalarProduct (bsca) < 0) score[si] = 0.; if (rdir[si].scalarProduct (bscb) < 0) score[si] = 0.; if (minscore < score[si]) { @@ -232,7 +233,7 @@ void BSRandomTester::randomTest () c_unmatch[num] ++; nomatchlength += sqrt (bsl2); } - delete dss; + if (unbiasOn) delete dss; } else nbdssnul ++; bsit ++; @@ -251,34 +252,39 @@ void BSRandomTester::randomTest () } if (dispLast && run == nbruns - 1) createMap (names[det]); c_undet[num] = 0; - c_trueArea[num] = 0; - c_falseArea[num] = 0; + c_true[num] = 0; + c_false[num] = 0; for (int i = 0; i < width * height; i++) { if (stilltofind_map[i]) c_undet[num] ++; - if (foundin_map[i]) c_trueArea[num] ++; - if (foundout_map[i]) c_falseArea[num] ++; + if (foundin_map[i]) c_true[num] ++; + if (foundout_map[i]) c_false[num] ++; } if (dispEach) cout << (nbIniPts[run] - c_undet[num]) << " points detected on " << nbIniPts[run] << " (" << (nbIniPts[run] - c_undet[num]) * 100 / (double) nbIniPts[run] << " %)" << endl; - c_redetArea[num] = 0; + c_redet[num] = 0; for (int i = 0; i < width * height; i++) - if (hit_map[i] > 1) c_redetArea[num] += (hit_map[i] - 1); + if (hit_map[i] > 1) c_redet[num] += (hit_map[i] - 1); if (dispEach) - cout << c_redetArea[num] << " points redetected on " << nbIniPts[run] - << " (" << c_redetArea[num] * 100 / (double) nbIniPts[run] + cout << c_redet[num] << " points redetected on " << nbIniPts[run] + << " (" << c_redet[num] * 100 / (double) nbIniPts[run] << " %)" << endl; - c_false[num] = 0; - for (int i = 0; i < width * height; i++) - if (hit_map[i] < 0) c_false[num] ++; m_precision[num] = nbIniPts[run] - c_undet[num]; m_recall[num] = m_precision[num] / nbIniPts[run]; - m_precision[num] = m_precision[num] / (m_precision[num] + c_false[num]); - m_fmeasure[num] = 2 * m_precision[num] * m_recall[num] - / (m_precision[num] + m_recall[num]); + if (m_precision[num] + c_false[num] != 0) + { + m_precision[num] = m_precision[num] / (m_precision[num] + c_false[num]); + m_fmeasure[num] = 2 * m_precision[num] * m_recall[num] + / (m_precision[num] + m_recall[num]); + } + else + { + m_precision[num] = 0.; + m_fmeasure[num] = 0.; + } if (dispEach) { cout << c_false[num] << " false points detected on " << nbIniPts[run] @@ -338,7 +344,7 @@ void BSRandomTester::randomTest () m_adiff[num] += (onleft ? ang : -ang); if (bsl2 > longEdgeThreshold) m_long_absadiff[num] += ang; } - delete mydss; + if (unbiasOn) delete mydss; sit ++; } } @@ -418,6 +424,7 @@ void BSRandomTester::randomTest () cout << mean << " (pm " << sdev << ") undetected segments per image" << endl; + /* mean = 0.; sdev = 0.; for (int i = 0; i < nbruns; i++) @@ -429,16 +436,17 @@ void BSRandomTester::randomTest () * ((nbIniPts[i] - c_undet[det * nbruns + i]) / (double) nbIniPts[i] - mean); sdev = sqrt (sdev / (nbruns - 1)); - cout << "Recall : " << 100 * mean << " (pm " << 100 * sdev + cout << "Weighted recall : " << 100 * mean << " (pm " << 100 * sdev << ") % of points found" << endl; + */ mean = 0.; sdev = 0.; - for (int i = 0; i < nbruns; i++) mean += c_redetArea[det * nbruns + i]; + for (int i = 0; i < nbruns; i++) mean += c_redet[det * nbruns + i]; mean /= total_nbIniPts; for (int i = 0; i < nbruns; i++) - sdev += (c_redetArea[det * nbruns + i] / (double) nbIniPts[i] - mean) - * (c_redetArea[det * nbruns + i] / (double) nbIniPts[i] - mean); + sdev += (c_redet[det * nbruns + i] / (double) nbIniPts[i] - mean) + * (c_redet[det * nbruns + i] / (double) nbIniPts[i] - mean); sdev = sqrt (sdev / (nbruns - 1)); cout << 100 * mean << " (pm " << 100 * sdev << ") % of points found more than once (redetections)" << endl; @@ -454,6 +462,7 @@ void BSRandomTester::randomTest () cout << 100 * mean << " (pm " << 100 * sdev << ") % false points produced" << endl; + /* mean = 0.; sdev = 0.; int numer = 0; @@ -469,7 +478,8 @@ void BSRandomTester::randomTest () sdev += (m_precision[det * nbruns + i] - mean) * (m_precision[det * nbruns + i] - mean); sdev = sqrt (sdev / (nbruns - 1)); - cout << "Precision : " << mean << " (pm " << sdev << ")" << endl; + cout << "Weighted precision : " << mean << " (pm " << sdev << ")" << endl; + */ mean = 0.; sdev = 0.; @@ -479,8 +489,7 @@ void BSRandomTester::randomTest () sdev += (m_precision[det * nbruns + i] - mean) * (m_precision[det * nbruns + i] - mean); sdev = sqrt (sdev / (nbruns - 1)); - cout << "Statistical precision : " << mean - << " (pm " << sdev << ")" << endl; + cout << "Precision : " << mean << " (pm " << sdev << ")" << endl; mean = 0.; sdev = 0.; @@ -490,7 +499,7 @@ void BSRandomTester::randomTest () sdev += (m_recall[det * nbruns + i] - mean) * (m_recall[det * nbruns + i] - mean); sdev = sqrt (sdev / (nbruns - 1)); - cout << "Statistical recall : " << mean << " (pm " << sdev << ")" << endl; + cout << "Recall : " << mean << " (pm " << sdev << ")" << endl; mean = 0.; sdev = 0.; @@ -500,8 +509,7 @@ void BSRandomTester::randomTest () sdev += (m_fmeasure[det * nbruns + i] - mean) * (m_fmeasure[det * nbruns + i] - mean); sdev = sqrt (sdev / (nbruns - 1)); - cout << "Statistical F-measure : " << mean - << " (pm " << sdev << ")" << endl; + cout << "F-measure : " << mean << " (pm " << sdev << ")" << endl; total = 0; for (int i = 0; i < nbruns; i++) total += m_matched[det * nbruns + i]; @@ -610,39 +618,46 @@ void BSRandomTester::generateImage () val = 255 - (rand () % 30); image.setPixel (i, j, val + val * 256 + val * 256 * 256); } + + bool nok; + double score1, score2, score3; + Pt2i bsc1, bsc2; + Vr2i ali; for (int i = 0; i < nbsegs; i++) { - rp1[i].set (margin + rand () % swidth, margin + rand () % sheight); - bool nok = false; do { nok = false; - rp2[i].set (margin + rand () % swidth, margin + rand () % sheight); + rp1[i].set (margin + (rand () % swidth), margin + (rand () % sheight)); + rp2[i].set (margin + (rand () % swidth), margin + (rand () % sheight)); if (rp1[i].chessboard (rp2[i]) < sminlength) nok = true; else { - double score1, score2, score3; rdir[i] = rp1[i].vectorTo (rp2[i]); - Pt2i bsc ((rp1[i].x () + rp2[i].x ()) / 2, + bsc1.set ((rp1[i].x () + rp2[i].x ()) / 2, (rp1[i].y () + rp2[i].y ()) / 2); - for (int si = 0; (! nok) && si < i - 1; si ++) + for (int si = 0; (! nok) && si < i; si ++) { score1 = rdir[si].squaredScalarProduct (rdir[i]) - / (rdir[si].norm2 () * rdir[i].norm2 ()); - Vr2i ali = rp1[si].vectorTo (bsc); + / (double) (rdir[si].norm2 () * rdir[i].norm2 ()); + if (rp1[si].chessboard (bsc1) < sminlength / 2) + ali = bsc1.vectorTo (rp2[si]); + else ali = rp1[si].vectorTo (bsc1); score2 = rdir[si].squaredScalarProduct (ali) - / (rdir[si].norm2 () * ali.norm2 ()); - bsc.set ((rp1[si].x () + rp2[si].x ()) / 2, - (rp1[si].y () + rp2[si].y ()) / 2); - ali = rp1[i].vectorTo (bsc); + / (double) (rdir[si].norm2 () * ali.norm2 ()); + bsc2.set ((rp1[si].x () + rp2[si].x ()) / 2, + (rp1[si].y () + rp2[si].y ()) / 2); + if (rp1[i].chessboard (bsc2) < sminlength / 2) + ali = bsc2.vectorTo (rp2[i]); + else ali = rp1[i].vectorTo (bsc2); score3 = rdir[i].squaredScalarProduct (ali) - / (rdir[i].norm2 () * ali.norm2 ()); - if (score1 > 0.7 && (score2 > 0.7 || score3 > 0.7)) nok = true; + / (double) (rdir[i].norm2 () * ali.norm2 ()); + if (score1 > 0.9 && (score2 > 0.9 || score3 > 0.9)) nok = true; } } } while (nok); - rw[i] = sminwidth + rand () % (smaxwidth - sminwidth); + rw[i] = sminwidth + (rand () % (smaxwidth - sminwidth)); DigitalStraightSegment dss (rp1[i], rp2[i], rw[i]); vector<Pt2i> pix; @@ -663,6 +678,7 @@ void BSRandomTester::generateImage () tofind_map[j * width + i] = QColor (image.pixel (i, height - 1 - j)).value () < 10; // QColor (image.pixel (i, height - 1 - j)).value () > 200; // ZZZ + if (dispEach) cout << "New segments generated" << endl; } diff --git a/Code/FBSD/BSTools/bsrandomtester.h b/Code/FBSD/BSTools/bsrandomtester.h index 5b162f5..773b4b7 100755 --- a/Code/FBSD/BSTools/bsrandomtester.h +++ b/Code/FBSD/BSTools/bsrandomtester.h @@ -79,15 +79,16 @@ private: int *rw; /** Occupancy map. */ bool *tofind_map; - /** Detected points map. */ + /** Amount of detected (positive) points. + * Negative sign for false positives, positive sign for true positives. */ int *hit_map; - /** Undetected points map. */ + /** Undetected points map (false negative points). */ bool *stilltofind_map; - /** Found points map. */ + /** Found points map (positive points). */ bool *found_map; - /** Correct found points map. */ + /** Correct found points map (true positive points). */ bool *foundin_map; - /** Incorrect found points map. */ + /** Incorrect found points map (false positive points). */ bool *foundout_map; /** Per image results display modality. */ @@ -106,7 +107,7 @@ private: /** Gradient extraction bias value. */ AbsRat biasVal; - /** ???. */ + /** Amount of points to find (points of synthetized segments). */ int *nbIniPts; /** Amount of tests on local minima per each detection. */ int *c_trials; @@ -116,16 +117,14 @@ private: int *c_ldet; /** Amount of unmatched segments per each detection. */ int *c_unmatch; - /** Amount of ??? per each detection. */ + /** Amount of undetected (false negative) points per each detection. */ int *c_undet; - /** Amount of true area pixels per each detection. */ - int *c_trueArea; - /** Amount of false area pixels per each detection. */ - int *c_falseArea; - /** Amount of redetected area pixels per each detection. */ - int *c_redetArea; - /** Amount of false pixels per each detection. */ + /** Amount of trully detected (true positive) points per each detection. */ + int *c_true; + /** Amount of wrongly detected (false positive) points per each detection. */ int *c_false; + /** Amount of redetected points per each detection. */ + int *c_redet; /** Measured precision per detector and per test. */ double *m_precision; diff --git a/Code/FBSD/BlurredSegment/bsdetector.cpp b/Code/FBSD/BlurredSegment/bsdetector.cpp index a4b1b26..9458174 100755 --- a/Code/FBSD/BlurredSegment/bsdetector.cpp +++ b/Code/FBSD/BlurredSegment/bsdetector.cpp @@ -7,6 +7,7 @@ const int BSDetector::STEP_FINAL = 0; const int BSDetector::STEP_INITIAL = 1; const int BSDetector::STEP_PRELIM = 2; +const int BSDetector::RESULT_VOID = -2; const int BSDetector::RESULT_UNDETERMINED = -1; const int BSDetector::RESULT_OK = 0; const int BSDetector::RESULT_PRELIM_NO_DETECTION = 1; @@ -19,7 +20,8 @@ const int BSDetector::RESULT_INITIAL_CLOSE_ORIENTATION = 15; const int BSDetector::RESULT_FINAL_NO_DETECTION = 21; const int BSDetector::RESULT_FINAL_TOO_FEW = 22; const int BSDetector::RESULT_FINAL_TOO_SPARSE = 23; -const int BSDetector::RESULT_FINAL_TOO_MANY_OUTLIERS = 24; +const int BSDetector::RESULT_FINAL_TOO_SMALL = 24; +const int BSDetector::RESULT_FINAL_TOO_MANY_OUTLIERS = 25; const int BSDetector::DEFAULT_FAST_TRACK_SCAN_WIDTH = 16; const int BSDetector::DEFAULT_FINE_TRACK_MAX_WIDTH = 3; @@ -66,6 +68,9 @@ BSDetector::BSDetector () densityTestOn = true; finalDensityTestOn = false; finalLengthTestOn = false; + finalSpreadTestOn = true; + finalSpreadMin = 30; + // nbSmallBS = 0; multiSelection = false; autodet = false; autoResol = DEFAULT_AUTO_RESOLUTION; @@ -112,6 +117,7 @@ void BSDetector::detectAll () bool isnext = true; nbtrials = 0; + // nbSmallBS = 0; int width = gMap->getWidth (); int height = gMap->getHeight (); for (int x = width / 2; isnext && x > 0; x -= autoResol) @@ -123,6 +129,7 @@ void BSDetector::detectAll () for (int y = height / 2 + autoResol; isnext && y < height - 1; y += autoResol) isnext = runMultiDetection (Pt2i (0, y), Pt2i (width - 1, y)); if (maxtrials > (int) (mbsf.size ())) maxtrials = 0; + // cout << nbSmallBS << " petits BS elimines" << endl; gMap->setMasking (false); } @@ -137,6 +144,7 @@ void BSDetector::detectAllWithBalancedXY () bool isnext = true; nbtrials = 0; + // nbSmallBS = 0; int width = gMap->getWidth (); int height = gMap->getHeight (); int xg = width / 2, yb = height / 2; @@ -170,6 +178,7 @@ void BSDetector::detectAllWithBalancedXY () } } if (maxtrials > (int) (mbsf.size ())) maxtrials = 0; + // cout << nbSmallBS << " petits BS elimines" << endl; gMap->setMasking (false); } @@ -183,13 +192,15 @@ void BSDetector::detectSelection (const Pt2i &p1, const Pt2i &p2) gMap->setMasking (true); gMap->clearMask (); nbtrials = 0; + // nbSmallBS = 0; runMultiDetection (p1, p2); + // cout << nbSmallBS << " petits BS elimines" << endl; if (maxtrials > (int) (mbsf.size ())) maxtrials = 0; gMap->setMasking (false); } else - if (oldp) olddetect (p1, p2); - else detect (p1, p2); + if (oldp) resultValue = olddetect (p1, p2); + else resultValue = detect (p1, p2); } @@ -224,9 +235,10 @@ bool BSDetector::runMultiDetection (const Pt2i &p1, const Pt2i &p2) if (edgeDirection != 0) edgeDirection = 1; while (isnext && edgeDirection >= -1) { - if (oldp) olddetect (p1, p2, true, ptstart); - else detect (p1, p2, true, ptstart); - if (bsf != NULL) + int res = RESULT_VOID; + if (oldp) res = olddetect (p1, p2, true, ptstart); + else res = detect (p1, p2, true, ptstart); + if (res == RESULT_OK) { gMap->setMask (bsf->getAllPoints ()); mbsf.push_back (bsf); @@ -243,17 +255,17 @@ bool BSDetector::runMultiDetection (const Pt2i &p1, const Pt2i &p2) } -void BSDetector::olddetect (const Pt2i &p1, const Pt2i &p2, - bool centralp, const Pt2i &pc) +int BSDetector::olddetect (const Pt2i &p1, const Pt2i &p2, + bool centralp, const Pt2i &pc) { // Entry check //------------ if (p1.equals (p2) - || ((! centralp) && p1.chessboard (p2) < BSTracker::MIN_SCAN)) return; + || ((! centralp) && p1.chessboard (p2) < BSTracker::MIN_SCAN)) + return RESULT_VOID; // Clearance //---------- - resultValue = RESULT_UNDETERMINED; bst1->clear (); bst2->clear (); if (bsini != NULL) delete bsini; @@ -271,11 +283,8 @@ void BSDetector::olddetect (const Pt2i &p1, const Pt2i &p2, bsini = bst1->fastTrack (DEFAULT_FAST_TRACK_SCAN_WIDTH / 4, inip1, inip2, iniwidth, inipc); if (bsini == NULL || bsini->size () < bsMinSize) - { - resultValue = (bsini == NULL ? RESULT_INITIAL_NO_DETECTION - : RESULT_INITIAL_TOO_FEW); - return; - } + return (bsini == NULL ? RESULT_INITIAL_NO_DETECTION + : RESULT_INITIAL_TOO_FEW); // Density test //------------- @@ -288,10 +297,7 @@ void BSDetector::olddetect (const Pt2i &p1, const Pt2i &p2, if (mydrlf < 0) mydrlf = -mydrlf; // Case of horizontal P1P2 int expansion = 1 + mydrlf; if (bsini->size () < expansion / 2) - { - resultValue = RESULT_INITIAL_TOO_SPARSE; - return; - } + return RESULT_INITIAL_TOO_SPARSE; } */ @@ -299,10 +305,7 @@ void BSDetector::olddetect (const Pt2i &p1, const Pt2i &p2, //------------------------------------------- Vr2i bsinidir = bsini->getSupportVector(); if (bsinidir.orientedAs (inip1.vectorTo (inip2))) - { - resultValue = RESULT_INITIAL_CLOSE_ORIENTATION; - return; - } + return RESULT_INITIAL_CLOSE_ORIENTATION; // Gradient reference selection //----------------------------- @@ -320,11 +323,7 @@ void BSDetector::olddetect (const Pt2i &p1, const Pt2i &p2, bsf = bstold->fineTrack (fmaxWidth, pCenter, bsinidir, 4 * fmaxWidth, gRef); if (bsf == NULL || bsf->size () < bsMinSize) - { - resultValue = (bsf == NULL ? RESULT_FINAL_NO_DETECTION - : RESULT_FINAL_TOO_FEW); - return; - } + return (bsf == NULL ? RESULT_FINAL_NO_DETECTION : RESULT_FINAL_TOO_FEW); // Scan recentering and fitting //----------------------------- @@ -339,10 +338,12 @@ void BSDetector::olddetect (const Pt2i &p1, const Pt2i &p2, 4 * fmaxWidth, gRef); if (bsf2 == NULL || bsf2->size () < bsMinSize) { - resultValue = (bsf2 == NULL ? RESULT_FINAL_NO_DETECTION - : RESULT_FINAL_TOO_FEW); - if (bsf2 != NULL) delete bsf2; - return; + if (bsf2 != NULL) + { + delete bsf2; + return RESULT_FINAL_TOO_FEW; + } + else return RESULT_FINAL_NO_DETECTION; } else { @@ -357,12 +358,7 @@ void BSDetector::olddetect (const Pt2i &p1, const Pt2i &p2, DigitalStraightSegment *dss = bsf->getSegment (); if (dss == NULL || (int) (bsf->getAllPoints().size ()) < (10 * dss->period ()) / dss->width ()) - { - resultValue = RESULT_FINAL_TOO_SPARSE; - delete bsf; - bsf = NULL; - return; - } + return RESULT_FINAL_TOO_SPARSE; } // New density test @@ -375,12 +371,7 @@ void BSDetector::olddetect (const Pt2i &p1, const Pt2i &p2, if (mydrlf < 0) mydrlf = -mydrlf; // Case of horizontal P1P2 int expansion = 1 + mydrlf; if (bsf->size () < expansion / 2) - { - resultValue = RESULT_FINAL_TOO_SPARSE; - delete bsf; - bsf = NULL; - return; - } + return RESULT_FINAL_TOO_SPARSE; } // Connected components analysis @@ -390,40 +381,30 @@ void BSDetector::olddetect (const Pt2i &p1, const Pt2i &p2, int bsccp = bsf->countOfConnectedPoints (ccMinSize); int bssize = bsf->getAllPoints().size (); if (bsccp < bssize / 2) - { - resultValue = RESULT_FINAL_TOO_SPARSE; - delete bsf; - bsf = NULL; - return; - } + return RESULT_FINAL_TOO_SPARSE; /* if (bssize < 20 || bsf->countOfConnectedComponents (bssize / 4) == 0) - { - resultValue = RESULT_FINAL_TOO_SPARSE; - delete bsf; - bsf = NULL; - return; - } + return RESULT_FINAL_TOO_SPARSE; */ } - resultValue = RESULT_OK; + return RESULT_OK; } -void BSDetector::detect (const Pt2i &p1, const Pt2i &p2, - bool centralp, const Pt2i &pc) +int BSDetector::detect (const Pt2i &p1, const Pt2i &p2, + bool centralp, const Pt2i &pc) { // Entry check //------------ if (p1.equals (p2) - || ((! centralp) && p1.chessboard (p2) < BSTracker::MIN_SCAN)) return; + || ((! centralp) && p1.chessboard (p2) < BSTracker::MIN_SCAN)) + return RESULT_VOID; // Clearance //---------- - resultValue = RESULT_UNDETERMINED; if (prelimDetectionOn) bst0->clear (); bst1->clear (); bst2->clear (); @@ -448,11 +429,8 @@ void BSDetector::detect (const Pt2i &p1, const Pt2i &p2, bspre = bst0->fastTrack (fmaxWidth + imaxMargin, prep1, prep2, prewidth, prepc); if (bspre == NULL || bspre->size () < bsMinSize) - { - resultValue = (bspre == NULL ? RESULT_PRELIM_NO_DETECTION - : RESULT_PRELIM_TOO_FEW); - return; - } + return (bspre == NULL ? RESULT_PRELIM_NO_DETECTION + : RESULT_PRELIM_TOO_FEW); Vr2i v0 = bspre->getSupportVector (); int l = v0.chessboard (); @@ -481,11 +459,8 @@ void BSDetector::detect (const Pt2i &p1, const Pt2i &p2, bsini = bst1->fastTrack (fmaxWidth + imaxMargin, inip1, inip2, iniwidth, inipc); if (bsini == NULL || bsini->size () < bsMinSize) - { - resultValue = (bsini == NULL ? RESULT_INITIAL_NO_DETECTION - : RESULT_INITIAL_TOO_FEW); - return; - } + return (bsini == NULL ? RESULT_INITIAL_NO_DETECTION + : RESULT_INITIAL_TOO_FEW); // Density test //------------- @@ -497,10 +472,7 @@ void BSDetector::detect (const Pt2i &p1, const Pt2i &p2, if (mydrlf < 0) mydrlf = -mydrlf; // Case of horizontal P1P2 int expansion = 1 + mydrlf; if (bsini->size () < expansion / 2) - { - resultValue = RESULT_INITIAL_TOO_SPARSE; - return; - } + return RESULT_INITIAL_TOO_SPARSE; } // Filtering the initial segment @@ -515,19 +487,13 @@ void BSDetector::detect (const Pt2i &p1, const Pt2i &p2, } } if (bsini->size () < bsMinSize) - { - resultValue = RESULT_INITIAL_TOO_MANY_OUTLIERS; - return; - } + return RESULT_INITIAL_TOO_MANY_OUTLIERS; // Orientation test for automatic extractions //------------------------------------------- Vr2i bsinidir = bsini->getSupportVector(); if (bsinidir.orientedAs (inip1.vectorTo (inip2))) - { - resultValue = RESULT_INITIAL_CLOSE_ORIENTATION; - return; - } + return RESULT_INITIAL_CLOSE_ORIENTATION; // Gradient reference selection //----------------------------- @@ -551,10 +517,18 @@ void BSDetector::detect (const Pt2i &p1, const Pt2i &p2, //--------------------------------------------------------------------- bsf = bst2->fineTrack (bswidth, pCenter, bsinidir, 2 * bswidth, gRef); if (bsf == NULL || bsf->size () < bsMinSize) + return (bsf == NULL ? RESULT_FINAL_NO_DETECTION : RESULT_FINAL_TOO_FEW); + + // Spread test + //------------ + if (finalSpreadTestOn) { - resultValue = (bsf == NULL ? RESULT_FINAL_NO_DETECTION - : RESULT_FINAL_TOO_FEW); - return; + // DigitalStraightSegment *dss = bsf->getSegment (); + if ((int) (bsf->getAllPoints().size ()) < finalSpreadMin) + { + // nbSmallBS ++; + return RESULT_FINAL_TOO_SMALL; + } } // Length test @@ -565,12 +539,7 @@ void BSDetector::detect (const Pt2i &p1, const Pt2i &p2, if ((int) (bsf->getAllPoints().size ()) < (3 * dss->width ()) / dss->period ()) // if ((int) (bsf->getAllPoints().size ()) < 10) - { - resultValue = RESULT_FINAL_TOO_SPARSE; - delete bsf; - bsf = NULL; - return; - } + return RESULT_FINAL_TOO_SPARSE; } // New density test @@ -583,12 +552,7 @@ void BSDetector::detect (const Pt2i &p1, const Pt2i &p2, if (mydrlf < 0) mydrlf = -mydrlf; // Case of horizontal P1P2 int expansion = 1 + mydrlf; if (expansion < 20 && bsf->size () < (expansion * 4) / 5) - { - resultValue = RESULT_FINAL_TOO_SPARSE; - delete bsf; - bsf = NULL; - return; - } + return RESULT_FINAL_TOO_SPARSE; } // Connected components analysis */ @@ -598,21 +562,11 @@ void BSDetector::detect (const Pt2i &p1, const Pt2i &p2, int bsccp = bsf->countOfConnectedPoints (ccMinSize); int bssize = bsf->getAllPoints().size (); if (bsccp < bssize / 2) - { - resultValue = RESULT_FINAL_TOO_SPARSE; - delete bsf; - bsf = NULL; - return; - } + return RESULT_FINAL_TOO_SPARSE; /* if (bssize < 20 || bsf->countOfConnectedComponents (bssize / 2) == 0) - { - resultValue = RESULT_FINAL_TOO_SPARSE; - delete bsf; - bsf = NULL; - return; - } + return RESULT_FINAL_TOO_SPARSE; */ } @@ -624,13 +578,13 @@ void BSDetector::detect (const Pt2i &p1, const Pt2i &p2, BlurredSegment *fbsf = lsf2->filter (bsf); if (fbsf != NULL) { - resultValue = RESULT_FINAL_TOO_MANY_OUTLIERS; delete bsf; bsf = fbsf; } + else return RESULT_FINAL_TOO_MANY_OUTLIERS; } - resultValue = RESULT_OK; + return RESULT_OK; } diff --git a/Code/FBSD/BlurredSegment/bsdetector.h b/Code/FBSD/BlurredSegment/bsdetector.h index 8d85816..24d4fd9 100755 --- a/Code/FBSD/BlurredSegment/bsdetector.h +++ b/Code/FBSD/BlurredSegment/bsdetector.h @@ -27,6 +27,8 @@ public: /** Identifier for the preliminary detection step. */ static const int STEP_PRELIM; + /** Extraction result : void input. */ + static const int RESULT_VOID; /** Extraction result : successful extraction. */ static const int RESULT_UNDETERMINED; /** Extraction result : successful extraction. */ @@ -51,6 +53,8 @@ public: static const int RESULT_FINAL_TOO_FEW; /** Extraction result : unsuccessful connectivity test at final detection. */ static const int RESULT_FINAL_TOO_SPARSE; + /** Extraction result : unsuccessful spread test at final detection. */ + static const int RESULT_FINAL_TOO_SMALL; /** Extraction result : unsuccessful filter test at final detection. */ static const int RESULT_FINAL_TOO_MANY_OUTLIERS; @@ -109,13 +113,14 @@ public: * The first candidates that prolongates the segment are retained. * Step 4: Outliers pruning based on parameter space filtering. * Note : Multi-detection along a stroke requires an initial start point. + * Returns the detection status (RESULT_OK if successfull). * @param p1 First input point. * @param p2 Second input point. * @param centralp Set to true if the central point is provided. * @param pc Initial central point. */ - void detect (const Pt2i &p1, const Pt2i &p2, - bool centralp = false, const Pt2i &pc = Pt2i ()); + int detect (const Pt2i &p1, const Pt2i &p2, + bool centralp = false, const Pt2i &pc = Pt2i ()); /** * \brief Detects a blurred segment between two input points. @@ -128,13 +133,14 @@ public: * Step 3: id. step 2. * The directional scan is oriented on the segment of step 2. * Note : Multi-detection along a stroke requires an initial start point. + * Returns the detection status (RESULT_OK if successfull). * @param p1 First input point. * @param p2 Second input point. * @param centralp Set to true if the central point is provided. * @param pc Initial central point. */ - void olddetect (const Pt2i &p1, const Pt2i &p2, - bool centralp = false, const Pt2i &pc = Pt2i ()); + int olddetect (const Pt2i &p1, const Pt2i &p2, + bool centralp = false, const Pt2i &pc = Pt2i ()); /** * \brief Returns the detected blurred segment at given step. @@ -640,6 +646,12 @@ private : bool finalDensityTestOn; /** Length test modality after final detection. */ bool finalLengthTestOn; + /** Spread test modality after final detection. */ + bool finalSpreadTestOn; + /** Spread test min value. */ + int finalSpreadMin; + /** Count of small BS eliminated by the spread test. */ + int nbSmallBS; /** Segment multi-selection modality status. */ bool multiSelection; /** Count of trials in a multi-detection. */ diff --git a/Code/FBSD/ImageTools/vmap.cpp b/Code/FBSD/ImageTools/vmap.cpp index eb88b07..7f5afed 100755 --- a/Code/FBSD/ImageTools/vmap.cpp +++ b/Code/FBSD/ImageTools/vmap.cpp @@ -15,7 +15,7 @@ const int VMap::TYPE_FULL_BLACK_HAT = 6; const int VMap::TYPE_FULL_MORPHO = 7; const int VMap::NEAR_SQ_ANGLE = 80; // 80% (roughly 25 degrees) -const int VMap::DEFAULT_GRADIENT_THRESHOLD = 33; +const int VMap::DEFAULT_GRADIENT_THRESHOLD = 20; const int VMap::DEFAULT_GRADIENT_RESOLUTION = 100; const int VMap::MAX_BOWL = 20; @@ -109,7 +109,7 @@ VMap::VMap (int width, int height, int *data, int type) imap[i] = (int) sqrt (map[i].norm2 ()); gmagThreshold *= gradientThreshold; } - else // type == TYPE_SOBEL_3X3 + else if (type == TYPE_SOBEL_3X3) { buildGradientMap (data); for (int i = 0; i < width * height; i++) @@ -205,7 +205,7 @@ VMap::VMap (int width, int height, int **data, int type) imap[i] = (int) sqrt (map[i].norm2 ()); gmagThreshold *= gradientThreshold; } - else // type == TYPE_SOBEL_3X3 + else if (type == TYPE_SOBEL_3X3) { buildGradientMap (data); for (int i = 0; i < width * height; i++) @@ -234,7 +234,7 @@ void VMap::init () for (int i = 0; i < width * height; i++) mask[i] = false; masking = false; angleThreshold = NEAR_SQ_ANGLE; - orientedGradient = false; + orientedGradient = true; bowl = new Vr2i[MAX_BOWL]; bowl[0] = Vr2i (1, 0); bowl[1] = Vr2i (0, 1); -- GitLab