diff --git a/Code/Seg/BSTools/bsdetectionwidget.cpp b/Code/Seg/BSTools/bsdetectionwidget.cpp index a80d399a72c557ee08b22fab92d0e432f6f38bf1..f3a4314ced71ba4ea14b18dbe5a78a04332a8747 100755 --- a/Code/Seg/BSTools/bsdetectionwidget.cpp +++ b/Code/Seg/BSTools/bsdetectionwidget.cpp @@ -8,6 +8,13 @@ using namespace std; +const int BSDetectionWidget::BACK_BLACK = 0; +const int BSDetectionWidget::BACK_WHITE = 1; +const int BSDetectionWidget::BACK_IMAGE = 2; +const int BSDetectionWidget::BACK_GRAD = 3; +const int BSDetectionWidget::BACK_GRADX = 4; +const int BSDetectionWidget::BACK_GRADY = 5; + const int BSDetectionWidget::DEFAULT_PEN_WIDTH = 1; @@ -32,7 +39,7 @@ BSDetectionWidget::BSDetectionWidget (QWidget *parent) alternate = 0; verbose = false; - paintItBlack = false; + background = BACK_IMAGE; exam = -1; selectionColor = Qt::red; @@ -64,11 +71,12 @@ QSize BSDetectionWidget::openImage (const QString &fileName, int type) if (gMap != NULL) delete gMap; gMap = new VMap (width, height, getBitmap (augmentedImage), type); detector.setGradientMap (gMap); + buildGradientImage (0); update (); if (idetview != NULL) idetview->setImage (&loadedImage, gMap); if (profileview != NULL) profileview->setImage (&loadedImage, gMap); - if (strucview != NULL) strucview->setGradientMap (gMap); + if (strucview != NULL) strucview->setGradientImage (&gradImage); return newSize; } @@ -93,6 +101,13 @@ int **BSDetectionWidget::getBitmap (const QImage &image) } +void BSDetectionWidget::toggleBackground () +{ + if (background++ == BACK_GRADY) background = BACK_BLACK; + if (background >= BACK_GRAD) buildGradientImage (background - BACK_GRAD); +} + + bool BSDetectionWidget::saveAugmentedImage (const QString &fileName, const char *fileFormat) { @@ -108,6 +123,39 @@ void BSDetectionWidget::clearImage () } +void BSDetectionWidget::buildGradientImage (int dir) +{ + int w = gMap->getWidth (); + int h = gMap->getHeight (); + double gn[w * h]; + for (int j = 0; j < h; j++) + for (int i = 0; i < w; i++) + { + if (dir == 2) + gn[j * w + i] = gMap->getValue(i,j).y (); + else if (dir == 1) + gn[j * w + i] = gMap->getValue(i,j).x (); + else + gn[j * w + i] = gMap->magn (i, j); + } + double min = gn[0]; + double max = gn[0]; + for (int i = 1; i < w * h; i++) + { + if (max < gn[i]) max = gn[i]; + if (min > gn[i]) min = gn[i]; + } + gradImage = QImage (w, h, QImage::Format_RGB32); + for (int j = 0; j < h; j++) + for (int i = 0; i < w; i++) + { + int val = (int) ((gn[(h - 1 - j) * w + i] - min) * 255 / (max - min)); + gradImage.setPixel (i, j, val + val * 256 + val * 256 * 256); + } + // gradImage.save ("hgradient.png"); +} + + void BSDetectionWidget::paintEvent (QPaintEvent *) { QPainter painter (this); @@ -186,7 +234,7 @@ void BSDetectionWidget::switchPixelAnalyzer () else { strucview = new BSStructureView (&loadedImage, &detector); - strucview->setGradientMap (gMap); + strucview->setGradientImage (&gradImage); strucview->show (); } } @@ -263,226 +311,305 @@ void BSDetectionWidget::keyPressEvent (QKeyEvent *event) { if (isActiveWindow ()) switch (event->key ()) { - case Qt::Key_U : - cerr << "p1 update: " << p1.x () << " " << p1.y () << endl; - cerr << "p2 update: " << p2.x () << " " << p2.y () << endl; - extract (); + case Qt::Key_A : + // Registers the last extracted blurred segment + saveExtractedSegment (); break; - case Qt::Key_A : - if (event->modifiers () & Qt::ShiftModifier) + case Qt::Key_B : + if (event->modifiers () & Qt::ControlModifier) { - bsBoundsVisible = ! bsBoundsVisible; - cout << "Segments bounds " - << (bsBoundsVisible ? "visible" : "hidden") << endl; + // Toggles background image + toggleBackground (); + if (p1.equals (p2)) displayBackground (); + else displayDetectionResult (true); } - else + break; + + case Qt::Key_C : + // Clears the registered blurred segments + clearSavedSegments (); + break; + + case Qt::Key_D : + if (event->modifiers () & Qt::ControlModifier) { - bsPointsVisible = ! bsPointsVisible; - cout << "Segments points " - << (bsPointsVisible ? "visible" : "hidden") << endl; + // Switches density test at initial step + detector.switchDensityTest (); + extract (); + cout << "Density test : " + << (detector.isSetDensityTest () ? "on" : "off") << endl; } break; - case Qt::Key_M : // Multi-selection switch - if (event->modifiers () & Qt::ShiftModifier) + case Qt::Key_E : + // Handles directed edge or stroke detection + if (event->modifiers () & Qt::ControlModifier) + detector.switchEdgeDirectionConstraint (); + else detector.invertEdgeDirection (); + switch (detector.edgeDirectionConstraint ()) { - detector.switchMultiSelection (); - cout << "Multi-selection " - << (detector.isMultiSelection () ? "on" : "off") << endl; + case 0 : + cout << "Stroke detection" << endl; + break; + case 1 : + cout << "Edge detection" << endl; + break; + case -1 : + cout << "Opposite edge detection" << endl; + break; } - else + extract (); + break; + + case Qt::Key_F : + if (event->modifiers () & Qt::ControlModifier) { - if (event->modifiers () & Qt::ControlModifier) - paintItBlack = ! paintItBlack; - extractAll (); + // Switches initial detection filtering + detector.switchFiltering (BSDetector::STEP_INITIAL); + cout << "Pre-filtering " + << (detector.isFiltering (BSDetector::STEP_INITIAL) ? "on" : "off") + << endl; + extract (); } break; - case Qt::Key_L : // Next multi-selected segment - if (! detector.getBlurredSegments().empty ()) + case Qt::Key_G : + // Tunes the gradient threshold for maximal value detection + detector.incGradientThreshold ( + (event->modifiers () & Qt::ShiftModifier ? -1 : 1)); + extract (); + cout << "Gradient threshold = " + << detector.getGradientThreshold () << endl; + break; + + case Qt::Key_H : + if (event->modifiers () & Qt::ControlModifier) { - displayNext (event->modifiers () & Qt::ShiftModifier ? -1 : 1); - cout << "Selection du segment " << exam << endl; + // Switches final detection filtering + detector.switchFiltering (BSDetector::STEP_FINAL); + cout << "Final filtering " + << (detector.isFiltering (BSDetector::STEP_FINAL) ? "on" : "off") + << endl; + extract (); } break; - case Qt::Key_Y : // Initial detection extension limitation - detector.switchInitialBounding (); - extract (); - cout << "Initial step max extension = " - << detector.initialDetectionMaxExtent () << endl; + case Qt::Key_K : + if (event->modifiers () & Qt::ControlModifier) + { + // Switches the final step connectivity constraint + detector.switchConnectivityConstraint (); + cout << "Connectivity constraint " + << (detector.isSetConnectivityConstraint () ? "on" : "off") + << endl; + extract (); + } break; - case Qt::Key_D : // Density test at initial step - detector.switchDensityTest (); + case Qt::Key_L : + // Tunes the output blurred segment minimal size + detector.setBSminSize (detector.getBSminSize () + + (event->modifiers () & Qt::ShiftModifier ? -1 : 1)); extract (); - cout << "Density test : " - << (detector.isSetDensityTest () ? "on" : "off") << endl; + cout << "Output BS min size = " << detector.getBSminSize () << endl; break; - case Qt::Key_W : // Fast tracks max width + case Qt::Key_M : if (event->modifiers () & Qt::ControlModifier) { - detector.switchScanRecentering (); - cout << "Fine tracking centered on " << (detector.isScanRecentering () ? - "detected segment" : "initial scan") << endl; - extract (); + // Switches the multi-detection + detector.switchMultiSelection (); + cout << "Multi-selection " + << (detector.isMultiSelection () ? "on" : "off") << endl; } else { - detector.setFineTracksMaxWidth (detector.fineTracksMaxWidth () + - (event->modifiers () & Qt::ShiftModifier ? -1 : 1)); - extract (); - cout << "Fine tracks max width = " - << detector.fineTracksMaxWidth () << endl; + // Runs an automatic detection + extractAll (); } break; - case Qt::Key_X : + case Qt::Key_N : if (event->modifiers () & Qt::ControlModifier) { - detector.switchScanFitting (); - cout << "Fine tracking fitted to " << (detector.isScanFitting () ? - "detected segment width" : "assigned width") << endl; + // Switches the initial detection extension limitation + detector.switchInitialBounding (); extract (); + cout << "Initial step max extension = " + << detector.initialDetectionMaxExtent () << endl; } else { - detector.setFastTracksMaxWidth (detector.fastTracksMaxWidth () + - (event->modifiers () & Qt::ShiftModifier ? -1 : 1)); + // Highlights the next segment in a multi-detection + if (! detector.getBlurredSegments().empty ()) + { + displayNext (event->modifiers () & Qt::ShiftModifier ? -1 : 1); + cout << "Selection du segment " << exam << endl; + } + } + break; + + case Qt::Key_O : + if (event->modifiers () & Qt::ControlModifier) + { + // Switches the scan directionality + detector.switchOrthoScans (); + cout << (detector.orthoScansOn () ? + "Orthographic scans" : "Directional scans") << endl; extract (); - cout << "Fast tracks max width = " - << detector.fastTracksMaxWidth () << endl; + } + else + { + // Outputs the detected segment + writeDetectionResult (); + cout << "Detection result output" << endl; } break; - case Qt::Key_K : // Output blurred segment min size - detector.setBSminSize (detector.getBSminSize () + - (event->modifiers () & Qt::ShiftModifier ? -1 : 1)); - extract (); - cout << "Output BS min size = " << detector.getBSminSize () << endl; + case Qt::Key_P : + if (event->modifiers () & Qt::ControlModifier) + { + // Switches the preliminary detection + detector.switchPreliminary (); + cout << "Preliminary detection " + << (detector.isPreliminary () ? "on" : "off") << endl; + extract (); + } + else + { + // Captures main window + augmentedImage.save ("capture.png"); + cout << "Main window shot in capture.png" << endl; + } break; - case Qt::Key_H : // Pixel lack tolerence - detector.setPixelLackTolerence (detector.getPixelLackTolerence () + - (event->modifiers () & Qt::ShiftModifier ? -1 : 1)); - extract (); - cout << "Lack tolerence = " << detector.getPixelLackTolerence () - << " pixels" << endl; + case Qt::Key_Q : + if (event->modifiers () & Qt::ControlModifier) + { + // Switches the scan flexibility + detector.switchDynamicScans (); + cout << (detector.dynamicScansOn () ? + "Dynamic scans" : "Static scans") << endl; + extract (); + } + else + { + // Displays registered blurred segments + displaySavedSegments (); + } break; - case Qt::Key_N : // Automatic detection grid resolution + case Qt::Key_R : + // Tunes the automatic detection grid resolution detector.setAutoGridResolution (detector.getAutoGridResolution () + (event->modifiers () & Qt::ShiftModifier ? -1 : 1)); cout << "Auto grid resolution = " << detector.getAutoGridResolution () << " pixels" << endl; break; - case Qt::Key_Q : - detector.switchAutoRestart (); - extract (); - cout << "Segment continuation after = " - << detector.getRestartOnLack () << " pixels" << endl; - break; - - case Qt::Key_T : - detector.toggleThinning (); - extract (); - cout << "Thinning " - << (detector.isThinningActivated () ? "on" : "off") << endl; - break; - case Qt::Key_S : - detector.switchDynamicScans (); - cout << (detector.dynamicScansOn () ? - "Dynamic scans" : "Static scans") << endl; - extract (); - break; - - case Qt::Key_O : - detector.switchOrthoScans (); - cout << (detector.orthoScansOn () ? - "Orthographic scans" : "Directional scans") << endl; - extract (); - break; - - case Qt::Key_F : - detector.switchFiltering (BSDetector::STEP_FINAL); - cout << "Final filtering " - << (detector.isFiltering (BSDetector::STEP_FINAL) ? "on" : "off") - << endl; - extract (); - break; - - case Qt::Key_P : if (event->modifiers () & Qt::ControlModifier) { - writeDetectionResult (); - cout << "Detection result output" << endl; - } - else if (event->modifiers () & Qt::ShiftModifier) - { - augmentedImage.save ("capture.png"); - cout << "Main window shot in capture.png" << endl; + // Switches the interruption handling + detector.switchAutoRestart (); + extract (); + cout << "Segment continuation after = " + << detector.getRestartOnLack () << " pixels" << endl; } else { - detector.switchFiltering (BSDetector::STEP_INITIAL); - cout << "Pre-filtering " - << (detector.isFiltering (BSDetector::STEP_INITIAL) ? "on" : "off") - << endl; + // Tunes the pixel lack tolerence value + detector.setPixelLackTolerence (detector.getPixelLackTolerence () + + (event->modifiers () & Qt::ShiftModifier ? -1 : 1)); extract (); + cout << "Lack tolerence = " << detector.getPixelLackTolerence () + << " pixels" << endl; } break; - case Qt::Key_G : - detector.switchConnectivityConstraint (); - cout << "Connectivity constraint " - << (detector.isSetConnectivityConstraint () ? "on" : "off") << endl; - extract (); + case Qt::Key_T : + if (event->modifiers () & Qt::ControlModifier) + { + // Switches the progressive thinning + detector.toggleThinning (); + extract (); + cout << "Thinning " + << (detector.isThinningActivated () ? "on" : "off") << endl; + } break; - case Qt::Key_C : + case Qt::Key_U : if (event->modifiers () & Qt::ControlModifier) - saveExtractedSegment (); + { + // Switches the display of the detected blurred segment bounds + bsBoundsVisible = ! bsBoundsVisible; + cout << "Segments bounds " + << (bsBoundsVisible ? "visible" : "hidden") << endl; + } + else + { + // Replays last extraction + cerr << "p1 update: " << p1.x () << " " << p1.y () << endl; + cerr << "p2 update: " << p2.x () << " " << p2.y () << endl; + extract (); + } break; case Qt::Key_V : if (event->modifiers () & Qt::ControlModifier) - displaySavedSegments (); - else switchVerbose (); + // Switches the detection result edition + switchVerbose (); break; - case Qt::Key_Z : + case Qt::Key_W : if (event->modifiers () & Qt::ControlModifier) - clearSavedSegments (); + { + // Switches the setting of the assigned width on the detected segment + detector.switchScanFitting (); + cout << "Fine tracking fitted to " << (detector.isScanFitting () ? + "detected segment width" : "assigned width") << endl; + extract (); + } + else + { + // Tunes the assigned max width for fine tracks + detector.setFastTracksMaxWidth (detector.fastTracksMaxWidth () + + (event->modifiers () & Qt::ShiftModifier ? -1 : 1)); + extract (); + cout << "Fast tracks max width = " + << detector.fastTracksMaxWidth () << endl; + } break; - case Qt::Key_E : - if (event->modifiers () & Qt::ShiftModifier) - detector.invertEdgeDirection (); - else detector.switchEdgeDirectionConstraint (); - switch (detector.edgeDirectionConstraint ()) + case Qt::Key_X : + if (event->modifiers () & Qt::ControlModifier) { - case 0 : - cout << "Stroke detection" << endl; - break; - case 1 : - cout << "Edge detection" << endl; - break; - case -1 : - cout << "Opposite edge detection" << endl; - break; + // Switches the scan centering on the detected segment + detector.switchScanRecentering (); + cout << "Fine tracking centered on " << (detector.isScanRecentering () ? + "detected segment" : "initial scan") << endl; + extract (); + } + else + { + // Tunes the assigned max width for fast tracks + detector.setFineTracksMaxWidth (detector.fineTracksMaxWidth () + + (event->modifiers () & Qt::ShiftModifier ? -1 : 1)); + extract (); + cout << "Fine tracks max width = " + << detector.fineTracksMaxWidth () << endl; } - extract (); break; - case Qt::Key_J : - detector.switchPreliminary (); - cout << "Preliminary detection " - << (detector.isPreliminary () ? "on" : "off") << endl; - extract (); + case Qt::Key_Y : + if (event->modifiers () & Qt::ControlModifier) + { + // Switches the display of the detected blurred segment pixels + bsPointsVisible = ! bsPointsVisible; + cout << "Segments points " + << (bsPointsVisible ? "visible" : "hidden") << endl; + } break; case Qt::Key_1 : @@ -607,9 +734,10 @@ void BSDetectionWidget::drawBlurredSegment (QPainter &painter, void BSDetectionWidget::displayBackground () { - augmentedImage = loadedImage; - QPainter painter (&augmentedImage); - update (QRect (QPoint (0, 0), QPoint (width, height))); + if (background == BACK_BLACK) augmentedImage.fill (qRgb (0, 0, 0)); + else if (background == BACK_WHITE) augmentedImage.fill (qRgb (255, 255, 255)); + else if (background == BACK_IMAGE) augmentedImage = loadedImage; + else augmentedImage = gradImage; } @@ -637,10 +765,11 @@ void BSDetectionWidget::writeDetectionResult () void BSDetectionWidget::displayDetectionResult (bool aux, int hnum) { - augmentedImage = loadedImage; + if (background == BACK_BLACK) augmentedImage.fill (qRgb (0, 0, 0)); + else if (background == BACK_WHITE) augmentedImage.fill (qRgb (255, 255, 255)); + else if (background == BACK_IMAGE) augmentedImage = loadedImage; + else augmentedImage = gradImage; QPainter painter (&augmentedImage); - if (paintItBlack) painter.fillRect (0, 0, width, height, QBrush (Qt::black)); - paintItBlack = false; vector<BlurredSegment *> bss = detector.getBlurredSegments (); if (! bss.empty ()) { @@ -692,7 +821,10 @@ void BSDetectionWidget::displayNext (int dir) void BSDetectionWidget::displaySavedSegments () { - augmentedImage = loadedImage; + if (background == BACK_BLACK) augmentedImage.fill (qRgb (0, 0, 0)); + else if (background == BACK_WHITE) augmentedImage.fill (qRgb (255, 255, 255)); + else if (background == BACK_IMAGE) augmentedImage = loadedImage; + else augmentedImage = gradImage; QPainter painter (&augmentedImage); if (! extractedSegments.empty ()) { diff --git a/Code/Seg/BSTools/bsdetectionwidget.h b/Code/Seg/BSTools/bsdetectionwidget.h index 942c32fe80b14f03462a3a13681445ef8c421e96..fd3d10d071c6d42bddbd8886d3a3e0a972a31554 100755 --- a/Code/Seg/BSTools/bsdetectionwidget.h +++ b/Code/Seg/BSTools/bsdetectionwidget.h @@ -56,11 +56,22 @@ public: const QStyleOptionGraphicsItem *option, QWidget *widget); */ + /** + * \brief Toggles the background image. + */ + void toggleBackground (); + /** * \brief Saves the augmented image with extraction results. */ bool saveAugmentedImage (const QString &fileName, const char *fileFormat); + /** + * \brief Builds ans stores the gradient image. + * @param dir : Gradient type (magnitude, x or y) + */ + void buildGradientImage (int dir); + /** * \brief Requires the accumulation window closure. */ @@ -159,6 +170,19 @@ protected: private: + /** Background status : uniform black. */ + static const int BACK_BLACK; + /** Background status : uniform white. */ + static const int BACK_WHITE; + /** Background status : intensity image displayed. */ + static const int BACK_IMAGE; + /** Background status : gradient image displayed. */ + static const int BACK_GRAD; + /** Background status : X-gradient image displayed. */ + static const int BACK_GRADX; + /** Background status : Y-gradient image displayed. */ + static const int BACK_GRADY; + /** Default value for pen width. */ static const int DEFAULT_PEN_WIDTH; @@ -186,13 +210,16 @@ private: QColor boundHighColor; /** Flag indicating whether blurred segments bounds are visible. */ bool bsBoundsVisible; - /** Flag indicating whether no background should be displayed. */ - bool paintItBlack; + /** Background type. + * Values : BACK_NO, BACK_IMAGE, BACK_GRAD, BACK_GRADX, BACK_GRADY. */ + int background; /** Flag indicating whether detection result should be output. */ bool verbose; /** Presently loaded image. */ QImage loadedImage; + /** Computed gradient image. */ + QImage gradImage; /** Present image augmented with processed data. */ QImage augmentedImage; /** Gradient map of the loaded picture. */ diff --git a/Code/Seg/BSTools/bsidetitem.cpp b/Code/Seg/BSTools/bsidetitem.cpp index efcf48df845236d5c4fea5f4faf4374bec7a027f..81ebea831b1b9c17b8464fcb4a727fe53b9316db 100755 --- a/Code/Seg/BSTools/bsidetitem.cpp +++ b/Code/Seg/BSTools/bsidetitem.cpp @@ -212,22 +212,47 @@ if (pt1.equals (pt2)) return; while (it != pts.end ()) { Pt2i pt = ds->locate (*it); + +/* +cout << "CC PT (" << pt.x () << ", " << pt.y () << ")" << endl; + if (pt.y () < 0) cout << "Y NEGATIF" << endl; + if (pt.x () <= 0) + { + if (-pt.x () >= (int) (leftscan.size ())) cout << "DEP LEFT" << endl; + else + { + if ((int) (leftscan.at(-pt.x ()).size ()) <= pt.y ()) + cout << "Y TOO FAR" << endl; + else + { + Pt2i pini = leftscan.at(-pt.x ()).at(pt.y ()); + if (it->x () != pini.x () || it->y () != pini.y ()) + cout << "IT (" << it->x () << ", " << it->y () << ") -> (" + << pini.x () << ", " << pini.y () << ")" << endl; + } + } + } + else + { + if (pt.x () - 1 >= (int) (rightscan.size ())) + cout << "DEP RIGHT" << endl; + else + { + if ((int) (rightscan.at(pt.x ()-1).size ()) <= pt.y ()) + cout << "Y TOO FAR" << endl; + else + { + Pt2i pini = rightscan.at(pt.x () - 1).at(pt.y ()); + if (it->x () != pini.x () || it->y () != pini.y ()) + cout << "IT (" << it->x () << ", " << it->y () << ") -> (" + << pini.x () << ", " << pini.y () << ")" << endl; + } + } + } +*/ + int posx = cpos + resol * pt.x (); int posy = lowpos - resol * pt.y (); -if (pt.x () <= 0) -{ -Pt2i pini = leftscan.at(-pt.x ()).at(pt.y ()); -if (it->x () != pini.x () || it->y () != pini.y ()) -cout << "IT (" << it->x () << ", " << it->y () << ") -> (" -<< pini.x () << ", " << pini.y () << ")" << endl; -} -else -{ -Pt2i pini = rightscan.at(pt.x () - 1).at(pt.y ()); -if (it->x () != pini.x () || it->y () != pini.y ()) -cout << "IT (" << it->x () << ", " << it->y () << ") -> (" -<< pini.x () << ", " << pini.y () << ")" << endl; -} painter->fillRect (posx, posy, resol, resol, QBrush (Qt::blue)); it++; } diff --git a/Code/Seg/BSTools/bsstructureview.cpp b/Code/Seg/BSTools/bsstructureview.cpp index 443a1789a6bcfdf7ae21a35eb9f4653904ada23b..b0d33f1e27f6a6b0fbe1bcd015ac87a5ac179c65 100755 --- a/Code/Seg/BSTools/bsstructureview.cpp +++ b/Code/Seg/BSTools/bsstructureview.cpp @@ -15,7 +15,6 @@ BSStructureView::BSStructureView (QImage *im, BSDetector *sd) int h = im->height (); imageInBack = true; gradDir = 0; - gMap = NULL; gradImage = NULL; gradInBack = false; setBackgroundBrush (QBrush (*currentImage)); @@ -30,48 +29,12 @@ BSStructureView::~BSStructureView () { scene()->removeItem (grid); delete grid; - delete gradImage; } -void BSStructureView::setGradientMap (VMap *gmap) +void BSStructureView::setGradientImage (QImage *gim) { - this->gMap = gmap; -} - - -void BSStructureView::updateGradientImage () -{ - if (gMap == NULL) return; - if (gradImage != NULL) delete gradImage; - int w = gMap->getWidth (); - int h = gMap->getHeight (); - double gn[w * h]; - for (int j = 0; j < h; j++) - for (int i = 0; i < w; i++) - { - if (gradDir == 2) - gn[j * w + i] = gMap->getValue(i,j).y (); - else if (gradDir == 1) - gn[j * w + i] = gMap->getValue(i,j).x (); - else - gn[j * w + i] = gMap->magn (i, j); - } - double min = gn[0]; - double max = gn[0]; - for (int i = 1; i < w * h; i++) - { - if (max < gn[i]) max = gn[i]; - if (min > gn[i]) min = gn[i]; - } - gradImage = new QImage (w, h, QImage::Format_RGB32); - for (int j = 0; j < h; j++) - for (int i = 0; i < w; i++) - { - int val = (int) ((gn[(h - 1 - j) * w + i] - min) * 255 / (max - min)); - gradImage->setPixel (i, j, val + val * 256 + val * 256 * 256); - } - // gradImage->save ("hgradient.png"); + gradImage = gim; } @@ -103,11 +66,7 @@ void BSStructureView::toggleBackground () void BSStructureView::toggleGradient () { if (currentImage == gradImage) currentImage = graylevelImage; - else - { - if (gradImage == NULL) updateGradientImage (); - currentImage = gradImage; - } + else currentImage = gradImage; setWindowTitle (grid->itemTitle () + backgroundSource ()); } @@ -115,11 +74,7 @@ void BSStructureView::toggleGradient () void BSStructureView::toggleGradientType () { if (++gradDir == 3) gradDir = 0; - if (currentImage == gradImage) - { - updateGradientImage (); - currentImage = gradImage; - } + if (currentImage == gradImage) currentImage = gradImage; setWindowTitle (grid->itemTitle () + backgroundSource ()); } diff --git a/Code/Seg/BSTools/bsstructureview.h b/Code/Seg/BSTools/bsstructureview.h index 81ea5a9b40165d390e667b9eeee45e987fc92a23..ea5aa7108597eb7a1df5c3a22c56736c26d34911 100755 --- a/Code/Seg/BSTools/bsstructureview.h +++ b/Code/Seg/BSTools/bsstructureview.h @@ -22,10 +22,10 @@ public: ~BSStructureView (); /** - * Sets the reference to the used gradient map. - * @param gMap Reference to the used gradient map. + * Sets the reference to the gradient image. + * @param gim Reference to the used gradient image. */ - void setGradientMap (VMap *gMap); + void setGradientImage (QImage *gim); /** * Sets the examined segment from a multi-selection. @@ -60,8 +60,6 @@ private: bool imageInBack; /** Pointer to the currently displayed image. */ QImage *currentImage; - /** Reference to the used gradient map. */ - VMap *gMap; /** Pointer to the gradient image. */ QImage *gradImage; /** Type of gradient image displayed (magnitude, horizontal or vertical). */ @@ -80,11 +78,6 @@ private: */ QString backgroundSource () const; - /** - * Updates the gradient image according to gradient type displayed. - */ - void updateGradientImage (); - /** * Toggles the window background between the current image or plain white. */ diff --git a/Code/Seg/BlurredSegment/bsdetector.h b/Code/Seg/BlurredSegment/bsdetector.h index bbdc5e515dadced5bb8692cb3c67f94f1f6c0825..a3ab53acd58c9154c6218be7aa862e6ee38d8019 100755 --- a/Code/Seg/BlurredSegment/bsdetector.h +++ b/Code/Seg/BlurredSegment/bsdetector.h @@ -162,6 +162,19 @@ public: inline void setBSminSize (int value) { if (value >= ABSOLUTE_BS_MIN_SIZE) bsMinSize = value; } + /** + * \brief Returns the threshold used for maximal gradient detection. + */ + inline int getGradientThreshold () const { + return (gMap->getGradientThreshold ()); } + + /** + * \brief Increments the threshold used for maximal gradient detection. + * @param inc Increment value. + */ + inline void incGradientThreshold (int inc) { + return (gMap->incGradientThreshold (inc)); } + /** * \brief Returns the automatic detection grid resolution. */ diff --git a/Code/Seg/DirectionalScanner/directionalscanner.cpp b/Code/Seg/DirectionalScanner/directionalscanner.cpp index b936b169b7f21533429150c43309fb0ebf129146..eaf6668e6c4ac7b50a6876f7ce741e79949de103 100755 --- a/Code/Seg/DirectionalScanner/directionalscanner.cpp +++ b/Code/Seg/DirectionalScanner/directionalscanner.cpp @@ -20,5 +20,5 @@ void DirectionalScanner::bindTo (int a, int b, int c) Pt2i DirectionalScanner::locate (const Pt2i & pt) const { - return (Pt2i (0, 0)); + return (Pt2i (pt)); } diff --git a/Code/Seg/ImageTools/vmap.cpp b/Code/Seg/ImageTools/vmap.cpp index b2839d61377028094017c3a4b7161d41e3ee06ba..c2597b78a27a09f9598c0ff01f4f6fd8a7011799 100755 --- a/Code/Seg/ImageTools/vmap.cpp +++ b/Code/Seg/ImageTools/vmap.cpp @@ -21,6 +21,7 @@ const int VMap::DEFAULT_GRADIENT_THRESHOLD = 30; VMap::VMap (int width, int height, int *data, int type) { + gradientThreshold = DEFAULT_GRADIENT_THRESHOLD; this->width = width; this->height = height; imap = new int[width * height]; @@ -120,6 +121,7 @@ VMap::VMap (int width, int height, int *data, int type) VMap::VMap (int width, int height, int **data, int type) { + gradientThreshold = DEFAULT_GRADIENT_THRESHOLD; this->width = width; this->height = height; imap = new int[width * height]; @@ -179,7 +181,6 @@ VMap::VMap (int width, int height, int **data, int type) } else if (type == TYPE_FULL_MORPHO) { -cout << "FULL MORPHO" << endl; Strucel se (Strucel::TYPE_PLUS_3X3); se.morphoGradient (imap, data, width, height); int *jmap = new int[width * height]; @@ -442,7 +443,7 @@ int VMap::largestIn (const vector<Pt2i> &pix) const int imax = -1; vector<Pt2i>::const_iterator pt = pix.begin (); int gmax = imap[pt->y() * width + pt->x()]; - if (gmax < DEFAULT_GRADIENT_THRESHOLD) gmax = DEFAULT_GRADIENT_THRESHOLD; + if (gmax < gradientThreshold) gmax = gradientThreshold; int i = 0; while (pt != pix.end ()) diff --git a/Code/Seg/ImageTools/vmap.h b/Code/Seg/ImageTools/vmap.h index 6d9e72415960be67e9c1595bb608e90ddd76169e..d7c277bdc6ab5b205a9b600bbf2ffde38d806380 100755 --- a/Code/Seg/ImageTools/vmap.h +++ b/Code/Seg/ImageTools/vmap.h @@ -188,6 +188,20 @@ public: */ int localMax (int *lmax, const vector<Pt2i> &pix, const Vr2i &gref) const; + /** + * \brief Returns the gradient threshold value used for maxima detection. + */ + inline int getGradientThreshold () const { return (gradientThreshold); } + + /** + * \brief Returns the gradient threshold value used for maxima detection. + */ + inline void incGradientThreshold (int inc) { + gradientThreshold += inc; + if (gradientThreshold < 0) gradientThreshold = 0; + if (gradientThreshold > 255) gradientThreshold = 255; + } + /** * \brief Switches the direction constraint for local maxima selection. */ @@ -253,6 +267,8 @@ private: bool *mask; /** Flag indicating whether the occupancy mask is in use. */ bool masking; + /** Gradient threshold for highest value detection. */ + int gradientThreshold; /** Direction constraint for local gradient maxima. */ bool orientedGradient; /** Registred direction constraint for local gradient maxima. */ diff --git a/Methode/ctrl.tex b/Methode/ctrl.tex index a19ebc13bf2816507aeb416bb7eb02c344c747f9..f15f4e79c6030ca31ecc6641393ca4ee8a02a42a 100755 --- a/Methode/ctrl.tex +++ b/Methode/ctrl.tex @@ -23,37 +23,38 @@ \begin{tabular}{|rcl|} \hline \multicolumn{3}{|l|}{Contr\^ole de l'extraction :} \\ -u & \spa & Actualiser \\ -v && Afficher le r\'esultat \\ -a && Commute l'affichage des points des segments flous. \\ -A && Commute l'affichage des bords des segments flous. \\ -w && Consigne d'\'epaisseur du segment flou pour le suivi fin \\ -x && Consigne d'\'epaisseur du segment flou pour le suivi rapide \\ -h && Longueur tol\'er\'ee pour les sauts de d\'etection \\ -k && Taille minimale des segments d\'etect\'es \\ -n && R\'esolution de la grille de d\'etection automatique \\ -e && Trait / bord \\ -E && Autre bord \\ -q && Retour d'absence (1 / longueur absence) \\ -Ctrl-c/v/z && Enregistre / Affiche / Supprime les segments \\ -M && Commute la multi-d\'etection \\ +a/q/c &\spa & Enregistre / Affiche / Supprime les segments \\ +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 \\ +l && Ajuste la taille minimale du segment final \\ m && D\'etection exhaustive de tous les segments \\ -Ctrl-m && D\'etection exhaustive de tous les segments sur fond noir \\ -l && Examine le segment suivant dans une multi-d\'etection \\ -j && Commute la d\'etection pr\'eliminaire \\ -t && Commute l'amincissement progressif \\ -y && Commute le bridage de la premi\`ere \'etape \\ -d && Commute le test de densit\'e \\ -p && Commute le pr\'e-filtrage \\ -f && Commute le filtrage final \\ -g && Commute la contrainte de connectivit\'e \\ -s && Commute l'aspect dynamique des scans \\ -o && Commute l'aspect directionel des scans \\ -Ctrl-w && Commute le recentrage du scan sur le segment d\'etect\'e \\ -Ctrl-x && Commute l'ajustement de la consigne d'\'epaisseur sur le segment -d\'etect\'e \\ -P && Capture la fen\^etre principale \\ -Ctrl-p && Edite la derni\`ere d\'etection dans un fichier seg.txt \\ +n && Allume le segment suivant dans une d\'etection multiple \\ +o && Edite le segment d\'etect\'e (seg.txt) \\ +p && Capture la fen\^etre principale \\ +r && Ajuste la r\'esolution de la grille de d\'etection automatique \\ +s && Ajuste la longueur tol\'er\'ee pour les sauts de d\'etection \\ +u && Relance la d\'etection sur la derni\`ere s\'election (update) \\ +w && Ajuste la consigne d'\'epaisseur du segment flou pour le suivi fin \\ +x && Ajuste la consigne d'\'epaisseur du segment flou pour le suivi rapide \\ +Ctrl-b && Commute le fond d'\'ecran de la fen\^etre principale. \\ +Ctrl-d && Commute le test de densit\'e \\ +Ctrl-e && Commute la prise en compte de la direction du bord (trait / contour) \\ +Ctrl-f && Commute le pr\'e-filtrage (segment initial) \\ +Ctrl-h && Commute le filtrage du segment final \\ +Ctrl-k && Commute la contrainte de konnectivit\'e \\ +Ctrl-m && Commute la d\'etection multiple \\ +Ctrl-n && Commute la limitation de l'extension de la d\'etection initiale \\ +Ctrl-o && Commute la directionnalit\'e des scans \\ +Ctrl-p && Commute la d\'etection pr\'eliminaire \\ +Ctrl-q && Commute le contr\^ole dynamique des scans \\ +Ctrl-s && Commute la gestion des reprises sur interruption (1 / longueur absence) \\ +Ctrl-t && Commute l'amincissement progressif \\ +Ctrl-u && Commute l'affichage des bords des segments flous. \\ +Ctrl-v && Commute l'affichage du r\'esultat de la d\'etection en console (verbose) \\ +Ctrl-w && Commute l'ajustement de la consigne d'\'epaisseur sur le segment \\ +Ctrl-x && Commute le recentrage du scan sur le segment d\'etect\'e \\ +Ctrl-y && Commute l'affichage des pixels des segments flous. \\ 1 && Commute la visu des segments (pixels) \\ 2 && Commute la visu de l'accumulateur \\ 3 && Commute la visu des profils \\