Skip to content
Snippets Groups Projects
bsdetector.cpp 20.3 KiB
Newer Older
even's avatar
even committed
#include "bsdetector.h"
even's avatar
even committed
//#include "linespacefilter.h"
even's avatar
even committed


even's avatar
even committed
const std::string BSDetector::VERSION = "0.2.2";
even's avatar
even committed
const int BSDetector::STEP_FINAL = 0;
const int BSDetector::STEP_INITIAL = 1;
const int BSDetector::STEP_PRELIM = 2;

even's avatar
even committed
const int BSDetector::RESULT_VOID = -2;
even's avatar
even committed
const int BSDetector::RESULT_UNDETERMINED = -1;
const int BSDetector::RESULT_OK = 0;
even's avatar
even committed
const int BSDetector::RESULT_PRELIM_NO_DETECTION = 1;
const int BSDetector::RESULT_PRELIM_TOO_FEW = 2;
even's avatar
even committed
const int BSDetector::RESULT_INITIAL_NO_DETECTION = 11;
const int BSDetector::RESULT_INITIAL_TOO_FEW = 12;
const int BSDetector::RESULT_INITIAL_TOO_SPARSE = 13;
const int BSDetector::RESULT_INITIAL_TOO_MANY_OUTLIERS = 14;
even's avatar
even committed
const int BSDetector::RESULT_INITIAL_CLOSE_ORIENTATION = 15;
even's avatar
even committed
const int BSDetector::RESULT_FINAL_NO_DETECTION = 21;
const int BSDetector::RESULT_FINAL_TOO_FEW = 22;
const int BSDetector::RESULT_FINAL_TOO_SPARSE = 23;
even's avatar
even committed
const int BSDetector::RESULT_FINAL_TOO_SMALL = 24;
const int BSDetector::RESULT_FINAL_TOO_FRAGMENTED = 25;
const int BSDetector::RESULT_FINAL_TOO_MANY_OUTLIERS = 26;
even's avatar
even committed

const int BSDetector::DEFAULT_FAST_TRACK_SCAN_WIDTH = 16;
even's avatar
even committed
const int BSDetector::DEFAULT_ASSIGNED_THICKNESS = 3;
const int BSDetector::FAST_TRACK_MARGIN = 2;
const int BSDetector::BS_MIN_SIZE = 3;
const int BSDetector::DEFAULT_INITIAL_MIN_SIZE = 5;
even's avatar
even committed
const int BSDetector::DEFAULT_FINAL_MIN_SIZE = 10;
const int BSDetector::DEFAULT_FRAGMENT_MIN_SIZE = 5;
even's avatar
even committed
const int BSDetector::DEFAULT_AUTO_SWEEPING_STEP = 15;
even's avatar
even committed
const int BSDetector::PRELIM_MIN_HALF_WIDTH = 10;
even's avatar
even committed


BSDetector::BSDetector ()
{
  gMap = NULL;
even's avatar
even committed
  inThick = DEFAULT_ASSIGNED_THICKNESS;
even's avatar
even committed
  prelimDetectionOn = false;
  staticDetOn = false;
even's avatar
even committed
  singleMultiOn = true;
even's avatar
even committed
  bst0 = (prelimDetectionOn ? new BSTracker () : NULL);
even's avatar
even committed
  bst1 = new BSTracker ();
even's avatar
even committed
  // bst1->setPixelLackTolerence (bst1->getVicinityThreshold ());
even's avatar
even committed
  bst2 = new BSTracker ();
  bstStatic = NULL;
  if (staticDetOn)
  {
    bstStatic = new BSTracker ();
    if (bstStatic->dynamicScansOn ()) bstStatic->toggleDynamicScans ();
    if (bstStatic->isAssignedThicknessControlOn ())
      bstStatic->toggleAssignedThicknessControl ();
  }
even's avatar
even committed

  prefilteringOn = false;
even's avatar
even committed
  //lsf1 = (prefilteringOn ? new LineSpaceFilter () : NULL);
  lsf1 = (prefilteringOn ? new BSFilter () : NULL);
even's avatar
even committed
  filteringOn = false;
even's avatar
even committed
  //lsf2 = (filteringOn ? new LineSpaceFilter () : NULL);
  lsf2 = (filteringOn ? new BSFilter () : NULL);
even's avatar
even committed

even's avatar
even committed
  oppositeGradientDir = false;   // main edge detection
  initialMinSize = DEFAULT_INITIAL_MIN_SIZE;
  finalFragmentationTestOn = false;
  fragmentMinSize = DEFAULT_FRAGMENT_MIN_SIZE;
even's avatar
even committed
  recenteringOn = true;
  initialSparsityTestOn = true;
even's avatar
even committed
  finalSizeTestOn = true;
  finalMinSize = DEFAULT_FINAL_MIN_SIZE;
  finalSparsityTestOn = false;
even's avatar
even committed
  // nbSmallBS = 0;
even's avatar
even committed
  multiSelection = false;
even's avatar
even committed
  autodet = false;
even's avatar
even committed
  autoSweepingStep = DEFAULT_AUTO_SWEEPING_STEP;
  maxtrials = 0;
even's avatar
even committed
  nbtrials = 0;
even's avatar
even committed

even's avatar
even committed
  bspre = NULL;
even's avatar
even committed
  bsini = NULL;
  bsf = NULL;
  resultValue = RESULT_UNDETERMINED;
}


BSDetector::~BSDetector ()
{
even's avatar
even committed
  if (prelimDetectionOn) delete bst0;
  if (staticDetOn) delete bstStatic;
even's avatar
even committed
  delete bst1;
  delete bst2;
  if (lsf1 != NULL) delete lsf1;
  if (lsf2 != NULL) delete lsf2;
even's avatar
even committed
  if (bsini != NULL) delete bsini;
  if (bsf != NULL) delete bsf;
even's avatar
even committed
  vector <BlurredSegment *>::iterator it = mbsf.begin ();
even's avatar
even committed
  while (it != mbsf.end ()) delete (*it++);
even's avatar
even committed
}


void BSDetector::setGradientMap (VMap *data)
{
  gMap = data;
even's avatar
even committed
  if (prelimDetectionOn) bst0->setGradientMap (data);
  if (staticDetOn) bstStatic->setGradientMap (data);
  if (bst1) bst1->setGradientMap (data);
  if (bst2) bst2->setGradientMap (data);
  if (bstStatic) bstStatic->setGradientMap (data);
even's avatar
even committed
}


void BSDetector::detectAll ()
{
even's avatar
even committed
  autodet = true;
even's avatar
even committed
  freeMultiSelection ();
even's avatar
even committed
  gMap->setMasking (true);
  gMap->clearMask ();
even's avatar
even committed

even's avatar
even committed
  bool isnext = true;
  nbtrials = 0;
even's avatar
even committed
  // nbSmallBS = 0;
even's avatar
even committed
  int width = gMap->getWidth ();
  int height = gMap->getHeight ();
even's avatar
even committed
  for (int x = width / 2; isnext && x > 0; x -= autoSweepingStep)
even's avatar
even committed
    isnext = runMultiDetection (Pt2i (x, 0), Pt2i (x, height - 1));
  for (int x = width / 2 + autoSweepingStep;
       isnext && x < width - 1; x += autoSweepingStep)
even's avatar
even committed
    isnext = runMultiDetection (Pt2i (x, 0), Pt2i (x, height - 1));
even's avatar
even committed
  for (int y = height / 2; isnext && y > 0; y -= autoSweepingStep)
even's avatar
even committed
    isnext = runMultiDetection (Pt2i (0, y), Pt2i (width - 1, y));
  for (int y = height / 2 + autoSweepingStep;
       isnext && y < height - 1; y += autoSweepingStep)
even's avatar
even committed
    isnext = runMultiDetection (Pt2i (0, y), Pt2i (width - 1, y));
  if (maxtrials > (int) (mbsf.size ())) maxtrials = 0;
even's avatar
even committed
  // cout << nbSmallBS << " petits BS elimines" << endl;
even's avatar
even committed

  gMap->setMasking (false);
}


even's avatar
even committed
void BSDetector::detectAllWithBalancedXY ()
{
  autodet = true;
  freeMultiSelection ();
  gMap->setMasking (true);
  gMap->clearMask ();
even's avatar
even committed

  bool isnext = true;
  nbtrials = 0;
even's avatar
even committed
  // nbSmallBS = 0;
even's avatar
even committed
  int width = gMap->getWidth ();
  int height = gMap->getHeight ();
  int xg = width / 2, yb = height / 2;
even's avatar
even committed
  int xd = xg + autoSweepingStep, yh = yb + autoSweepingStep;
even's avatar
even committed
  bool agauche = true, enbas = true, adroite = true, enhaut = true;
  while (isnext && (agauche || enbas || adroite || enhaut))
  {
    if (agauche)
    {
      isnext = runMultiDetection (Pt2i (xg, 0), Pt2i (xg, height - 1));
even's avatar
even committed
      xg -= autoSweepingStep;
even's avatar
even committed
      if (xg <= 0) agauche = false;
    }
    if (isnext && enbas)
    {
      isnext = runMultiDetection (Pt2i (0, yb), Pt2i (width - 1, yb));
even's avatar
even committed
      yb -= autoSweepingStep;
even's avatar
even committed
      if (yb <= 0) enbas = false;
    }
    if (isnext && adroite)
    {
      isnext = runMultiDetection (Pt2i (xd, 0), Pt2i (xd, height - 1));
even's avatar
even committed
      xd += autoSweepingStep;
even's avatar
even committed
      if (xd >= width - 1) adroite = false;
    }
    if (isnext && enhaut)
    {
      isnext = runMultiDetection (Pt2i (0, yh), Pt2i (width - 1, yh));
even's avatar
even committed
      yh += autoSweepingStep;
even's avatar
even committed
      if (yh >= height - 1) enhaut = false;
    }
  }
  if (maxtrials > (int) (mbsf.size ())) maxtrials = 0;
even's avatar
even committed
  // cout << nbSmallBS << " petits BS elimines" << endl;
even's avatar
even committed
  gMap->setMasking (false);
}


even's avatar
even committed
void BSDetector::detectSelection (const Pt2i &p1, const Pt2i &p2)
{
even's avatar
even committed
  autodet = false;
even's avatar
even committed
  freeMultiSelection ();
  if (multiSelection)
  {
    gMap->setMasking (true);
    gMap->clearMask ();
even's avatar
even committed
    nbtrials = 0;
even's avatar
even committed
    // nbSmallBS = 0;
even's avatar
even committed
    runMultiDetection (p1, p2);
even's avatar
even committed
    // cout << nbSmallBS << " petits BS elimines" << endl;
    if (maxtrials > (int) (mbsf.size ())) maxtrials = 0;
even's avatar
even committed
    gMap->setMasking (false);
  }
even's avatar
even committed
  else
even's avatar
even committed
    if (staticDetOn) resultValue = staticDetect (p1, p2);
even's avatar
even committed
    else resultValue = detect (p1, p2);
even's avatar
even committed
void BSDetector::redetect ()
{
  if (autodet) detectAll ();
  else detectSelection (inip1, inip2);
}


even's avatar
even committed
void BSDetector::freeMultiSelection ()
even's avatar
even committed
{
even's avatar
even committed
  vector<BlurredSegment *>::iterator it = mbsf.begin ();
even's avatar
even committed
  while (it != mbsf.end ()) delete (*it++);
  mbsf.clear ();
}


even's avatar
even committed
bool BSDetector::runMultiDetection (const Pt2i &p1, const Pt2i &p2)
even's avatar
even committed
{
  vector<Pt2i> pts;
  p1.draw (pts, p2);
  int locmax[pts.size ()];
even's avatar
even committed
  int nlm = gMap->localMax (locmax, pts);
  bool isnext = true;
  for (int i = 0; isnext && i < nlm; i++)
even's avatar
even committed
  {
even's avatar
even committed
    Pt2i ptstart = pts.at (locmax[i]);
    if (gMap->isFree (ptstart))
even's avatar
even committed
    {
even's avatar
even committed
      bool savedOppDir = oppositeGradientDir;
      oppositeGradientDir = false;
      int nbDets = (gMap->isOrientationConstraintOn () ? 2 : 1);
      if (singleMultiOn) nbDets = 1;
      while (isnext && nbDets != 0)
even's avatar
even committed
        int res = RESULT_VOID;
even's avatar
even committed
        if (staticDetOn) res = staticDetect (p1, p2, true, ptstart);
even's avatar
even committed
        else res = detect (p1, p2, true, ptstart);
        if (res == RESULT_OK)
        {
          gMap->setMask (bsf->getAllPoints ());
          mbsf.push_back (bsf);
          bsf = NULL; // to avoid BS deletion
          if ((int) (mbsf.size ()) == maxtrials) isnext = false;
even's avatar
even committed
        oppositeGradientDir = ! oppositeGradientDir;
        nbDets --;
        nbtrials ++;
even's avatar
even committed
      oppositeGradientDir = savedOppDir;
even's avatar
even committed
    }
  }
even's avatar
even committed
  return (isnext);
even's avatar
even committed
}


even's avatar
even committed
int BSDetector::detect (const Pt2i &p1, const Pt2i &p2,
                        bool centralp, const Pt2i &pc)
even's avatar
even committed
{
even's avatar
even committed
  // Entry check
  //------------
  if (p1.equals (p2)
even's avatar
even committed
      || ((! centralp) && p1.chessboard (p2) < BSTracker::MIN_SCAN))
    return RESULT_VOID;
even's avatar
even committed

even's avatar
even committed
  // Clearance
  //----------
even's avatar
even committed
  if (prelimDetectionOn) bst0->clear ();
even's avatar
even committed
  bst1->clear ();
  bst2->clear ();
even's avatar
even committed
  if (prefilteringOn) lsf1->clear ();
  if (filteringOn) lsf2->clear ();
  if (bspre != NULL) delete bspre;
  bspre = NULL;
even's avatar
even committed
  if (bsini != NULL) delete bsini;
  bsini = NULL;
  if (bsf != NULL) delete bsf;
  bsf = NULL;

even's avatar
even committed
  prep1.set (p1);
  prep2.set (p2);
  prewidth = (centralp ? DEFAULT_FAST_TRACK_SCAN_WIDTH : 0);
  prepc.set (pc);

  // Preliminary based on highest gradient without orientation constraint
  //---------------------------------------------------------------------
  if (prelimDetectionOn)
  {
    bspre = bst0->fastTrack (inThick + FAST_TRACK_MARGIN,
even's avatar
even committed
                             prep1, prep2, prewidth, prepc);
    if (bspre == NULL || bspre->size () < initialMinSize)
even's avatar
even committed
      return (bspre == NULL ? RESULT_PRELIM_NO_DETECTION
                            : RESULT_PRELIM_TOO_FEW);

    Vr2i v0 = bspre->getSupportVector ();
    int l = v0.chessboard ();
    if (l != 0)
    {
      Pt2i pcentral = bspre->getSegment()->centerOfIntersection (prep1, prep2);
      int detw = 2 * (1 + bspre->minimalWidth().floor ());
      if (detw < PRELIM_MIN_HALF_WIDTH) detw = PRELIM_MIN_HALF_WIDTH;
      int dx = (int) ((v0.y () * detw) / l);
      int dy = (int) (- (v0.x () * detw) / l);
      inip1 = Pt2i (pcentral.x () + dx, pcentral.y () + dy);
      inip2 = Pt2i (pcentral.x () - dx, pcentral.y () - dy);
      iniwidth = 0;
    }
  }
  else
  {
    inip1.set (p1);
    inip2.set (p2);
    iniwidth = (centralp ? DEFAULT_FAST_TRACK_SCAN_WIDTH : 0);
    inipc.set (pc);
  }
even's avatar
even committed

  // Initial detection based on highest gradient without orientation constraint
  //---------------------------------------------------------------------------
  bsini = bst1->fastTrack (inThick + FAST_TRACK_MARGIN,
even's avatar
even committed
                           inip1, inip2, iniwidth, inipc);
  if (bsini == NULL || bsini->size () < initialMinSize)
even's avatar
even committed
    return (bsini == NULL ? RESULT_INITIAL_NO_DETECTION
                          : RESULT_INITIAL_TOO_FEW);
even's avatar
even committed

  // Sparsity test
even's avatar
even committed
  //-------------
  if (initialSparsityTestOn)
even's avatar
even committed
  {
    DigitalStraightLine mydsl (inip1, inip2, DigitalStraightLine::DSL_NAIVE);
    int mydrlf = mydsl.manhattan (bsini->getLastRight ())
                 - mydsl.manhattan (bsini->getLastLeft ());
    if (mydrlf < 0) mydrlf = -mydrlf; // Case of horizontal P1P2
    int expansion = 1 + mydrlf;
    if (bsini->size () < expansion / 2)
even's avatar
even committed
      return RESULT_INITIAL_TOO_SPARSE;
even's avatar
even committed
  }
even's avatar
even committed

  // Filtering the initial segment
  //------------------------------
  if (prefilteringOn)
  {
    BlurredSegment *fbs = lsf1->filter (bsini);
    if (fbs != NULL)
    {
      delete bsini;
      bsini = fbs;
    }
    if (bsini->size () < initialMinSize)
even's avatar
even committed
      return RESULT_INITIAL_TOO_MANY_OUTLIERS;
  }
even's avatar
even committed

even's avatar
even committed
  // Orientation test for automatic extractions
  //-------------------------------------------
  Vr2i bsinidir = bsini->getSupportVector();
  if (bsinidir.orientedAs (inip1.vectorTo (inip2)))
even's avatar
even committed
    return RESULT_INITIAL_CLOSE_ORIENTATION;
even's avatar
even committed
  
even's avatar
even committed
  // Gradient reference selection
  //-----------------------------
  Pt2i pCenter = bsini->getCenter ();
  Vr2i gRef = gMap->getValue (pCenter);
even's avatar
even committed
  if (oppositeGradientDir && gMap->isOrientationConstraintOn ())
    gRef.invert ();
even's avatar
even committed

  // Scan recentering and fitting
  //-----------------------------
  if (recenteringOn)
    pCenter = bsini->getSegment()->centerOfIntersection (inip1, inip2);

  // Finer detection based on gradient maxima with orientation constraint
  //---------------------------------------------------------------------
  bsf = bst2->fineTrack (inThick, pCenter, bsinidir, 2 * inThick, gRef);
  if (bsf == NULL || bsf->size () < initialMinSize)
even's avatar
even committed
    return (bsf == NULL ? RESULT_FINAL_NO_DETECTION : RESULT_FINAL_TOO_FEW);
even's avatar
even committed

even's avatar
even committed
  // Size test
  //------------
  if (finalSizeTestOn)
even's avatar
even committed
  {
even's avatar
even committed
    // DigitalStraightSegment *dss = bsf->getSegment ();
    if ((int) (bsf->getAllPoints().size ()) < finalMinSize)
even's avatar
even committed
    {
even's avatar
even committed
      // nbSmallBS ++;
      return RESULT_FINAL_TOO_SMALL;
even's avatar
even committed
    }
even's avatar
even committed
  }

  // Sparsity test
  //--------------
  if (finalSparsityTestOn)
    Pt2i pOrtho (pCenter.x () + bsinidir.y (), pCenter.y () - bsinidir.y ());
    DigitalStraightLine mydsl (pCenter, pOrtho, DigitalStraightLine::DSL_NAIVE);
even's avatar
even committed
    int mydrlf = mydsl.manhattan (bsf->getLastRight ())
                 - mydsl.manhattan (bsf->getLastLeft ());
    if (mydrlf < 0) mydrlf = -mydrlf; // Case of horizontal P1P2
    int expansion = 1 + mydrlf;
even's avatar
even committed
    if (expansion < 20 && bsf->size () < (expansion * 4) / 5)
even's avatar
even committed
      return RESULT_FINAL_TOO_SPARSE;
  // Fragmentation test */
  //--------------------*/
  if (finalFragmentationTestOn)
    int bsccp = bsf->countOfConnectedPoints (fragmentMinSize);
    int bssize = bsf->getAllPoints().size ();
    if (bsccp < bssize / 2) return RESULT_FINAL_TOO_FRAGMENTED;
even's avatar
even committed

  // Final filtering
  //----------------
  if (filteringOn)
  {
    BlurredSegment *fbsf = lsf2->filter (bsf);
    if (fbsf != NULL)
    {
      delete bsf;
      bsf = fbsf;
    }
    else return RESULT_FINAL_TOO_MANY_OUTLIERS;
  }

even's avatar
even committed
  return RESULT_OK;
even's avatar
even committed
int BSDetector::staticDetect (const Pt2i &p1, const Pt2i &p2,
                              bool centralp, const Pt2i &pc)
even's avatar
even committed
{
even's avatar
even committed
  // Entry check
  //------------
  if (p1.equals (p2)
even's avatar
even committed
      || ((! centralp) && p1.chessboard (p2) < BSTracker::MIN_SCAN))
    return RESULT_VOID;
even's avatar
even committed
  // Clearance
  //----------
  bst1->clear ();
  bstStatic->clear ();
even's avatar
even committed
  if (bsini != NULL) delete bsini;
even's avatar
even committed
  bsini = NULL;
even's avatar
even committed
  if (bsf != NULL) delete bsf;
even's avatar
even committed
  bsf = NULL;
even's avatar
even committed

even's avatar
even committed
  inip1.set (p1);
  inip2.set (p2);
  iniwidth = (centralp ? DEFAULT_FAST_TRACK_SCAN_WIDTH : 0);
  inipc.set (pc);
even's avatar
even committed

  // Initial detection based on highest gradient without orientation constraint
  //---------------------------------------------------------------------------
even's avatar
even committed
  bsini = bst1->fastTrack (DEFAULT_FAST_TRACK_SCAN_WIDTH / 4,
even's avatar
even committed
                           inip1, inip2, iniwidth, inipc);
  if (bsini == NULL || bsini->size () < initialMinSize)
even's avatar
even committed
    return (bsini == NULL ? RESULT_INITIAL_NO_DETECTION
                          : RESULT_INITIAL_TOO_FEW);
even's avatar
even committed

  // Sparsity test
even's avatar
even committed
  //-------------
even's avatar
even committed
/*
  if (initialSparsityTestOn)
even's avatar
even committed
  {
even's avatar
even committed
    DigitalStraightLine mydsl (inip1, inip2, DigitalStraightLine::DSL_NAIVE);
even's avatar
even committed
    int mydrlf = mydsl.manhattan (bsini->getLastRight ())
                 - mydsl.manhattan (bsini->getLastLeft ());
    if (mydrlf < 0) mydrlf = -mydrlf; // Case of horizontal P1P2
    int expansion = 1 + mydrlf;
    if (bsini->size () < expansion / 2)
even's avatar
even committed
      return RESULT_INITIAL_TOO_SPARSE;
even's avatar
even committed
  }
even's avatar
even committed
*/
even's avatar
even committed

even's avatar
even committed
  // Orientation test for automatic extractions
  //-------------------------------------------
  Vr2i bsinidir = bsini->getSupportVector();
  if (bsinidir.orientedAs (inip1.vectorTo (inip2)))
even's avatar
even committed
    return RESULT_INITIAL_CLOSE_ORIENTATION;
even's avatar
even committed

even's avatar
even committed
  // Gradient reference selection
  //-----------------------------
even's avatar
even committed
  Pt2i pCenter = bsini->getCenter ();
even's avatar
even committed
  Vr2i gRef = gMap->getValue (pCenter);
even's avatar
even committed
  if (oppositeGradientDir && gMap->isOrientationConstraintOn ())
    gRef.invert ();
even's avatar
even committed

  // Scan recentering and fitting
  //-----------------------------
  if (recenteringOn)
even's avatar
even committed
    pCenter = bsini->getSegment()->centerOfIntersection (inip1, inip2);
even's avatar
even committed

  // Finer detection based on gradient maxima with orientation constraint
  //---------------------------------------------------------------------
  bsf = bstStatic->fineTrack (inThick, pCenter, bsinidir,
                              4 * inThick, gRef);
  if (bsf == NULL || bsf->size () < initialMinSize)
even's avatar
even committed
    return (bsf == NULL ? RESULT_FINAL_NO_DETECTION : RESULT_FINAL_TOO_FEW);

even's avatar
even committed
  // Scan recentering and fitting
  //-----------------------------
  pCenter = bsini->getCenter ();
  if (recenteringOn)
    pCenter = bsf->getSegment()->centerOfIntersection (inip1, inip2);

  // Third detection based on gradient maxima with orientation constraint
  //---------------------------------------------------------------------
  BlurredSegment *bsf2 = bstStatic->fineTrack (inThick,
                                               pCenter, bsf->getSupportVector(),
                                               4 * inThick, gRef);
  if (bsf2 == NULL || bsf2->size () < initialMinSize)
even's avatar
even committed
  {
even's avatar
even committed
    if (bsf2 != NULL)
even's avatar
even committed
    {
even's avatar
even committed
      delete bsf2;
      return RESULT_FINAL_TOO_FEW;
even's avatar
even committed
    }
even's avatar
even committed
    else return RESULT_FINAL_NO_DETECTION;
  }
  else
  {
    delete bsf;
    bsf = bsf2;
even's avatar
even committed
  }

  // Size test
  //------------
  if (finalSizeTestOn)
  {
    // DigitalStraightSegment *dss = bsf->getSegment ();
    if ((int) (bsf->getAllPoints().size ()) < finalMinSize)
    {
      // nbSmallBS ++;
      return RESULT_FINAL_TOO_SMALL;
    }
  }

  // Final sparsity test
even's avatar
even committed
  //-----------------
  if (finalSparsityTestOn)
    Pt2i pOrtho (pCenter.x () + bsinidir.y (), pCenter.y () - bsinidir.y ());
    DigitalStraightLine mydsl (pCenter, pOrtho, DigitalStraightLine::DSL_NAIVE);
even's avatar
even committed
    int mydrlf = mydsl.manhattan (bsf->getLastRight ())
                 - mydsl.manhattan (bsf->getLastLeft ());
    if (mydrlf < 0) mydrlf = -mydrlf; // Case of horizontal P1P2
    int expansion = 1 + mydrlf;
even's avatar
even committed
    if (bsf->size () < expansion / 2)
even's avatar
even committed
      return RESULT_FINAL_TOO_SPARSE;
even's avatar
even committed
  // Connected components analysis
  //------------------------------
  if (finalFragmentationTestOn)
even's avatar
even committed
  {
    int bsccp = bsf->countOfConnectedPoints (fragmentMinSize);
even's avatar
even committed
    int bssize = bsf->getAllPoints().size ();
    if (bsccp < bssize / 2) return RESULT_FINAL_TOO_FRAGMENTED;
even's avatar
even committed
  }

even's avatar
even committed
  return RESULT_OK;
even's avatar
even committed
}


even's avatar
even committed
BlurredSegment *BSDetector::getBlurredSegment (int step) const
{
  if (step == STEP_PRELIM) return (bspre);
  else if (step == STEP_INITIAL) return (bsini);
  else if (mbsf.empty ()) return (bsf);
  else return (mbsf.back ());
void BSDetector::incMaxDetections (bool dir)
{
  maxtrials = maxtrials + (dir ? -1 : 1);
  if (maxtrials < 0) maxtrials = (int) (mbsf.size ());
}


even's avatar
even committed
void BSDetector::getScanInput (int step,
                               Pt2i &p1, Pt2i &p2, int &swidth, Pt2i &pc) const
even's avatar
even committed
{
  if (step == STEP_PRELIM)
  {
    if (prelimDetectionOn)
    {
      p1.set (prep1);
      p2.set (prep2);
even's avatar
even committed
      swidth = prewidth;
even's avatar
even committed
      pc.set (prepc);
    }
  }
  else if (step == STEP_INITIAL)
  {
    p1.set (inip1);
    p2.set (inip2);
even's avatar
even committed
    swidth = iniwidth;
even's avatar
even committed
    pc.set (inipc);
  }
}


const vector <vector <Pt2i> > BSDetector::getFinalScans () const
{
  return (bst2->getScans ());
}


bool BSDetector::finalScansRecordOn () const
{
  return (bst2->scanRecordOn ());
}


void BSDetector::setFinalScansRecord (bool status)
{
  bst2->setScanRecord (status);
  if (status) redetect ();
}

even's avatar
even committed

void BSDetector::switchOrthoScans ()
{
even's avatar
even committed
  if (prelimDetectionOn) bst0->switchOrthoScans ();
  if (staticDetOn) bstStatic->switchOrthoScans ();
even's avatar
even committed
  bst1->switchOrthoScans ();
  bst2->switchOrthoScans ();
}


vector<Pt2i> BSDetector::getRejected (int step) const
{
  vector<Pt2i> res;
even's avatar
even committed
  if (step == STEP_FINAL)
even's avatar
even committed
  {
even's avatar
even committed
    if (filteringOn) res = lsf2->getRejected ();
even's avatar
even committed
  }
even's avatar
even committed
  else if (prefilteringOn) res = lsf1->getRejected ();
even's avatar
even committed
  return res;
}


void BSDetector::switchFiltering (int step)
{
even's avatar
even committed
  if (step == STEP_FINAL)
even's avatar
even committed
  {
    filteringOn = ! filteringOn;
even's avatar
even committed
    //if (filteringOn && lsf2 == NULL) lsf2 = new LineSpaceFilter ();
    if (filteringOn && lsf2 == NULL) lsf2 = new BSFilter ();
even's avatar
even committed
  }
even's avatar
even committed
  else if (step == STEP_INITIAL)
even's avatar
even committed
  {
    prefilteringOn = ! prefilteringOn;
even's avatar
even committed
    //if (prefilteringOn && lsf1 == NULL) lsf1 = new LineSpaceFilter ();
    if (prefilteringOn && lsf1 == NULL) lsf1 = new BSFilter ();
even's avatar
even committed
  }
}


bool BSDetector::incFragmentSizeMinValue (bool increase)
even's avatar
even committed
{
  if ((! increase) && fragmentMinSize <= 1) return false;
  fragmentMinSize += (increase ? 1 : -1);
even's avatar
even committed
  return true;
}
even's avatar
even committed


void BSDetector::switchPreliminary ()
{
  if (prelimDetectionOn)
  {
    delete bst0;
    prelimDetectionOn = false;
  }
  else
  {
    prelimDetectionOn = true;
    bst0 = new BSTracker ();
    bst0->setGradientMap (gMap);
    if (bst1->orthoScansOn ()) bst0->switchOrthoScans ();
  }
}
even's avatar
even committed
bool BSDetector::switchOppositeGradient ()
{
  if (gMap != NULL && gMap->isOrientationConstraintOn ())
  {
    oppositeGradientDir = ! oppositeGradientDir;
    return true;
  }
  return false;
}


void BSDetector::setStaticDetector (bool status)
{
  if (staticDetOn && ! status)
  {
    delete bstStatic;
    staticDetOn = false;
  }
  else if (status && ! staticDetOn)
  {
    bstStatic = new BSTracker ();
    if (gMap) bstStatic->setGradientMap (gMap);
    if (bstStatic->dynamicScansOn ()) bstStatic->toggleDynamicScans ();
    if (bstStatic->isAssignedThicknessControlOn ())
      bstStatic->toggleAssignedThicknessControl ();
    staticDetOn = true;
  }
}


Kerautret Bertrand's avatar
Kerautret Bertrand committed
std::string BSDetector::version ()
{
  return BSDetector::VERSION;
}