]> SALOME platform Git repositories - modules/gui.git/commitdiff
Salome HOME
rnc : previous work
authorgdd <gdd>
Tue, 13 Sep 2011 13:07:00 +0000 (13:07 +0000)
committergdd <gdd>
Tue, 13 Sep 2011 13:07:00 +0000 (13:07 +0000)
src/OCCViewer/OCCViewer_FeatureDetector.cxx [new file with mode: 0644]
src/OCCViewer/OCCViewer_FeatureDetector.h [new file with mode: 0644]

diff --git a/src/OCCViewer/OCCViewer_FeatureDetector.cxx b/src/OCCViewer/OCCViewer_FeatureDetector.cxx
new file mode 100644 (file)
index 0000000..6f70d85
--- /dev/null
@@ -0,0 +1,214 @@
+// Copyright (C) 2007-2011  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+
+// File   : OCCViewer_FeatureDetector.cxx
+// Author : Renaud NEDELEC, Open CASCADE S.A.S.
+
+#include "OCCViewer_FeatureDetector.h"
+#include <stdio.h>
+#include "utilities.h"
+
+using namespace cv;
+
+/*!
+  Constructor
+  \param theFilename - image to process
+*/
+OCCViewer_FeatureDetector::OCCViewer_FeatureDetector(const QString& theFilename): 
+  corners()
+{
+  cornerCount = 2000;
+  rect=cvRect(0,0,0,0);
+  imagePath = theFilename.toStdString();
+  // Store the dimensions of the picture
+  IplImage* bg_img = cvLoadImage (imagePath.c_str(), CV_LOAD_IMAGE_GRAYSCALE);
+  imgHeight = bg_img->height;
+  imgWidth  = bg_img->width; 
+}
+
+/*!
+  Computes the corners of the image located at imagePath
+*/
+void OCCViewer_FeatureDetector::ComputeCorners(){
+  
+  // Parameters for the corner detection
+  double qualityLevel = 0.2;
+  double minDistance = 1;
+  // Images to be used for detection
+  IplImage *eig_img, *temp_img, *src_img_gray;
+  
+  // Load image
+  src_img_gray = cvLoadImage (imagePath.c_str(), CV_LOAD_IMAGE_GRAYSCALE);
+  
+  if ( rect.width > 1 )
+  {
+    // If a ROI as been set use it for detection
+    cvSetImageROI( src_img_gray, rect );
+  }
+  
+  eig_img = cvCreateImage (cvGetSize (src_img_gray), IPL_DEPTH_32F, 1);
+  temp_img = cvCreateImage (cvGetSize (src_img_gray), IPL_DEPTH_32F, 1);
+  corners = (CvPoint2D32f *) cvAlloc (cornerCount * sizeof (CvPoint2D32f));
+  
+  // image height and width
+  imgHeight = src_img_gray->height;
+  imgWidth  = src_img_gray->width;
+
+  // Corner detection using cvCornerMinEigenVal 
+  // (one of the methods available inOpenCV, there is also a cvConerHarris method that can be used by setting a flag in cvGoodFeaturesToTrack)
+  cvGoodFeaturesToTrack (src_img_gray, eig_img, temp_img, corners, &cornerCount, /*quality-level=*/qualityLevel, /*min-distance=*/minDistance);
+  cvFindCornerSubPix (src_img_gray, corners, cornerCount,
+                    cvSize (3, 3), cvSize (-1, -1), cvTermCriteria (CV_TERMCRIT_ITER | CV_TERMCRIT_EPS, 20, 0.03));
+
+  cvReleaseImage (&eig_img);
+  cvReleaseImage (&temp_img);
+  cvReleaseImage (&src_img_gray);
+
+}
+
+/*!
+  Computes the contours of the image located at imagePath
+*/
+bool OCCViewer_FeatureDetector::ComputeContours(){
+  // Initialising images
+  Mat src, src_gray;
+  Mat detected_edges;
+
+  /* TEST inutile si partie du bas commentée
+  int lowThreshold = 100;
+  int ratio = 3;
+  int kernel_size = 3;
+  */
+  
+  if (rect.width > 1)
+    src = _colorFiltering();
+  else
+  {
+    src = imread( imagePath.c_str() );
+  }
+
+  if( !src.data )
+  { return false; }
+
+  // Convert the image to grayscale
+  if (src.channels() == 3)
+    cvtColor( src, src_gray, CV_BGR2GRAY );
+  else if (src.channels() == 1)
+    src_gray = src;
+
+  /* TEST commenté pour le moment mais peut servir dans certains cas
+  // Reduce noise with a kernel 3x3               
+  blur( src_gray, detected_edges, Size(3,3) );
+
+  // Canny detector
+  Canny( detected_edges, detected_edges, lowThreshold, lowThreshold*ratio, kernel_size );    // The problem is that with that filter the detector detects dobble contours
+  
+  // Retrieve contours on the Canny result
+  _detectAndRetrieveContours( detected_edges );
+  */
+  
+    _detectAndRetrieveContours( src_gray );
+
+  return true;
+  
+}
+
+/*!
+  Stores a regio of interest given by user in rect
+  \param theRect - Region Of Interest of the image located at imagePath 
+*/
+void OCCViewer_FeatureDetector::SetROI( const QRect& theRect )
+{
+  if (!theRect.isEmpty()){
+    rect = cvRect(theRect.x(),theRect.y(),theRect.width(),theRect.height());
+  }
+}
+
+/*!
+  Performs contours detection and store them in contours 
+  \param src - src image to find contours of 
+*/
+void OCCViewer_FeatureDetector::_detectAndRetrieveContours( Mat src )
+{
+  src = src > 1;  
+  findContours( src, contours, hierarchy,CV_RETR_CCOMP, CV_CHAIN_APPROX_TC89_KCOS);
+  // Other possible approximations CV_CHAIN_APPROX_TC89_L1, CV_CHAIN_APPROX_SIMPLE cf. OpenCV documentation 
+  // for precise information
+}
+
+/*!
+  Performs color filtering from the image sample contained in the ROI rect of the image 
+  located at imagePath
+  Thresholds the result in order ot obtain a binary image
+  \return binary image resulting from filtering and thersholding
+*/
+Mat OCCViewer_FeatureDetector::_colorFiltering()
+{  
+  IplImage* find_image = cvLoadImage(imagePath.c_str(),CV_LOAD_IMAGE_COLOR);
+  if ( !rect.width > 1 )
+    return Mat(find_image);
+  
+  // Crop the image to build an histogram from the selected part
+  cvSetImageROI(find_image, rect);
+  IplImage* test_image = cvCreateImage(cvGetSize(find_image),
+                                      find_image->depth,
+                                      find_image->nChannels);
+  cvCopy(find_image, test_image, NULL);
+  cvResetImageROI(find_image);
+  
+  IplImage* test_hsv = cvCreateImage(cvGetSize(test_image),8,3);
+  IplImage* test_hue = cvCreateImage(cvGetSize(test_image),8,1);
+
+  CvHistogram* hist;
+
+  cvCvtColor(test_image, test_hsv, CV_BGR2HSV);
+  cvCvtPixToPlane(test_hsv, test_hue, 0, 0, 0);
+  
+  //create hist
+  int size_hist = 10;
+  float hranges[] = {0, 180};
+  float* ranges = hranges;
+  hist = cvCreateHist(1, &size_hist, CV_HIST_ARRAY, &ranges, 1);
+  
+  //calculate hue` histogram
+  cvCalcHist(&test_hue, hist, 0 ,0);
+
+  //calculate back projection of hue plane of input image
+  IplImage* backproject = cvCreateImage(cvGetSize(find_image), 8, 1);
+  IplImage* binary_backproject = cvCreateImage(cvGetSize(find_image), 8, 1);
+  IplImage* find_hsv = cvCreateImage(cvGetSize(find_image),8,3);
+  IplImage* find_hue = cvCreateImage(cvGetSize(find_image),8,1);
+  
+  cvCvtColor(find_image, find_hsv, CV_BGR2HSV);
+  cvCvtPixToPlane(find_hsv, find_hue, 0, 0, 0);
+  cvCalcBackProject(&find_hue, backproject, hist);
+  
+  // Threshold in order to obtain binary image
+  cvThreshold(backproject, binary_backproject, 1, 255, CV_THRESH_BINARY);  // NOTE it would be good to think about the best threshold to use (1 here)
+  cvReleaseImage(&test_image);
+  cvReleaseImage(&test_hsv);
+  cvReleaseImage(&test_hue);
+  cvReleaseImage(&backproject);
+  
+  return Mat(binary_backproject);
+}
diff --git a/src/OCCViewer/OCCViewer_FeatureDetector.h b/src/OCCViewer/OCCViewer_FeatureDetector.h
new file mode 100644 (file)
index 0000000..b05e526
--- /dev/null
@@ -0,0 +1,70 @@
+// Copyright (C) 2007-2011  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+
+// File   : OCCViewer_FeatureDetector.h
+// Author : Renaud NEDELEC, Open CASCADE S.A.S.
+
+// OpenCV includes
+#include <cv.h>
+#include <highgui.h>
+#include "opencv2/imgproc/imgproc.hpp"
+#include "opencv2/highgui/highgui.hpp"
+
+// Qt
+#include <QString>
+#include <QRect>
+
+class OCCViewer_FeatureDetector
+{
+public:
+  
+  typedef std::vector<cv::Point>               CvContour;
+  typedef std::vector<std::vector<cv::Point> > CvContoursArray;
+  
+  OCCViewer_FeatureDetector( const QString& );                           // Constructor
+  
+  void                    ComputeCorners();                              // Detects the corners from the image located at imagePath
+  bool                    ComputeContours();                             // Detects the corners from the image located at imagePath
+  
+  void                    SetROI( const QRect& );                        // Sets a Region Of Interest in the image
+  CvPoint2D32f*           GetCorners()           { return corners;     };
+  CvContoursArray         GetContours()          { return contours;    };
+  std::vector<cv::Vec4i>  GetContoursHierarchy() { return hierarchy;   };
+  int                     GetCornerCount()       { return cornerCount; };
+  int                     GetImgHeight()         { return imgHeight;   };
+  int                     GetImgWidth()          { return imgWidth;    };
+  
+  
+private:
+  std::string             imagePath;
+  
+  CvPoint2D32f*           corners;
+  int                     cornerCount;
+  
+  CvContoursArray         contours;
+  std::vector<cv::Vec4i>  hierarchy;
+  int                     imgHeight;
+  int                     imgWidth; 
+  CvRect                  rect;
+  
+  void                    _detectAndRetrieveContours( cv::Mat binaryImg );
+  cv::Mat                 _colorFiltering();
+};