]> SALOME platform Git repositories - modules/geom.git/commitdiff
Salome HOME
Improve shape recognition features
authorkga <kga@opencascade.com>
Tue, 22 Oct 2013 11:42:25 +0000 (11:42 +0000)
committerkga <kga@opencascade.com>
Tue, 22 Oct 2013 11:42:25 +0000 (11:42 +0000)
src/EntityGUI/EntityGUI_FeatureDetectorDlg.cxx
src/EntityGUI/EntityGUI_FeatureDetectorDlg.h
src/GEOMGUI/GEOM_msg_en.ts
src/GEOMGUI/GEOM_msg_fr.ts

index a9a5d2ce38af48bc6b46eae249bfacdafdd05767..cbb5645fded338fc123f0a8c7a71888c40028e25 100644 (file)
@@ -89,6 +89,25 @@ enum {
   PUSH_BUTTON,
 };
 
+enum {
+  KERNEL_SIZE,
+  FIND_CONTOURS_METHOD,
+  QUALITY_LEVEL,
+  MIN_DISTANCE,
+  TYPE_CRITERIA,
+  MAX_ITER,
+  EPSILON,
+  LOW_THRESHOLD,
+  RATIO,
+  L2GRADIENT,
+  SMOOTH_SIZE,
+  HBINS,
+  SBINS,
+  HIST_TYPE,
+  THRESHOLD_VALUE,
+  MAX_THRESHOLD,
+};
+
 // // // View
 // // enum {
 // //   XY,
@@ -157,9 +176,151 @@ EntityGUI_FeatureDetectorDlg::EntityGUI_FeatureDetectorDlg( GeometryGUI* theGeom
   
 //   myOutputGroup->hide(); //caché pour la demo
     
+  // Parameters 
+  QGridLayout* parametersLayout = new QGridLayout();
+  parametersLayout->setMargin(9);
+  QComboBox* kernelSize = new QComboBox();
+  kernelSize->addItems( QStringList() << "3" << "5" << "7" );
+  myWidgets.insert( KERNEL_SIZE, kernelSize );
+  myUseROI = new QCheckBox( tr("USE_ROI") );
+  myUseROI->setChecked( true );
+
+  parametersLayout->addWidget( new QLabel( tr("KERNEL_SIZE") ), 0, 0 );
+  parametersLayout->addWidget( kernelSize, 0, 1 );
+  parametersLayout->addWidget( myUseROI, 0, 2 );
+
+  // Corners Parameters 
+  myCornersParameters = new QFrame();
+  myCornersParameters->setFrameStyle(QFrame::NoFrame);
+  QDoubleSpinBox* qualityLevel = new QDoubleSpinBox();
+  qualityLevel->setValue( 0.2 );
+  qualityLevel->setSingleStep( 0.1 );
+  qualityLevel->setRange( 0.01, 0.99 );
+  myWidgets.insert( QUALITY_LEVEL, qualityLevel );
+  QDoubleSpinBox* minDistance = new QDoubleSpinBox();
+  minDistance->setValue( 1 );
+  myWidgets.insert( MIN_DISTANCE, minDistance );
+  QComboBox* typeCriteria = new QComboBox();
+  typeCriteria->addItems( QStringList() << tr("CV_TERMCRIT_ITER") << tr("CV_TERMCRIT_EPS") << tr("CV_TERMCRIT_ITER | CV_TERMCRIT_EPS") );
+  typeCriteria->setCurrentIndex( 2 );
+  myWidgets.insert( TYPE_CRITERIA, typeCriteria );
+  QSpinBox* maxIter = new QSpinBox();
+  maxIter->setValue( 20 );
+  maxIter->setRange( 1, 100 );
+  myWidgets.insert( MAX_ITER, maxIter );
+  QDoubleSpinBox* epsilon = new QDoubleSpinBox();
+  epsilon->setValue( 0.03 );
+  epsilon->setSingleStep( 0.01 );
+  myWidgets.insert( EPSILON, epsilon );
+
+  QGridLayout* cornersLayout = new QGridLayout();
+  cornersLayout->setMargin( 0 );
+  cornersLayout->addWidget( new QLabel( tr("QUALITY_LEVEL") ), 0, 0 );
+  cornersLayout->addWidget( qualityLevel, 0, 1 );
+  cornersLayout->addWidget( new QLabel( tr("MIN_DISTANCE") ), 0, 2 );
+  cornersLayout->addWidget( minDistance, 0 ,3 );
+  cornersLayout->addWidget( new QLabel( tr("TYPE_CRITERIA") ), 1, 0 );
+  cornersLayout->addWidget( typeCriteria, 1, 1, 1, 3 );
+  cornersLayout->addWidget( new QLabel( tr("MAX_ITER") ), 2, 0 );
+  cornersLayout->addWidget( maxIter, 2, 1 );
+  cornersLayout->addWidget( new QLabel( tr("EPSILON") ), 2, 2 );
+  cornersLayout->addWidget( epsilon, 2 , 3 );
+
+  myCornersParameters->setLayout( cornersLayout );
+
+  // Contours Parameters
+  myContoursParameters = new QFrame();
+  myContoursParameters->setFrameStyle(QFrame::NoFrame);
+
+  QComboBox* findContoursMethod = new QComboBox();
+  findContoursMethod->addItems( QStringList() << tr("CV_CHAIN_APPROX_NONE") << tr("CV_CHAIN_APPROX_SIMPLE") << tr("CV_CHAIN_APPROX_TC89_L1") << tr("CV_CHAIN_APPROX_TC89_KCOS") );
+  myWidgets.insert( FIND_CONTOURS_METHOD, findContoursMethod );
+
+  myCannyParameters = new QFrame();
+  myCannyParameters->setFrameStyle(QFrame::NoFrame);
+  QSpinBox* threshold = new QSpinBox();
+  threshold->setRange( 0, 255 );
+  threshold->setValue( 100 );
+  myWidgets.insert( LOW_THRESHOLD, threshold );
+  QSpinBox* ratio = new QSpinBox();
+  ratio->setValue( 3 );
+  ratio->setRange( 0, 255 );
+  myWidgets.insert( RATIO, ratio );
+  QCheckBox* L2gradient = new QCheckBox(tr("L2GRADIENT"));
+  L2gradient->setChecked(true);
+  myWidgets.insert( L2GRADIENT, L2gradient );
+
+  QGridLayout* cannyLayout = new QGridLayout();
+  cannyLayout->setMargin( 0 );
+  cannyLayout->addWidget( new QLabel( tr("LOWTHRESHOLD") ), 0, 0 );
+  cannyLayout->addWidget( threshold, 0, 1 );
+  cannyLayout->addWidget( new QLabel( tr("RATIO") ), 0, 2 );
+  cannyLayout->addWidget( ratio, 0, 3 );
+  cannyLayout->addWidget( L2gradient, 1, 0 );
+
+  myCannyParameters->setLayout( cannyLayout );
+  myCannyParameters->setHidden( true );
+
+  myColorFilterParameters = new QFrame();
+  myColorFilterParameters->setFrameStyle(QFrame::NoFrame);
+
+  QSpinBox* smoothSize = new QSpinBox();
+  smoothSize->setValue( 3 );
+  smoothSize->setSingleStep( 2 );
+  smoothSize->setRange( 1, 1000 );
+  myWidgets.insert( SMOOTH_SIZE, smoothSize );
+  QSpinBox* hbins = new QSpinBox();
+  hbins->setValue( 30 );
+  hbins->setRange( 0, 179 );
+  myWidgets.insert( HBINS, hbins );
+  QSpinBox* sbins = new QSpinBox();
+  sbins->setValue( 32 );
+  sbins->setRange( 0, 255 );
+  myWidgets.insert( SBINS, sbins );
+  QComboBox* histType = new QComboBox();
+  histType->addItems( QStringList() << tr("CV_HIST_ARRAY") << tr("CV_HIST_SPARSE") );
+  myWidgets.insert( HIST_TYPE, histType );
+  QDoubleSpinBox* thresholdValue = new QDoubleSpinBox();
+  thresholdValue->setRange( 0, 254 );
+  thresholdValue->setValue( 128 );
+  myWidgets.insert( THRESHOLD_VALUE, thresholdValue );
+  QDoubleSpinBox* maxThreshold = new QDoubleSpinBox();
+  maxThreshold->setRange( 1, 255 );
+  maxThreshold->setValue( 255 );
+  myWidgets.insert( MAX_THRESHOLD, maxThreshold );
+
+  QGridLayout* colorFilterLayout = new QGridLayout();
+  colorFilterLayout->setMargin( 0 );
+  colorFilterLayout->addWidget( new QLabel( tr("SMOOTH_SIZE") ), 0, 0 );
+  colorFilterLayout->addWidget( smoothSize, 0, 1 );
+  colorFilterLayout->addWidget( new QLabel( tr("HBINS") ), 1, 0 );
+  colorFilterLayout->addWidget( hbins, 1, 1 );
+  colorFilterLayout->addWidget( new QLabel( tr("SBINS") ), 1, 2 );
+  colorFilterLayout->addWidget( sbins, 1, 3 );
+  colorFilterLayout->addWidget( new QLabel( tr("HIST_TYPE") ), 2, 0 );
+  colorFilterLayout->addWidget( histType, 2, 1, 1, 3 );
+  colorFilterLayout->addWidget( new QLabel( tr("THRESHOLD_VALUE") ), 3, 0 );
+  colorFilterLayout->addWidget( thresholdValue, 3, 1 );
+  colorFilterLayout->addWidget( new QLabel( tr("MAX_THRESHOLD") ), 3, 2 );
+  colorFilterLayout->addWidget( maxThreshold, 3, 3 );
+
+  myColorFilterParameters->setLayout( colorFilterLayout );
+  QGridLayout* contoursLayout = new QGridLayout();
+  contoursLayout->setMargin( 0 );
+  contoursLayout->addWidget( new QLabel( tr("FIND_CONTOURS_METHOD") ), 0, 0 );
+  contoursLayout->addWidget( findContoursMethod, 0, 1 );
+  contoursLayout->addWidget( myCannyParameters, 1, 0, 1, 3 );
+  contoursLayout->addWidget( myColorFilterParameters, 1, 0, 1, 3  );
+
+  myContoursParameters->setLayout( contoursLayout );
+
+  parametersLayout->addWidget( myCornersParameters, 1, 0, 1, 3 );
+  parametersLayout->addWidget( myContoursParameters, 1, 0, 1, 3 );
+
   QVBoxLayout* layout = new QVBoxLayout(centralWidget());
   layout->setMargin(0); layout->setSpacing(6);
 //   layout->addWidget( myViewGroup);
+  layout->addLayout( parametersLayout );
   layout->addWidget( mySelectionGroup);
   layout->addWidget( myOutputGroup);
   
@@ -192,6 +353,7 @@ void EntityGUI_FeatureDetectorDlg::Init()
   connect( myGeomGUI,         SIGNAL( SignalCloseAllDialogs() ), this, SLOT( ClickOnCancel() ) );
   connect( buttonOk(),        SIGNAL( clicked() ),               this, SLOT( ClickOnOk() ) );
   connect( buttonApply(),     SIGNAL( clicked() ),               this, SLOT( ClickOnApply() ) );
+  connect( myUseROI,          SIGNAL( toggled(bool) ),           this, SLOT( onCheckBoxClicked(bool) ) );
   connect( this,              SIGNAL(constructorsClicked(int)),  this, SLOT(ConstructorsClicked(int))); 
   connect( mySelectionGroup->PushButton2,      SIGNAL( clicked() ),               this, SLOT( onButtonClicked() ) );
   connect( mySelectionGroup->PushButton1,       SIGNAL( clicked() ),               this, SLOT( onButtonClicked() ) );  
@@ -341,23 +503,21 @@ void EntityGUI_FeatureDetectorDlg::ConstructorsClicked(int id)
   switch (id)
   {
     case CORNERS:
+      myCornersParameters->show();
+      myContoursParameters->hide();
 //       myViewGroup->show();
 //       mySelectionGroup->show();
       myOutputGroup->hide();
 //       mySelectionGroup->TextLabel2->setText(tr("GEOM_DETECT_ZONE"));
-      mySelectionGroup->TextLabel2->hide();
-      mySelectionGroup->Frame->hide();
-      mySelectionGroup->PushButton2->hide();
       initName(tr("GEOM_CORNERS"));
       break;
     case CONTOURS:
+      myCornersParameters->hide();
+      myContoursParameters->show();
 //       myViewGroup->hide();
 //       mySelectionGroup->hide();
 //       mySelectionGroup->show();
       myOutputGroup->show();
-      mySelectionGroup->TextLabel2->show();
-      mySelectionGroup->Frame->show();
-      mySelectionGroup->PushButton2->show();
       mySelectionGroup->TextLabel2->setText(tr("GEOM_COLOR_FILTER"));
       initName(tr("GEOM_CONTOURS"));
       break;
@@ -424,6 +584,78 @@ void EntityGUI_FeatureDetectorDlg::onButtonClicked()
   }
 }
 
+//=================================================================================
+// function : onCheckBoxClicked(bool)
+// purpose  :
+//=================================================================================
+void EntityGUI_FeatureDetectorDlg::onCheckBoxClicked( bool isChecked )
+{
+  mySelectionGroup->TextLabel2->setVisible( isChecked );
+  mySelectionGroup->Frame->setVisible( isChecked );
+  mySelectionGroup->PushButton2->setVisible( isChecked );
+  myCannyParameters->setHidden( isChecked );
+  myColorFilterParameters->setHidden( !isChecked );
+}
+
+//=================================================================================
+// function : parametersChanged()
+// purpose  :
+//=================================================================================
+ShapeRec_Parameters* EntityGUI_FeatureDetectorDlg::parametersChanged()
+{
+  ShapeRec_Parameters* aParameters = new ShapeRec_Parameters();
+
+  if ( myConstructorId == CORNERS ) {
+    ShapeRec_CornersParameters* aCornersParameters = dynamic_cast<ShapeRec_CornersParameters*>( aParameters );
+    if ( !aCornersParameters ) aCornersParameters = new ShapeRec_CornersParameters();
+    aCornersParameters->qualityLevel = (dynamic_cast<QDoubleSpinBox*>(myWidgets[QUALITY_LEVEL]))->value();
+    aCornersParameters->minDistance  = (dynamic_cast<QDoubleSpinBox*>(myWidgets[MIN_DISTANCE]))->value();
+    switch ( (dynamic_cast<QComboBox*>(myWidgets[TYPE_CRITERIA]))->currentIndex() ) {
+    case 0: aCornersParameters->typeCriteria = CV_TERMCRIT_ITER;
+    case 1: aCornersParameters->typeCriteria = CV_TERMCRIT_EPS;
+    case 2: aCornersParameters->typeCriteria = CV_TERMCRIT_ITER | CV_TERMCRIT_EPS;
+    }
+    aCornersParameters->maxIter = (dynamic_cast<QSpinBox*>(myWidgets[MAX_ITER]))->value();
+    aCornersParameters->epsilon = (dynamic_cast<QDoubleSpinBox*>(myWidgets[EPSILON]))->value();
+    aParameters = aCornersParameters;
+  }
+  else if ( myConstructorId == CONTOURS ) {
+    if ( !myUseROI->isChecked() ) { 
+      ShapeRec_CannyParameters* aCannyParameters = dynamic_cast<ShapeRec_CannyParameters*>( aParameters );
+      if ( !aCannyParameters ) aCannyParameters = new ShapeRec_CannyParameters();
+      aCannyParameters->lowThreshold = (dynamic_cast<QSpinBox*>(myWidgets[LOW_THRESHOLD]))->value();
+      aCannyParameters->ratio        = (dynamic_cast<QSpinBox*>(myWidgets[RATIO]))->value();
+      aCannyParameters->L2gradient   = (dynamic_cast<QCheckBox*>(myWidgets[L2GRADIENT]))->isChecked();
+      aParameters = aCannyParameters;
+    }
+    else {
+      ShapeRec_ColorFilterParameters* aColorFilterParameters = dynamic_cast<ShapeRec_ColorFilterParameters*>( aParameters );
+      if ( !aColorFilterParameters ) aColorFilterParameters = new ShapeRec_ColorFilterParameters();
+      int aSmoothSize = (dynamic_cast<QSpinBox*>(myWidgets[SMOOTH_SIZE]))->value();
+      aColorFilterParameters->smoothSize  = aSmoothSize % 2 == 0 ? aSmoothSize - 1 : aSmoothSize;
+      aColorFilterParameters->histSize[0] = (dynamic_cast<QSpinBox*>(myWidgets[HBINS]))->value();
+      aColorFilterParameters->histSize[1] = (dynamic_cast<QSpinBox*>(myWidgets[SBINS]))->value();
+      switch ( (dynamic_cast<QComboBox*>(myWidgets[HIST_TYPE]))->currentIndex() ) {
+      case 0: aColorFilterParameters->histType = CV_HIST_ARRAY;  break;
+      case 1: aColorFilterParameters->histType = CV_HIST_SPARSE; break;
+      }
+      aColorFilterParameters->threshold    = (dynamic_cast<QDoubleSpinBox*>(myWidgets[THRESHOLD_VALUE]))->value();
+      aColorFilterParameters->maxThreshold = (dynamic_cast<QDoubleSpinBox*>(myWidgets[MAX_THRESHOLD]))->value();
+      aParameters = aColorFilterParameters;
+    }
+  }
+  aParameters->kernelSize = ( (dynamic_cast<QComboBox*>(myWidgets[KERNEL_SIZE]))->currentText() ).toInt();
+  switch ( (dynamic_cast<QComboBox*>(myWidgets[FIND_CONTOURS_METHOD]))->currentIndex() ) {
+  case 0: aParameters->findContoursMethod = CV_CHAIN_APPROX_NONE;      break;
+  case 1: aParameters->findContoursMethod = CV_CHAIN_APPROX_SIMPLE;    break;
+  case 2: aParameters->findContoursMethod = CV_CHAIN_APPROX_TC89_L1;   break;
+  case 3: aParameters->findContoursMethod = CV_CHAIN_APPROX_TC89_KCOS; break;
+  }
+
+  return aParameters;
+}
+
 //=================================================================================
 // function : setStartPnt( const QPoint& )
 // purpose  :
@@ -501,85 +733,87 @@ bool EntityGUI_FeatureDetectorDlg::execute( ObjectList& objects )
   
   GEOM::GEOM_IBasicOperations_var  aBasicOperations  = myGeomGUI->GetGeomGen()->GetIBasicOperations( getStudyId() );
   GEOM::GEOM_IShapesOperations_var aShapesOperations = GEOM::GEOM_IShapesOperations::_narrow( getOperation() );
-  
-  if (myConstructorId == CORNERS)
-  {
-    double subPictureLeft;
-    double subPictureTop;
-    if( !myRect.isEmpty() )
-    {
-      aDetector->SetROI( myRect );
-      subPictureLeft    = myStartPnt.X();                
-      subPictureTop     = myStartPnt.Y();
-    }
-    else
+
+  ShapeRec_Parameters* parameters = parametersChanged();
+  if ( !parameters ) parameters = new ShapeRec_Parameters();
+
+  bool useROI = myUseROI->isChecked() && !myRect.isEmpty();
+  try {
+    if (myConstructorId == CORNERS)
     {
-      subPictureLeft    = pictureLeft;
-      subPictureTop     = pictureTop;
-    }
-    aDetector->ComputeCorners();
-    CvPoint2D32f* corners     = aDetector->GetCorners();
-    int cornerCount           = aDetector->GetCornerCount();
-    int i;
+      double subPictureLeft;
+      double subPictureTop;
+      if( useROI )
+      {
+       subPictureLeft    = myStartPnt.X();                
+       subPictureTop     = myStartPnt.Y();
+      }
+      else
+      {
+       subPictureLeft    = pictureLeft;
+       subPictureTop     = pictureTop;
+      }
+      aDetector->ComputeCorners( useROI, parameters );
+      CvPoint2D32f* corners     = aDetector->GetCorners();
+      int cornerCount           = aDetector->GetCornerCount();
+      int i;
     
-    // Build the geom objects associated to the detected corners and returned by execute   
-    if( !aBasicOperations->_is_nil() && !aShapesOperations->_is_nil() ) 
-    {
-      GEOM::GEOM_Object_var  aGeomCorner;
-      GEOM::ListOfGO_var     geomCorners = new GEOM::ListOfGO();
-      geomCorners->length( cornerCount );
-      for (i = 0; i < cornerCount; i++)
+      // Build the geom objects associated to the detected corners and returned by execute   
+      if( !aBasicOperations->_is_nil() && !aShapesOperations->_is_nil() ) 
       {
-        double x = subPictureLeft + corners[i].x;
-        double y = subPictureTop  - corners[i].y;
-        double z =  0;
+       GEOM::GEOM_Object_var  aGeomCorner;
+       GEOM::ListOfGO_var     geomCorners = new GEOM::ListOfGO();
+       geomCorners->length( cornerCount );
+       for (i = 0; i < cornerCount; i++)
+        {
+         double x = subPictureLeft + corners[i].x;
+         double y = subPictureTop  - corners[i].y;
+         double z =  0;
         
-        aGeomCorner = aBasicOperations->MakePointXYZ( x,y,z );
+         aGeomCorner = aBasicOperations->MakePointXYZ( x,y,z );
         
-        geomCorners[i] = aGeomCorner;  
-      } 
-      GEOM::GEOM_Object_var aCompound = aShapesOperations->MakeCompound(geomCorners);    
-      if ( !aCompound->_is_nil() )
-      {
-        // Dark blue color
-        SALOMEDS::Color aColor;
-        aColor.R = 0;
-        aColor.G = 0;
-        aColor.B = 0.8;
-        
-        aCompound->SetColor(aColor);
-        aCompound->SetMarkerStd(GEOM::MT_POINT,GEOM::MS_30);
-        objects.push_back( aCompound._retn() );
-        res = true;
-      }
+         geomCorners[i] = aGeomCorner;  
+       } 
+       GEOM::GEOM_Object_var aCompound = aShapesOperations->MakeCompound(geomCorners);    
+       if ( !aCompound->_is_nil() )
+       {
+         // Dark blue color
+         SALOMEDS::Color aColor;
+         aColor.R = 0;
+         aColor.G = 0;
+         aColor.B = 0.8;
+
+         aCompound->SetColor(aColor);
+         aCompound->SetMarkerStd(GEOM::MT_POINT,GEOM::MS_30);
+         objects.push_back( aCompound._retn() );
+         res = true;
+       }
+      }   
     }
-  }
-  else if (myConstructorId == CONTOURS)
-  {
-    int method = 0 ; //CANNY
-    if( !myRect.isEmpty() && myRect.width() > 1 )
-    {
-      aDetector->SetROI( myRect );
-      method = 1 ; //COLORFILTER    
-    }
-    
-    GEOM::GEOM_ICurvesOperations_var aCurveOperations = myGeomGUI->GetGeomGen()->GetICurvesOperations( getStudyId() );
-    
-    aDetector->ComputeContours( method );
-    std::vector< std::vector<cv::Point> >   contours  = aDetector->GetContours();
-    std::vector<cv::Vec4i>                  hierarchy = aDetector->GetContoursHierarchy();
-    
-    std::vector< cv::Point >                contour;
-    int idx = 0;
+    else if (myConstructorId == CONTOURS)
+    {    
+      GEOM::GEOM_ICurvesOperations_var aCurveOperations = myGeomGUI->GetGeomGen()->GetICurvesOperations( getStudyId() );
+
+      aDetector->ComputeContours( useROI, parameters );
+      std::vector< std::vector<cv::Point> >   contours  = aDetector->GetContours();
+      std::vector<cv::Vec4i>                  hierarchy = aDetector->GetContoursHierarchy();
     
-    GEOM::ListOfGO_var                      geomContours = new GEOM::ListOfGO();
-    int contourCount = 0;
+      std::vector< cv::Point >                contour;
+      int idx = 0;
+      
+      GEOM::ListOfGO_var                      geomContours = new GEOM::ListOfGO();
+      int contourCount = 0;
     
-    bool insert;
+      bool insert;
     
-    MESSAGE("hierarchy.size() =" << hierarchy.size()) 
-    for( ; idx >= 0; idx = hierarchy[idx][0])
-    {
+      MESSAGE("hierarchy.size() =" << hierarchy.size()) 
+      if ( hierarchy.size() < 1 ) {
+       getOperation()->SetErrorCode( "Impossible detected contours" );
+       return false;
+      }
+
+      for( ; idx >= 0; idx = hierarchy[idx][0])
+      {
 //       for(int count=0, child=idx; child>=0, count<1; child=hierarchy[idx][2], count++)
 //       {     
 //         contour = contours[child];
@@ -595,7 +829,7 @@ bool EntityGUI_FeatureDetectorDlg::execute( ObjectList& objects )
         int j = 0;
         std::set< std::vector<int> > existing_points;
         std::pair< std::set< std::vector<int> >::iterator,bool > pnt_it;
-        for ( it=contour.begin() ; it < contour.end(); it++ )
+        for ( it=contour.begin() ; it < contour.end()-1; it++ )
         {
           int pnt_array[] = {it->x,it->y};     
           std::vector<int> pnt (pnt_array, pnt_array + sizeof(pnt_array) / sizeof(int) );
@@ -662,13 +896,18 @@ bool EntityGUI_FeatureDetectorDlg::execute( ObjectList& objects )
           contourCount++;
         }
 //       }
+      }
+      GEOM::GEOM_Object_var aContoursCompound = aShapesOperations->MakeCompound(geomContours);
+      if ( !aContoursCompound->_is_nil() )
+      {
+       objects.push_back( aContoursCompound._retn() );
+      }
+      res=true;
     }
-    GEOM::GEOM_Object_var aContoursCompound = aShapesOperations->MakeCompound(geomContours);
-    if ( !aContoursCompound->_is_nil() )
-    {
-      objects.push_back( aContoursCompound._retn() );
-    }
-    res=true;
+  }
+  catch( ... ) {
+    getOperation()->SetErrorCode( "Impossible detected contours/corners" );
+    return false;
   }
   
   // TEST not very conclusive
index cdbced6474a1bee0863282147aaccff17b93410f..fdc850d8df8a68c733dcbec46953340213ebe19b 100644 (file)
@@ -34,6 +34,7 @@ class QCheckBox;
 class QGroupBox;
 class QPushButton;
 class QLabel;
+class QFrame;
 class QPoint;
 class DlgRef_3Radio;
 class DlgRef_1Sel;
@@ -41,6 +42,7 @@ class DlgRef_1Sel1Frame;
 
 class gp_Pnt;
 class ShapeRec_FeatureDetector;
+class ShapeRec_Parameters;
 
 //=================================================================================
 // class    : EntityGUI_Dlg
@@ -68,6 +70,7 @@ private:
   void                               Init();
   bool                               setSelectionRect();
   void                               showImageSample();
+  ShapeRec_Parameters*               parametersChanged();
 
   
 private slots:
@@ -75,6 +78,7 @@ private slots:
   void                               ConstructorsClicked( int );
 //   void                               onViewClicked( int );
   void                               onButtonClicked(); 
+  void                               onCheckBoxClicked( bool );
   void                               ClickOnOk();
   bool                               ClickOnApply();
   
@@ -92,6 +96,13 @@ private:
   
   DlgRef_1Sel1Frame*                 mySelectionGroup; 
   DlgRef_1Sel*                       mySelWidget;
+
+  QCheckBox*                         myUseROI;
+  QFrame*                            myCornersParameters;
+  QFrame*                            myContoursParameters;
+  QFrame*                            myCannyParameters;
+  QFrame*                            myColorFilterParameters;
+  QList<QWidget*>                    myWidgets;
   
   // Output typeselection widget
   DlgRef_3Radio*                     myOutputGroup;;
index c0b8d2e951fa54510064cbe64edf82b5ff8eb003..9ab089610bc91c292786a582954f8eb6c3954524 100644 (file)
@@ -5318,6 +5318,110 @@ Number of sketch points too small</translation>
         <source>GEOM_LEFT</source>
         <translation>Left (X-Z)</translation>
     </message>
+    <message>
+        <source>USE_ROI</source>
+        <translation>Use region of interest</translation>
+    </message>
+    <message>
+        <source>KERNEL_SIZE</source>
+        <translation>Kernel size</translation>
+    </message>
+    <message>
+        <source>QUALITY_LEVEL</source>
+        <translation>Quality level</translation>
+    </message>
+    <message>
+        <source>MIN_DISTANCE</source>
+        <translation>Min distance</translation>
+    </message>
+    <message>
+        <source>TYPE_CRITERIA</source>
+        <translation>Type criteria</translation>
+    </message>
+    <message>
+        <source>CV_TERMCRIT_ITER</source>
+        <translation>Max number of iteration</translation>
+    </message>
+    <message>
+        <source>CV_TERMCRIT_EPS</source>
+        <translation>Epsilon</translation>
+    </message>
+    <message>
+        <source>CV_TERMCRIT_ITER | CV_TERMCRIT_EPS</source>
+        <translation>Max number of iteration or epsilon</translation>
+    </message>
+    <message>
+        <source>MAX_ITER</source>
+        <translation>Max iteration</translation>
+    </message>
+    <message>
+        <source>EPSILON</source>
+        <translation>Epsilon</translation>
+    </message>
+    <message>
+        <source>L2GRADIENT</source>
+        <translation>L2 gradient</translation>
+    </message>
+    <message>
+        <source>LOWTHRESHOLD</source>
+        <translation>Low theshold</translation>
+    </message>
+    <message>
+        <source>RATIO</source>
+        <translation>Ratio</translation>
+    </message>
+    <message>
+        <source>SMOOTH_SIZE</source>
+        <translation>Smooth size</translation>
+    </message>
+    <message>
+        <source>HBINS</source>
+        <translation>Hbins</translation>
+    </message>
+    <message>
+        <source>SBINS</source>
+        <translation>Sbins</translation>
+    </message>
+    <message>
+        <source>HIST_TYPE</source>
+        <translation>Histogram type</translation>
+    </message>
+    <message>
+        <source>CV_HIST_ARRAY</source>
+        <translation>Multi-dimensional dense array</translation>
+    </message>
+    <message>
+        <source>CV_HIST_SPARSE</source>
+        <translation>Multi-dimensional sparse array</translation>
+    </message>
+    <message>
+        <source>THRESHOLD_VALUE</source>
+        <translation>Threshold value</translation>
+    </message>
+    <message>
+        <source>MAX_THRESHOLD</source>
+        <translation>Max threshold</translation>
+    </message>
+    <message>
+        <source>FIND_CONTOURS_METHOD</source>
+        <translation>Chain approximation method</translation>
+    </message>
+    <message>
+        <source>CV_CHAIN_APPROX_NONE</source>
+        <translation>None</translation>
+    </message>
+    <message>
+        <source>CV_CHAIN_APPROX_SIMPLE</source>
+        <translation>Simple</translation>
+    </message>
+    <message>
+        <source>CV_CHAIN_APPROX_TC89_KCOS</source>
+        <translation>TC89 KCOS</translation>
+    </message>
+    <message>
+        <source>CV_CHAIN_APPROX_TC89_L1</source>
+        <translation>TC89 L1</translation>
+    </message>
 </context>
 <context>
     <name>EntityGUI_PictureImportDlg</name>
index f013178ac4200825a159f8e3a91be5ce42512ae2..0e6ad23e1a4a3899d9183c0e9458837ec33cdd01 100644 (file)
@@ -5255,6 +5255,110 @@ Le nombre de points n&apos;est pas suffisant</translation>
         <source>GEOM_LEFT</source>
         <translation>Gauche (X-Z)</translation>
     </message>
+    <message>
+        <source>USE_ROI</source>
+        <translation type="unfinished">Use region of interest</translation>
+    </message>
+    <message>
+        <source>KERNEL_SIZE</source>
+        <translation type="unfinished">Kernel size</translation>
+    </message>
+    <message>
+        <source>QUALITY_LEVEL</source>
+        <translation type="unfinished">Quality level</translation>
+    </message>
+    <message>
+        <source>MIN_DISTANCE</source>
+        <translation type="unfinished">Min distance</translation>
+    </message>
+    <message>
+        <source>TYPE_CRITERIA</source>
+        <translation type="unfinished">Type criteria</translation>
+    </message>
+    <message>
+        <source>CV_TERMCRIT_ITER</source>
+        <translation type="unfinished">Max number of iteration</translation>
+    </message>
+    <message>
+        <source>CV_TERMCRIT_EPS</source>
+        <translation type="unfinished">Epsilon</translation>
+    </message>
+    <message>
+        <source>CV_TERMCRIT_ITER | CV_TERMCRIT_EPS</source>
+        <translation type="unfinished">Max number of iteration or epsilon</translation>
+    </message>
+    <message>
+        <source>MAX_ITER</source>
+        <translation type="unfinished">Max iteration</translation>
+    </message>
+    <message>
+        <source>EPSILON</source>
+        <translation type="unfinished">Epsilon</translation>
+    </message>
+    <message>
+        <source>L2GRADIENT</source>
+        <translation type="unfinished">L2 gradient</translation>
+    </message>
+    <message>
+        <source>LOWTHRESHOLD</source>
+        <translation type="unfinished">Low theshold</translation>
+    </message>
+    <message>
+        <source>RATIO</source>
+        <translation type="unfinished">Ratio</translation>
+    </message>
+    <message>
+        <source>SMOOTH_SIZE</source>
+        <translation type="unfinished">Smooth size</translation>
+    </message>
+    <message>
+        <source>HBINS</source>
+        <translation type="unfinished">Hbins</translation>
+    </message>
+    <message>
+        <source>SBINS</source>
+        <translation type="unfinished">Sbins</translation>
+    </message>
+    <message>
+        <source>HIST_TYPE</source>
+        <translation type="unfinished">Histogram type</translation>
+    </message>
+    <message>
+        <source>CV_HIST_ARRAY</source>
+        <translation type="unfinished">Multi-dimensional dense array</translation>
+    </message>
+    <message>
+        <source>CV_HIST_SPARSE</source>
+        <translation type="unfinished">Multi-dimensional sparse array</translation>
+    </message>
+    <message>
+        <source>THRESHOLD_VALUE</source>
+        <translation type="unfinished">Threshold value</translation>
+    </message>
+    <message>
+        <source>MAX_THRESHOLD</source>
+        <translation type="unfinished">Max threshold</translation>
+    </message>
+    <message>
+        <source>FIND_CONTOURS_METHOD</source>
+        <translation type="unfinished">Chain approximation method</translation>
+    </message>
+    <message>
+        <source>CV_CHAIN_APPROX_NONE</source>
+        <translation type="unfinished">None</translation>
+    </message>
+    <message>
+        <source>CV_CHAIN_APPROX_SIMPLE</source>
+        <translation type="unfinished">Simple</translation>
+    </message>
+    <message>
+        <source>CV_CHAIN_APPROX_TC89_KCOS</source>
+        <translation type="unfinished">TC89 KCOS</translation>
+    </message>
+    <message>
+        <source>CV_CHAIN_APPROX_TC89_L1</source>
+        <translation type="unfinished">TC89 L1</translation>
+    </message>
 </context>
 <context>
     <name>EntityGUI_PictureImportDlg</name>