From 5f5c8605b9861e7b0a8f529087600d4de0623788 Mon Sep 17 00:00:00 2001 From: even <philippe.even@loria.fr> Date: Fri, 19 Apr 2019 17:44:34 +0200 Subject: [PATCH] Detected lines selection (right mouse) --- Code/FBSD/BSTools/bsdetectionwidget.cpp | 163 ++++++++++++------ Code/FBSD/BSTools/bsdetectionwidget.h | 40 +++-- Code/FBSD/BSTools/bswindow.cpp | 16 +- Code/FBSD/BlurredSegment/bsdetector.cpp | 4 +- Code/FBSD/BlurredSegment/bsdetector.h | 6 + .../ImageTools/digitalstraightsegment.cpp | 12 ++ Code/FBSD/ImageTools/digitalstraightsegment.h | 7 + Code/FBSD/main.cpp | 73 ++++++-- 8 files changed, 228 insertions(+), 93 deletions(-) diff --git a/Code/FBSD/BSTools/bsdetectionwidget.cpp b/Code/FBSD/BSTools/bsdetectionwidget.cpp index ecf3fa1..cf65f36 100755 --- a/Code/FBSD/BSTools/bsdetectionwidget.cpp +++ b/Code/FBSD/BSTools/bsdetectionwidget.cpp @@ -1,3 +1,4 @@ +#include <QtGui> #include <iostream> #include <fstream> #include <cstdlib> @@ -16,6 +17,7 @@ const int BSDetectionWidget::BACK_GRADX = 4; const int BSDetectionWidget::BACK_GRADY = 5; const int BSDetectionWidget::DEFAULT_PEN_WIDTH = 1; +const int BSDetectionWidget::SELECT_TOL = 5; @@ -26,17 +28,18 @@ BSDetectionWidget::BSDetectionWidget (QWidget *parent) // Sets initial user inputs parameters setFocus (); grabKeyboard (); + picking = false; udef = false; nodrag = true; // Initializes the gradient map and the auxiliary views gMap = NULL; - // accuview = NULL; - strucview = NULL; - profileview = NULL; - idetview = NULL; - cannyview = NULL; - yorkview = NULL; + // accuview = NULL; // DEV + strucview = NULL; // DEV + profileview = NULL; // DEV + idetview = NULL; // DEV + cannyview = NULL; // DEV + yorkview = NULL; // DEV // Sets initial user outputs parameters verbose = false; @@ -67,12 +70,12 @@ BSDetectionWidget::BSDetectionWidget (QWidget *parent) BSDetectionWidget::~BSDetectionWidget () { - // if (accuview != NULL) delete accuview; - if (strucview != NULL) delete strucview; - if (profileview != NULL) delete profileview; - if (idetview != NULL) delete idetview; - if (cannyview != NULL) delete cannyview; - if (yorkview != NULL) delete yorkview; + // if (accuview != NULL) delete accuview; // DEV + if (strucview != NULL) delete strucview; // DEV + if (profileview != NULL) delete profileview; // DEV + if (idetview != NULL) delete idetview; // DEV + if (cannyview != NULL) delete cannyview; // DEV + if (yorkview != NULL) delete yorkview; // DEV } @@ -91,9 +94,9 @@ QSize BSDetectionWidget::openImage (const QString &fileName, int type) buildGradientImage (0); update (); - if (idetview != NULL) idetview->setImage (&loadedImage, gMap); - if (profileview != NULL) profileview->setImage (&loadedImage, gMap); - if (strucview != NULL) strucview->setGradientImage (&gradImage); + if (idetview != NULL) idetview->setImage (&loadedImage, gMap); // DEV + if (profileview != NULL) profileview->setImage (&loadedImage, gMap); // DEV + if (strucview != NULL) strucview->setGradientImage (&gradImage); // DEV xMaxShift = (width > maxWidth ? maxWidth - width : 0); yMaxShift = (height > maxHeight ? maxHeight - height : 0); @@ -201,6 +204,7 @@ void BSDetectionWidget::paintEvent (QPaintEvent *) } +// DEV IN /* void BSDetectionWidget::closeAccuAnalyzer () { @@ -316,6 +320,7 @@ void BSDetectionWidget::switchIdetAnalyzer () idetview->show (); } } +// DEV OUT void BSDetectionWidget::switchHighlightColors () @@ -342,54 +347,94 @@ void BSDetectionWidget::switchArlequin () void BSDetectionWidget::mousePressEvent (QMouseEvent *event) { - oldp1.set (p1); - oldp2.set (p2); - oldudef = udef; int ex = zoom * (event->pos().x () - xShift); - int ey = zoom * (event->pos().y () - yShift); - p1 = Pt2i (ex, height - 1 - ey); - if (p1.manhattan (p2) < 10) p1.set (oldp1); - else if (p1.manhattan (oldp1) < 10) p1.set (p2); - udef = true; + int ey = height - 1 - zoom * (event->pos().y () - yShift); + + if (event->button () == Qt::RightButton) + { + vector<BlurredSegment *> bsl = detector.getBlurredSegments (); + if (! bsl.empty ()) + { + bool searching = true; + int nb = 0; + vector<BlurredSegment *>::iterator it = bsl.begin (); + while (searching && it != bsl.end ()) + { + if (*it != NULL) + { + DigitalStraightSegment *dss = (*it)->getSegment (); + if (dss != NULL) + { + if (dss->contains (Pt2i (ex, ey), SELECT_TOL)) searching = false; + else nb ++; + } + else nb ++; + } + else nb ++; + it ++; + } + cout << "Selection of segment " << (searching ? 0 : nb + 1) << endl; + detector.setMaxDetections (searching ? 0 : nb + 1); + extract (); + } + picking = true; + } + else + { + oldp1.set (p1); + oldp2.set (p2); + oldudef = udef; + p1 = Pt2i (ex, ey); + if (p1.manhattan (p2) < 10) p1.set (oldp1); + else if (p1.manhattan (oldp1) < 10) p1.set (p2); + udef = true; + } } void BSDetectionWidget::mouseReleaseEvent (QMouseEvent *event) { - int ex = zoom * (event->pos().x () - xShift); - int ey = zoom * (event->pos().y () - yShift); - p2 = Pt2i (ex, height - 1 - ey); - if (p1.equals (p2)) - { - p1.set (oldp1); - p2.set (oldp2); - udef = oldudef; - } - else + if (! picking) { - cerr << "p1 defined: " << p1.x () << " " << p1.y () << endl; - cerr << "p2 defined: " << p2.x () << " " << p2.y () << endl; - detector.resetMaxDetections (); - extract (); + int ex = zoom * (event->pos().x () - xShift); + int ey = zoom * (event->pos().y () - yShift); + p2 = Pt2i (ex, height - 1 - ey); + if (p1.equals (p2)) + { + p1.set (oldp1); + p2.set (oldp2); + udef = oldudef; + } + else + { + cerr << "p1 defined: " << p1.x () << " " << p1.y () << endl; + cerr << "p2 defined: " << p2.x () << " " << p2.y () << endl; + detector.resetMaxDetections (); + extract (); + } } } void BSDetectionWidget::mouseMoveEvent (QMouseEvent *event) { - int ex = zoom * (event->pos().x () - xShift); - int ey = zoom * (event->pos().y () - yShift); - p2 = Pt2i (ex, height - 1 - ey); - if (verbose) cerr << "(" << p1.x () << ", " << p1.y () << ") (" - << p2.x () << ", " << p2.y () << ")" << endl; - if (p1.manhattan (p2) > 5 - && (width > p2.x() && height > p2.y() - && p2.x() > 0 && p2.y() > 0)) + if (picking) picking = false; + else { - nodrag = false; - extract (); - nodrag = true; - detector.setMaxTrials (0); + int ex = zoom * (event->pos().x () - xShift); + int ey = zoom * (event->pos().y () - yShift); + p2 = Pt2i (ex, height - 1 - ey); + if (verbose) cerr << "(" << p1.x () << ", " << p1.y () << ") (" + << p2.x () << ", " << p2.y () << ")" << endl; + if (p1.manhattan (p2) > 5 + && (width > p2.x() && height > p2.y() + && p2.x() > 0 && p2.y() > 0)) + { + nodrag = false; + extract (); + nodrag = true; + detector.setMaxTrials (0); + } } } @@ -839,6 +884,7 @@ void BSDetectionWidget::keyPressEvent (QKeyEvent *event) cout << "Selection stroke saved" << endl; break; +// DEV IN case Qt::Key_Percent : if (cannyview == NULL) cannyview = new BSCannyView (&loadedImage, &detector); @@ -850,6 +896,7 @@ void BSDetectionWidget::keyPressEvent (QKeyEvent *event) yorkview = new BSYorkView (&loadedImage, &detector); yorkview->show (); break; +// DEV OUT case Qt::Key_Plus : if (zoom > 1) @@ -909,6 +956,7 @@ void BSDetectionWidget::keyPressEvent (QKeyEvent *event) displayDetectionResult (); break; +// DEV IN case Qt::Key_1 : switchPixelAnalyzer (); break; @@ -924,6 +972,7 @@ void BSDetectionWidget::keyPressEvent (QKeyEvent *event) case Qt::Key_4 : switchIdetAnalyzer (); break; +// DEV OUT case Qt::Key_5 : // Switches the crosswise segment detection @@ -956,14 +1005,17 @@ void BSDetectionWidget::keyPressEvent (QKeyEvent *event) localTest (); break; } +// DEV IN else if (strucview != NULL && strucview->isActiveWindow ()) { if (strucview->processKeyEvent (event)) extract (); } - /* else if (accuview != NULL && accuview->isActiveWindow ()) + /* + else if (accuview != NULL && accuview->isActiveWindow ()) { if (accuview->processKeyEvent (event)) extract (); - } */ + } + */ else if (profileview != NULL && profileview->isActiveWindow ()) { if (profileview->processKeyEvent (event)) extract (); @@ -980,6 +1032,7 @@ void BSDetectionWidget::keyPressEvent (QKeyEvent *event) { if (cannyview->processKeyEvent (event)) extract (); } +// DEV OUT } @@ -1157,7 +1210,7 @@ void BSDetectionWidget::writeDetectionResult () } } else - { + { ofstream outf ("segs.txt", ios::out); vector<BlurredSegment *>::iterator it = bss.begin (); while (it != bss.end ()) @@ -1223,6 +1276,7 @@ void BSDetectionWidget::displayDetectionResult () // Update auxiliary view if not dragging if (nodrag) { +// DEV IN if (idetview != NULL) idetview->update (); if (profileview != NULL) { @@ -1235,6 +1289,7 @@ void BSDetectionWidget::displayDetectionResult () strucview->scene()->update (); strucview->repaint (); } +// DEV OUT if (verbose) writeDetectionStatus (); if (statsOn) writeStats (); } @@ -1561,6 +1616,7 @@ void BSDetectionWidget::performanceTest () { if (p1.equals (p2)) { +// DEV IN /* if (cannyview) { @@ -1583,6 +1639,7 @@ void BSDetectionWidget::performanceTest () else { */ +// DEV OUT // No stroke -> automatic cout << "Automatic extraction test" << endl; clock_t start = clock (); @@ -1590,7 +1647,7 @@ void BSDetectionWidget::performanceTest () double diff = (clock () - start) / (double) CLOCKS_PER_SEC; cout << "Test run : " << diff << endl; extract (); -// } +// } // DEV } else { diff --git a/Code/FBSD/BSTools/bsdetectionwidget.h b/Code/FBSD/BSTools/bsdetectionwidget.h index 53dad09..94572bd 100755 --- a/Code/FBSD/BSTools/bsdetectionwidget.h +++ b/Code/FBSD/BSTools/bsdetectionwidget.h @@ -8,12 +8,12 @@ #include <QVector> #include <fstream> #include "bsdetector.h" -// #include "bsaccumulatorview.h" -#include "bsstructureview.h" -#include "bsprofileview.h" -#include "bsidetview.h" -#include "bscannyview.h" -#include "bsyorkview.h" +// #include "bsaccumulatorview.h" // DEV +#include "bsstructureview.h" // DEV +#include "bsprofileview.h" // DEV +#include "bsidetview.h" // DEV +#include "bscannyview.h" // DEV +#include "bsyorkview.h" // DEV using namespace std; @@ -221,6 +221,8 @@ private: /** Default value for pen width. */ static const int DEFAULT_PEN_WIDTH; + /** Tolerence for segment picking (in count of naive lines) */ + static const int SELECT_TOL; /** Initial scan start point. */ @@ -233,6 +235,8 @@ private: Pt2i oldp2; /** Flag indicating if the mouse is not dragging. */ bool nodrag; + /** Flag indicating if picking mode is set. */ + bool picking; /** Flag indicating if the detection is user defined. */ bool udef; /** Saved user definition flag. */ @@ -296,18 +300,18 @@ private: /** Blurred segment detector. */ BSDetector detector; - /** Initial detection graphics view. */ - BSIdetView *idetview; - /** Scanned profile graphics view. */ - BSProfileView *profileview; - /** Filter accumulator view. */ - // BSAccumulatorView *accuview; - /** Blurred segment contents view. */ - BSStructureView *strucview; - /** CannyLine comparator view. */ - BSCannyView *cannyview; - /** YorkLine comparator view. */ - BSYorkView *yorkview; + /** Initial detection graphics view. */ // DEV + BSIdetView *idetview; // DEV + /** Scanned profile graphics view. */ // DEV + BSProfileView *profileview; // DEV + /** Filter accumulator view. */ // DEV + // BSAccumulatorView *accuview; // DEV + /** Blurred segment contents view. */ // DEV + BSStructureView *strucview; // DEV + /** CannyLine comparator view. */ // DEV + BSCannyView *cannyview; // DEV + /** YorkLine comparator view. */ // DEV + BSYorkView *yorkview; // DEV /** Aggregation of segment extraction results with initial conditions. */ struct ExtractedSegment diff --git a/Code/FBSD/BSTools/bswindow.cpp b/Code/FBSD/BSTools/bswindow.cpp index 465abd7..cf609d2 100755 --- a/Code/FBSD/BSTools/bswindow.cpp +++ b/Code/FBSD/BSTools/bswindow.cpp @@ -49,10 +49,10 @@ void BSWindow::setFile (QString fileName) void BSWindow::runOptions () { - if (showIdet) detectionWidget->switchIdetAnalyzer (); - if (showProf) detectionWidget->switchProfileAnalyzer (); - // if (showAccu) detectionWidget->switchAccuAnalyzer (); - if (showSeg) detectionWidget->switchPixelAnalyzer (); + if (showIdet) detectionWidget->switchIdetAnalyzer (); // DEV + if (showProf) detectionWidget->switchProfileAnalyzer (); // DEV + // if (showAccu) detectionWidget->switchAccuAnalyzer (); // DEV + if (showSeg) detectionWidget->switchPixelAnalyzer (); // DEV } @@ -64,10 +64,10 @@ void BSWindow::runTest () void BSWindow::closeEvent (QCloseEvent *event) { - detectionWidget->closeIdetAnalyzer (); - detectionWidget->closeProfileAnalyzer (); - // detectionWidget->closeAccuAnalyzer (); - detectionWidget->closePixelAnalyzer (); + detectionWidget->closeIdetAnalyzer (); // DEV + detectionWidget->closeProfileAnalyzer (); // DEV + // detectionWidget->closeAccuAnalyzer (); // DEV + detectionWidget->closePixelAnalyzer (); // DEV event->accept (); } diff --git a/Code/FBSD/BlurredSegment/bsdetector.cpp b/Code/FBSD/BlurredSegment/bsdetector.cpp index 88d3b35..c7d518f 100755 --- a/Code/FBSD/BlurredSegment/bsdetector.cpp +++ b/Code/FBSD/BlurredSegment/bsdetector.cpp @@ -68,8 +68,8 @@ BSDetector::BSDetector () densityTestOn = true; finalDensityTestOn = false; finalLengthTestOn = false; - finalSpreadTestOn = true; - finalSpreadMin = 30; + finalSpreadTestOn = false; + finalSpreadMin = 10; // nbSmallBS = 0; multiSelection = false; autodet = false; diff --git a/Code/FBSD/BlurredSegment/bsdetector.h b/Code/FBSD/BlurredSegment/bsdetector.h index 96935e7..3c32feb 100755 --- a/Code/FBSD/BlurredSegment/bsdetector.h +++ b/Code/FBSD/BlurredSegment/bsdetector.h @@ -578,6 +578,12 @@ public: */ void incMaxDetections (bool dir); + /** + * \brief Sets the maximum number of detections in a multi-detection. + * @param nb Number of detections (0 if illimited). + */ + inline void setMaxDetections (int nb) { maxtrials = nb; } + /** * \brief Resets the maximum number of detections set for a multi-detection. */ diff --git a/Code/FBSD/ImageTools/digitalstraightsegment.cpp b/Code/FBSD/ImageTools/digitalstraightsegment.cpp index c0bb5b0..1e63a8d 100755 --- a/Code/FBSD/ImageTools/digitalstraightsegment.cpp +++ b/Code/FBSD/ImageTools/digitalstraightsegment.cpp @@ -200,3 +200,15 @@ void DigitalStraightSegment::dilate (int radius) nu += 2 * radius; c -= radius; } + + +bool DigitalStraightSegment::contains (Pt2i p, int tol) const +{ + int pos = a * p.x () + b * p.y (); + tol *= period (); + if (pos < c - tol || pos >= c + nu + tol) return (false); + if (a < (b < 0 ? -b : b)) + return (p.x () >= min && p.x () <= max); + else + return (p.y () >= min && p.y () <= max); +} diff --git a/Code/FBSD/ImageTools/digitalstraightsegment.h b/Code/FBSD/ImageTools/digitalstraightsegment.h index 65964e0..fb681f5 100755 --- a/Code/FBSD/ImageTools/digitalstraightsegment.h +++ b/Code/FBSD/ImageTools/digitalstraightsegment.h @@ -93,6 +93,13 @@ public: */ void dilate (int radius); + /** + * \brief Inquires if given point belongs to the segment with given tolerence. + * @param p Tested point. + * @param tol Count of naive lines tolerated outside. + */ + bool contains (Pt2i p, int tol) const; + protected: diff --git a/Code/FBSD/main.cpp b/Code/FBSD/main.cpp index 48adc43..1afb875 100755 --- a/Code/FBSD/main.cpp +++ b/Code/FBSD/main.cpp @@ -1,18 +1,21 @@ #include <QApplication> #include <string> -#include <cmath> +#include <cmath> // DEV #include "bswindow.h" #include "bsrandomtester.h" -// #include "scanwindow.h" +// #include "scanwindow.h" // DEV int main (int argc, char *argv[]) { int val = 0; int imageName = 0; - bool random = false, testing = false, york = false; + bool random = false, testing = false; + bool york = false; // DEV + bool yt = false; // DEV QApplication app (argc, argv); +// DEV IN /* if (argc == 2 && string (argv[1]) == string ("scans")) { @@ -22,20 +25,28 @@ int main (int argc, char *argv[]) return app.exec (); } */ +// DEV OUT BSWindow window (&val); // val : necessary argument ! for (int i = 1; i < argc; i++) { if (string(argv[i]).at(0) == '-') { - if (string(argv[i]) == string ("-profile")) window.toggleProfWindow (); - // else if (string(argv[i]) == string ("-acc"))window.toggleAccuWindow (); - else if (string(argv[i]) == string ("-seg")) window.toggleSegWindow (); - else if (string(argv[i]) == string ("-idet")) window.toggleIdetWindow (); - // Test command : time ./Seg -test ../Images/couloir.jpg + if (string(argv[i]) == string ("-random")) random = true; else if (string(argv[i]) == string ("-test")) testing = true; - else if (string(argv[i]) == string ("-random")) random = true; +// DEV IN else if (string(argv[i]) == string ("-york")) york = true; + else if (string(argv[i]) == string ("-yt")) yt = true; + else if (string(argv[i]) == string ("-profile")) + window.toggleProfWindow (); + // else if (string(argv[i]) == string ("-acc")) + // window.toggleAccuWindow (); + else if (string(argv[i]) == string ("-seg")) + window.toggleSegWindow (); + else if (string(argv[i]) == string ("-idet")) + window.toggleIdetWindow (); + // Test command : time ./Seg -test ../Images/couloir.jpg +// DEV OUT else if (string(argv[i]) == string ("-sobel3x3")) window.useGradient (VMap::TYPE_SOBEL_3X3); else if (string(argv[i]) == string ("-sobel5x5")) @@ -52,6 +63,7 @@ int main (int argc, char *argv[]) window.useGradient (VMap::TYPE_FULL_BLACK_HAT); else if (string(argv[i]) == string ("-fullmorpho")) window.useGradient (VMap::TYPE_FULL_MORPHO); +// DEV IN else { int l = string (argv[i]).length (); @@ -64,6 +76,7 @@ int main (int argc, char *argv[]) else if (carac == 'i') window.toggleIdetWindow (); } } +// DEV OUT } else imageName = i; } @@ -74,7 +87,8 @@ int main (int argc, char *argv[]) delete tester; return (EXIT_SUCCESS); } - if (york) +// DEV IN + else if (york) { QImage im; im.load ("york.jpg"); @@ -90,7 +104,7 @@ int main (int argc, char *argv[]) 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.); + double covCL = yl.cannyLineCovering ("cannylines.txt", ncl, lcl, 0.); ofstream outf ("cmpcov.txt", ios::out); outf << covCL << " " << covFBSD << endl; outf.close (); @@ -114,10 +128,45 @@ int main (int argc, char *argv[]) outl.close (); return (EXIT_SUCCESS); } + else if (yt) + { + QImage im; + im.load ("york.jpg"); + int width = im.width (); + int height = im.height (); + int **tabImage = new int*[height]; + for (int i = 0; i < height; i++) + { + tabImage[i] = new int[width]; + for(int j = 0; j < width; j++) + { + QColor c = QColor (im.pixel (j, height - i - 1)); + tabImage[i][j] = c.value (); + } + } + BSDetectionWidget bsdw; + BSDetector detector; + clock_t start = clock (); + VMap *gMap = NULL; + for (int i = 0; i < 100; i++) + { + if (gMap != NULL) delete gMap; + gMap = new VMap (width, height, tabImage, VMap::TYPE_SOBEL_5X5); + detector.setGradientMap (gMap); + // buildGradientImage (0); + detector.detectAll (); + } + double diff = (clock () - start) / (double) CLOCKS_PER_SEC; + ofstream outf ("fbsdperf.txt", ios::out); + outf << diff << endl; + outf.close (); + return (EXIT_SUCCESS); + } +// DEV OUT else { if (imageName != 0) window.setFile (QString (argv[imageName])); - else window.setFile (QString ("../couloir.gif")); + else window.setFile (QString ("Images/couloir.gif")); if (testing) { window.runTest (); -- GitLab