Browse Source

erics edits added

Bjoern Froehlich 13 năm trước cách đây
mục cha
commit
2f73010a7a

+ 163 - 163
features/localfeatures/LFColorWeijer.h

@@ -1,4 +1,4 @@
-/** 
+/**
  * @file LFColorWeijer.cpp
  * @brief implementation of the color features mentioned in van de Weijer, J. & Schmid, C. Applying Color Names to Image Description (2007)
  * @author Björn Fröhlich
@@ -23,168 +23,168 @@ namespace OBJREC {
 class LFColorWeijer : public LocalFeature
 {
 
-    protected:
-		//! enum for 11 main colors
-		enum 
-		{
-			BLACK = 0,
-			BLUE,
-			BROWN,
-			GREY,
-			GREEN,
-			ORANGE,
-			PINK,
-			PURPLE,
-			RED,
-			WHITE,
-			YELLOW,
-			LASTCOLOR
-		};
-		
-		//! bins for L*, a* and b* chanel of L*a*b*
-		int bin[3];
-
-		//! upper limits for L*, a* and b* chanel of L*a*b*
-		double maxv[3];
-		
-		//! lower limits for L*, a* and b* chanel of L*a*b*
-		double minv[3];
-		
-		//! quantization interval for L*, a* and b* chanel of L*a*b* depending on bin, maxv and minv
-		double interval[3];
-		
-		//! destination of the computed lookuptable
-		std::string tfile;
-		
-		//! lookuptable for the probabilities (4d: colors, L-channel, a-channel, b-channel)
-		std::vector<std::vector<std::vector<std::vector<double> > > > hist;
-		
-		//! configuration file
-		const NICE::Config *conf;
-		
-    public:
-  
-		/** simple constructor */
-		LFColorWeijer( const NICE::Config *c);
-		  
-		/** simple destructor */
-		virtual ~LFColorWeijer();
-		
-		/**
-		 * get the size of the descriptor
-		 * @return size of descriptor
-		 */
-		int getDescSize () const;
-		
-		/**
-		 * get the colorWeijer features
-		 * @param img grayvalue input image
-		 * @param features features (output)
-		 * @param positions position of the features
-		 * @return 
-		 */
-		int getDescriptors ( const NICE::Image & img, NICE::VVector & positions, NICE::VVector & features ) const;
-		
-		/**
-		 * get the colorWeijer features
-		 * @param img color input image
-		 * @param features features (output)
-		 * @param positions given positions of the features
-		 * @return 
-		 */
-		int getDescriptors ( const NICE::ColorImage & img, NICE::VVector & positions, NICE::VVector & features ) const;
-		
-		/**
-		 * visualize the features
-		 * @param mark 
-		 * @param positions 
-		 * @param color 
-		 */
-		void visualizeFeatures ( NICE::Image & mark, const NICE::VVector & positions,	size_t color ) const;
-		
-		/**
-		 * visualize the features
-		 * @param mark 
-		 * @param positions 
-		 * @param color 
-		 */
-		void visualizeFeatures ( NICE::ColorImage & mark, const NICE::VVector & features, const NICE::VVector & position ) const;
-		
-		/**
-		 * visualize the features
-		 * @param cimg 
-		 */
-		void visualizeFeatures ( const NICE::ColorImage & cimg) const;
-		
-		/**
-		 * visualize the features
-		 * @param cimg 
-		 * @param out
-		 */
-		void visualizeFeatures ( const NICE::ColorImage & cimg, NICE::ColorImage & out) const;
-		
-		/**
-		 * save parameters
-		 */
-		void store();
-		
-		
-		/**
-		 * load parameters
-		 */
-		void restore();
-		
-		/**
-		 * smooths the look up table
-		 */
-		void smooth();
-		
-		/**
-		 * normalizes the sum of a 3d histogram to 1
-		 * @param tab 3d histogram
-		 */
-		void normalize(std::vector<std::vector<std::vector<double> > > &tab);
-		
-		/**
-		 * creates a new and empty table
-		 * @return table of the size bin[0]xbin[1]xbin[2]
-		 */
-		std::vector<std::vector<std::vector<double > > > createTable();
-		
-		/**
-		 * finds a colorname in a given string
-		 * @param fn input string
-		 * @return number of the color
-		 */
-		int findColor(std::string &fn);
-		
-		/**
-		 * creates a new Histogram for input image depending on the image mask
-		 * @param cimg input image
-		 * @param hist histogram
-		 * @param mask which pixel should be consider
-		 */
-		void createHist(const NICE::ColorImage &cimg, std::vector<std::vector<std::vector<double> > > &hist, NICE::Image &mask);
-		
-		/**
-		 * train the lookuptable
-		 */
-		void train();
-		
-		
-		/**
-		 * add a 3d table to a 3d table elementwise
-		 * @param dest destination table
-		 * @param src source table
-		 */
-		void add(std::vector<std::vector<std::vector<double> > > &dest, std::vector<std::vector<std::vector<double> > > &src);
-		
-		/**
-		 * transform each pixel of an image
-		 * @param img input image
-		 * @param feats feature vector for each pixel
-		 */
-		void getFeats(const NICE::ColorImage &img, NICE::MultiChannelImageT<double> &feats);
+  protected:
+    //! enum for 11 main colors
+    enum
+    {
+      BLACK = 0,
+      BLUE,
+      BROWN,
+      GREY,
+      GREEN,
+      ORANGE,
+      PINK,
+      PURPLE,
+      RED,
+      WHITE,
+      YELLOW,
+      LASTCOLOR
+    };
+
+    //! bins for L*, a* and b* chanel of L*a*b*
+    int bin[3];
+
+    //! upper limits for L*, a* and b* chanel of L*a*b*
+    double maxv[3];
+
+    //! lower limits for L*, a* and b* chanel of L*a*b*
+    double minv[3];
+
+    //! quantization interval for L*, a* and b* chanel of L*a*b* depending on bin, maxv and minv
+    double interval[3];
+
+    //! destination of the computed lookuptable
+    std::string tfile;
+
+    //! lookuptable for the probabilities (4d: colors, L-channel, a-channel, b-channel)
+    std::vector<std::vector<std::vector<std::vector<double> > > > hist;
+
+    //! configuration file
+    const NICE::Config *conf;
+
+  public:
+
+    /** simple constructor */
+    LFColorWeijer ( const NICE::Config *c );
+
+    /** simple destructor */
+    virtual ~LFColorWeijer();
+
+    /**
+     * get the size of the descriptor
+     * @return size of descriptor
+     */
+    int getDescSize () const;
+
+    /**
+     * get the colorWeijer features
+     * @param img grayvalue input image
+     * @param features features (output)
+     * @param positions position of the features
+     * @return
+     */
+    int getDescriptors ( const NICE::Image & img, NICE::VVector & positions, NICE::VVector & features ) const;
+
+    /**
+     * get the colorWeijer features
+     * @param img color input image
+     * @param features features (output)
+     * @param positions given positions of the features
+     * @return
+     */
+    int getDescriptors ( const NICE::ColorImage & img, NICE::VVector & positions, NICE::VVector & features ) const;
+
+    /**
+     * visualize the features
+     * @param mark
+     * @param positions
+     * @param color
+     */
+    void visualizeFeatures ( NICE::Image & mark, const NICE::VVector & positions, size_t color ) const;
+
+    /**
+     * visualize the features
+     * @param mark
+     * @param positions
+     * @param color
+     */
+    void visualizeFeatures ( NICE::ColorImage & mark, const NICE::VVector & features, const NICE::VVector & position ) const;
+
+    /**
+     * visualize the features
+     * @param cimg
+     */
+    void visualizeFeatures ( const NICE::ColorImage & cimg ) const;
+
+    /**
+     * visualize the features
+     * @param cimg
+     * @param out
+     */
+    void visualizeFeatures ( const NICE::ColorImage & cimg, NICE::ColorImage & out ) const;
+
+    /**
+     * save parameters
+     */
+    void store();
+
+
+    /**
+     * load parameters
+     */
+    void restore();
+
+    /**
+     * smooths the look up table
+     */
+    void smooth();
+
+    /**
+     * normalizes the sum of a 3d histogram to 1
+     * @param tab 3d histogram
+     */
+    void normalize ( std::vector<std::vector<std::vector<double> > > &tab );
+
+    /**
+     * creates a new and empty table
+     * @return table of the size bin[0]xbin[1]xbin[2]
+     */
+    std::vector<std::vector<std::vector<double > > > createTable();
+
+    /**
+     * finds a colorname in a given string
+     * @param fn input string
+     * @return number of the color
+     */
+    int findColor ( std::string &fn );
+
+    /**
+     * creates a new Histogram for input image depending on the image mask
+     * @param cimg input image
+     * @param hist histogram
+     * @param mask which pixel should be consider
+     */
+    void createHist ( const NICE::ColorImage &cimg, std::vector<std::vector<std::vector<double> > > &hist, NICE::Image &mask );
+
+    /**
+     * train the lookuptable
+     */
+    void train();
+
+
+    /**
+     * add a 3d table to a 3d table elementwise
+     * @param dest destination table
+     * @param src source table
+     */
+    void add ( std::vector<std::vector<std::vector<double> > > &dest, std::vector<std::vector<std::vector<double> > > &src );
+
+    /**
+     * transform each pixel of an image
+     * @param img input image
+     * @param feats feature vector for each pixel
+     */
+    void getFeats ( const NICE::ColorImage &img, NICE::MultiChannelImageT<double> &feats );
 };
 
 

+ 33 - 46
features/localfeatures/LFonHSG.cpp

@@ -6,29 +6,32 @@
 */
 
 /* LocalFeatureHSG Include */
-
 #include "vislearning/features/localfeatures/LFonHSG.h"
 
-using namespace OBJREC;
-using namespace NICE;
 using namespace std;
+using namespace NICE;
+using namespace OBJREC;
+
+#ifdef NICE_USELIB_BOOST
+using namespace boost;
+#endif
 
-LFonHSG::LFonHSG ( const Config *conf, const string section )
+LFonHSG::LFonHSG (const Config *conf, const string section)
 {
   /** initialization **/
   this->lf = NULL;
 
   /** get parameters for the grid **/
-  sampleScaling    = conf->gI ( section, "sample_scaling", 50 );
-  scales   = conf->gS ( section, "scales"        , "1" );
+  sampleScaling    = conf->gI (section, "sample_scaling", 50);
+  scales		 = conf->gS (section, "scales"        , "1");
   // the scales are seperated by '+', like in the Van de Sande implementation
   char separator = '+';
 
   /** get debuginformation **/
-  debug    = conf->gB ( "debug", "show_log_HSG", false );
+  debug 		 = conf->gB ("debug", "show_log_HSG", false);
 
   /** generate the descriptor-instanz **/
-  lf = GenericLocalFeatureSelection::selectLocalFeature ( conf, section );
+  lf = GenericLocalFeatureSelection::selectLocalFeature (conf, section);
 
   /** parse scales string **/
   debug && clog << "[log] LocalFeatureHSG::LocalFeatureHSG" << endl;
@@ -36,20 +39,19 @@ LFonHSG::LFonHSG ( const Config *conf, const string section )
 
 #ifdef NICE_USELIB_BOOST
   typedef tokenizer<boost::char_separator<char> > tokenizer;
-  char_separator<char> sep ( separator );
-  tokenizer tokens ( scales, sep );  // parse the string into tokens
-  for ( tokenizer::iterator tok_iter = tokens.begin(); tok_iter != tokens.end(); ++tok_iter )
-  {
+  char_separator<char> sep (separator);
+  tokenizer tokens (scales, sep);		// parse the string into tokens
+  for (tokenizer::iterator tok_iter = tokens.begin(); tok_iter != tokens.end(); ++tok_iter) {
     debug && clog << *tok_iter << " ";
-    scalesV.push_back ( strToFloat ( *tok_iter ) );
+    scalesV.push_back(StringTools::convert<float>(*tok_iter));
   }
 #else // standard
   vector<string> temp;
-  StringTools::split ( scales, separator, temp );
-  for ( vector<string>::const_iterator it = temp.begin(); it != temp.end(); ++it )
-  {
+  StringTools::split (scales, separator, temp);
+  for (vector<string>::const_iterator it = temp.begin(); it != temp.end(); ++it) {
     debug && clog << *it << " ";
-    scalesV.push_back ( strToFloat ( *it ) );
+    scalesV.push_back(StringTools::convert<float>(*it));
+    //scalesV.push_back (strToFloat (*it));
   }
 #endif
   debug && clog << endl;
@@ -60,9 +62,9 @@ LFonHSG::~LFonHSG()
   /** free memory of descriptors **/
 }
 
-void LFonHSG::getPositionsOnHSG ( const unsigned int imageWidth, const unsigned int imageHeight, VVector& positions ) const
+void LFonHSG::getPositionsOnHSG (const unsigned int imageWidth, const unsigned int imageHeight, VVector& positions) const
 {
-  if ( sampleScaling < 1 ) {
+  if (sampleScaling < 1) {
     cerr << "[err] sample-scaling (" << sampleScaling << ") musst be larger the 0!" << endl;
     return;
   }
@@ -70,64 +72,49 @@ void LFonHSG::getPositionsOnHSG ( const unsigned int imageWidth, const unsigned
   debug && clog << "[log] LocalFeatureHSG::getPositionsOnHSG calculate ";
 
   bool oddRow = true;
-  NICE::Vector pos ( 4 );
+  NICE::Vector pos (4);
 
   /** we have to calculate the koo. for every different scale **/
-  for ( vector <float>::const_iterator it = scalesV.begin(); it != scalesV.end(); ++it )
-  {
+  for (vector <float>::const_iterator it = scalesV.begin(); it != scalesV.end(); ++it) {
     oddRow = true;
 
-    for ( unsigned int j = sampleScaling; j <= ( imageHeight - sampleScaling ); j += sampleScaling )
-    {
-      for ( unsigned int i = ( oddRow ? sampleScaling + sampleScaling / 2 : sampleScaling ); i <= ( imageWidth - sampleScaling ); i += sampleScaling )
-      {
+    for (unsigned int j = sampleScaling; j <= (imageHeight - sampleScaling); j += sampleScaling) {
+      for (unsigned int i = (oddRow ? sampleScaling + sampleScaling / 2 : sampleScaling); i <= (imageWidth - sampleScaling); i += sampleScaling) {
         pos[ 0] = i;
         pos[ 1] = j;
         pos[ 2] = *it;
         pos[ 3] = 0;
-        positions.push_back ( pos );
+        positions.push_back (pos);
       }
       oddRow = !oddRow;
     }
   }
 }
 
-int LFonHSG::extractFeatures ( const NICE::ColorImage & cimg, VVector & features, VVector & positions ) const
+int LFonHSG::extractFeatures (const NICE::ColorImage & cimg, VVector & features, VVector & positions) const
 {
   /** To get the keypoint descriptor, we need the positions of the keypoints. **/
-  getPositionsOnHSG ( cimg.width(), cimg.height(), positions );
+  getPositionsOnHSG (cimg.width(), cimg.height(), positions);
 
   /** calulate the descriptor-values **/
-  return lf->getDescriptors ( cimg, positions, features );
+  return lf->getDescriptors (cimg, positions, features);
 }
 
 
-int LFonHSG::extractFeatures ( const NICE::Image & img, VVector & features, VVector & positions ) const
+int LFonHSG::extractFeatures (const NICE::Image & img, VVector & features, VVector & positions) const
 {
   /** To get the keypoint descriptor, we need the positions of the keypoints. **/
-  getPositionsOnHSG ( img.width(), img.height(), positions );
+  getPositionsOnHSG (img.width(), img.height(), positions);
 
   /** calculate the descriptor-values **/
-  return lf->getDescriptors ( img, positions, features );
+  return lf->getDescriptors (img, positions, features);
 }
 
-void LFonHSG::visualizeFeatures ( NICE::Image & mark, const VVector & positions, size_t color ) const
+void LFonHSG::visualizeFeatures (NICE::Image & mark, const VVector & positions, size_t color) const
 {
   // TODO: Implementierung des gewaehlten Descriptortyps aufrufen.
 }
 
-float LFonHSG::strToFloat ( const string str ) const
-{
-  float temp;
-
-  stringstream ss;
-  ss << str;
-  ss >> temp;
-
-  return temp;
-}
-
-
 
 
 

+ 66 - 65
features/localfeatures/LocalFeatureRGBSift.cpp

@@ -11,81 +11,82 @@ using namespace OBJREC;
 using namespace std;
 using namespace NICE;
 
-#undef DEBUG_show_one_picture_per_channel
 
-LocalFeatureRGBSift::LocalFeatureRGBSift( const Config *conf ):LocalFeatureSift(conf)
+LocalFeatureRGBSift::LocalFeatureRGBSift (const Config *conf) : LocalFeatureSift (conf)
 {
-    deletemode = false;
+  deletemode = false;
 }
 
 LocalFeatureRGBSift::~LocalFeatureRGBSift()
 {
-	
+
 }
 
-int LocalFeatureRGBSift::getDescriptors ( const NICE::ColorImage & img, 
-				     VVector & positions,
-				     VVector & descriptors ) const
+int LocalFeatureRGBSift::getDescriptors (const NICE::ColorImage & img,
+    VVector & positions,
+    VVector & descriptors) const
 {
-	sortPositions(positions);
-	descriptors.clear();
-	// Fuer jede Position wird ein leerer NICE::Vector in descriptors eingefuegt
-	for(int i = 0; i < (int) positions.size(); i++)
-	{
-		NICE::Vector v;
-		descriptors.push_back(v);
-	}
-	
-	vector<VVector> desc( 3 );
-#ifndef DEBUG_show_one_picture_per_channel
+  sortPositions (positions);
+  descriptors.clear();
+  // Fuer jede Position wird ein leerer NICE::Vector in descriptors eingefuegt
+  for (int i = 0; i < (int) positions.size(); i++) {
+    NICE::Vector v;
+    descriptors.push_back (v);
+  }
+
+  vector<VVector> desc (3);
+
+  // Maximale Anzahl an Thread ist abhaengig von der Anzahl der verfuegbaren Grafikkarten
+  // bzw. (wenn siftGPU nicht genutzt wird) von der Anzahl der Prozessoren
+  const int numberOfGPU = getNumOfDevices();
+  const int numberOfCPU = omp_get_num_procs();
+
+  if (numberOfGPU == -1) { // siftGPU wird nicht genutzt
+    omp_set_num_threads (numberOfCPU);
+  }
+  else if (numberOfGPU == 0) {
+    fthrow (Exception, "No Devices");
+  }
+  else { // siftGPU wird genutzt: LocalFeatureSiftGPU kuemmert sich um die threads.
+    omp_set_num_threads (numberOfGPU);
+  }
+
 #pragma omp parallel for
-#endif
-	// Descriptor fuer jeden der 3 Kanaele berechnen
-	for(int i = 0; i < 3; i++)
-	{
-		NICE::Image tmp(img.width(), img.height());
-
-		for(int y = 0; y < img.height(); y++)
-		{
-			for(int x = 0; x < img.width(); x++)
-			{
-				tmp.setPixel(x,y,img.getPixel(x,y,i));
-			}
-		}
-#ifdef DEBUG_show_one_picture_per_channel
-		showImage( tmp );
-#endif
-		VVector pos = positions;
-		computeDesc(tmp, pos, desc[i]);
-	}
-	// ?
-	//desc[0] = desc[2];
-	for(int i = 0; i < 3; i++)
-	{
-		assert(desc[i].size() == descriptors.size());
-		
-		if(i == 0)
-		{
-#ifndef DEBUG_show_one_picture_per_channel
+  // Descriptor fuer jeden der 3 Kanaele berechnen
+  for (int i = 0; i < 3; i++) {
+    NICE::Image tmp (img.width(), img.height());
+
+    for (int y = 0; y < img.height(); y++) {
+      for (int x = 0; x < img.width(); x++) {
+        tmp.setPixel (x, y, img.getPixel (x, y, i));
+      }
+    }
+    VVector pos = positions;
+    computeDesc (tmp, pos, desc[i]);
+  }
+
+  // ab hier stehen wird nur noch mit dem Prozessor gerechnet
+  omp_set_num_threads (numberOfCPU);
+
+  // ?
+  //desc[0] = desc[2];
+  for (int i = 0; i < 3; i++) {
+    assert (desc[i].size() == descriptors.size());
+
+    if (i == 0) {
 #pragma omp parallel for
-#endif
-			for(int j = 0; j < (int)desc[i].size(); j++)
-			{
-				// kopiere den roten (1.)-Kanal in den Descriptorsvektor
-				descriptors[j] = desc[i][j];
-			}
-		}
-		else
-		{
-#ifndef DEBUG_show_one_picture_per_channel
+      for (int j = 0; j < (int) desc[i].size(); j++) {
+        // kopiere den roten (1.)-Kanal in den Descriptorsvektor
+        descriptors[j] = desc[i][j];
+      }
+    }
+    else {
 #pragma omp parallel for
-#endif
-			for(int j = 0; j < (int)desc[i].size(); j++)
-			{
-				descriptors[j].append(desc[i][j]);
-			}
-		}
-	}
-	
-	return positions.size();
+      for (int j = 0; j < (int) desc[i].size(); j++) {
+        descriptors[j].append (desc[i][j]);
+      }
+    }
+  }
+
+  return positions.size();
 }

+ 35 - 33
features/localfeatures/LocalFeatureRGBSift.h

@@ -1,4 +1,4 @@
-/** 
+/**
 * @file LocalFeatureRGBSift.h
 * @brief local feature with color sift
 * @author Björn Fröhlich
@@ -22,38 +22,40 @@ namespace OBJREC {
 class LocalFeatureRGBSift : public LocalFeatureSift
 {
 
-    protected:
-	int octaves;
-	int levels;
-	bool normalizeFeature;
-	int first_octave;
-	double magnif;
-
-    public:
-  
-	/** simple constructor */
-	LocalFeatureRGBSift ( const NICE::Config *conf );
-      
-	/** simple destructor */
-
-	virtual ~LocalFeatureRGBSift();
-	
-	/**
-	 * returns the size of each the SIFT-Feature
-	 * @return 128
-	 */
-	int getDescSize() const { return 384; };
-	
-	/** 
-	 * get the descriptor
-	 * @param img input color image
-	 * @param positions positions for the SIFT features
-	 * @param descriptors output
-	 * @return 0
-	 */
-	virtual int getDescriptors ( const NICE::ColorImage & cimg, 
-			     NICE::VVector & positions,
-			     NICE::VVector & descriptors ) const;     
+  protected:
+    int octaves;
+    int levels;
+    bool normalizeFeature;
+    int first_octave;
+    double magnif;
+
+  public:
+
+    /** simple constructor */
+    LocalFeatureRGBSift ( const NICE::Config *conf );
+
+    /** simple destructor */
+
+    virtual ~LocalFeatureRGBSift();
+
+    /**
+     * returns the size of each the SIFT-Feature
+     * @return 128
+     */
+    int getDescSize() const {
+      return 384;
+    };
+
+    /**
+     * get the descriptor
+     * @param img input color image
+     * @param positions positions for the SIFT features
+     * @param descriptors output
+     * @return 0
+     */
+    virtual int getDescriptors ( const NICE::ColorImage & cimg,
+                                 NICE::VVector & positions,
+                                 NICE::VVector & descriptors ) const;
 };
 
 

+ 191 - 186
features/localfeatures/LocalFeatureSift.cpp

@@ -1,220 +1,225 @@
-/** 
+/**
 * @file LocalFeatureSift.cpp
 * @brief local feature with sift
 * @author Erik Rodner
 * @date 02/05/2008
 */
-// #ifdef NICE_USELIB_ICE
-//   #include <image_nonvis.h>
-// #endif
 #include <iostream>
 
-#include "core/basics/Exception.h"
-
 #include "vislearning/features/localfeatures/sift.h"
 #include "vislearning/features/localfeatures/LocalFeatureSift.h"
+#include "LocalFeatureSiftGPU.h"
+
 
 using namespace OBJREC;
 using namespace std;
 using namespace NICE;
 
-LocalFeatureSift::LocalFeatureSift( const Config *conf )
+LocalFeatureSift::LocalFeatureSift ( const Config *conf )
 {
-    octaves          = conf->gI("LFSiftPP", "octaves", 			6);
-    levels           = conf->gI("LFSiftPP", "levels", 			3);
-    first_octave     = conf->gI("LFSiftPP", "first_octave", 		-1);
-    normalizeFeature = conf->gB("LFSiftPP", "normalize_feature", 	true );
-    magnif 	     = conf->gD("LFSiftPP", "magnif", 			3 );
-    deletemode       = conf->gB("LFSiftPP", "deletemode", 		true );	
-    integerValues    = conf->gB("LFSiftPP", "integer_values", 		true );
+  this->conf = conf;
+
+  octaves          = conf->gI ( "LFSiftPP", "octaves",    6 );
+  levels           = conf->gI ( "LFSiftPP", "levels",    3 );
+  first_octave     = conf->gI ( "LFSiftPP", "first_octave",   -1 );
+  normalizeFeature = conf->gB ( "LFSiftPP", "normalize_feature",  true );
+  magnif       = conf->gD ( "LFSiftPP", "magnif",    3 );
+  deletemode       = conf->gB ( "LFSiftPP", "deletemode",   true );
+  integerValues    = conf->gB ( "LFSiftPP", "integer_values",   true );
+  usegpu       = conf->gB ( "LFSiftPP", "use_siftgpu",  false );
+
+  if ( usegpu ) numOfGPU = conf->gI ( "SIFTGPU", "numgpu", 1 );
+  else numOfGPU = -1;
 }
 
 LocalFeatureSift::~LocalFeatureSift()
 {
 }
 
-void LocalFeatureSift::sortPositions(VVector & positions) const
+void LocalFeatureSift::sortPositions ( VVector & positions ) const
 {
-	// < Key  , Val >
-	map<double, bool> scales;
-
-	// in der Map entpsrechende Skalewerte auf true setzten, jeder Skalewert ist dabei einzigartig
-	for( vector< NICE::Vector >::iterator i  = positions.begin(); 
-			i != positions.end();i++)
-	{
-		const NICE::Vector & pos = *i;
-		scales[pos[2]] = true;
-	}
-	
-	VVector newpositions;
-	
-	map<double,bool>::iterator iter;
-	// Map durchlaufen
-	for( iter = scales.begin(); iter != scales.end(); ++iter ) 
-	{
-		// alle Positionen durchlaufen
-		for( vector< NICE::Vector >::iterator i  = positions.begin(); 
-				   i != positions.end();i++)
-		{
-			
-			const NICE::Vector & pos = *i;
-			if(pos[2] == iter->first)
-			{
-				newpositions.push_back(pos);
-			}
-		}
-	}
-	positions = newpositions;
+  // < Key  , Val >
+  map<double, bool> scales;
+
+  // in der Map entpsrechende Skalewerte auf true setzten, jeder Skalewert ist dabei einzigartig
+  for ( vector< NICE::Vector >::iterator i  = positions.begin();
+        i != positions.end();i++ )
+  {
+    const NICE::Vector & pos = *i;
+    scales[pos[2]] = true;
+  }
+
+  VVector newpositions;
+
+  map<double, bool>::iterator iter;
+  // Map durchlaufen
+  for ( iter = scales.begin(); iter != scales.end(); ++iter )
+  {
+    // alle Positionen durchlaufen
+    for ( vector< NICE::Vector >::iterator i  = positions.begin();
+          i != positions.end();i++ )
+    {
+
+      const NICE::Vector & pos = *i;
+      if ( pos[2] == iter->first )
+      {
+        newpositions.push_back ( pos );
+      }
+    }
+  }
+  positions = newpositions;
 }
 
-void LocalFeatureSift::computeDesc( const NICE::Image & img, VVector & positions, VVector & descriptors ) const
+void LocalFeatureSift::computeDesc ( const NICE::Image & img, VVector & positions, VVector & descriptors ) const
 {
-	
-	int         O      = octaves ;
-	int const   S      = levels ;
-	int const   omin   = first_octave;
-	float const sigman = .5 ; //.5
-	float const sigma0 = 1.6 * powf(2.0f, 1.0f / S) ;
-
-	if (O < 1) 
-	{
-		O = std::max(int(std::floor(log2
-				(std::min(img.width(),img.height()))) - omin - 3), 1) ;
-	}
-	
-	const unsigned char *blockimg = (unsigned char*) img.getPixelPointer();
-	float *blockimgfl = new float[img.width() * img.height()];
-	for ( int k = 0 ; k < img.width() * img.height() ; k++ )
-		blockimgfl[k] = blockimg[k];
-
-	VL::Sift sift( blockimgfl, img.width(), img.height(),
-				   sigman, sigma0, O, S, omin, -1, S+1) ;
-
-	sift.process ( blockimgfl, img.width(), img.height() );
-
-	sift.setMagnification ( magnif );
-	sift.setNormalizeDescriptor ( normalizeFeature );
-
-	const int descr_size = 128;
-	VL::float_t *descr_pt = new VL::float_t [descr_size];
-	VL::float_t angles[4] ;
-
-	NICE::Vector feature (descr_size);
-	NICE::Vector pos     ( 4 );
-
-
-	for( vector< NICE::Vector >::iterator i  = positions.begin(); 
-			i != positions.end();)
-	{
-		const NICE::Vector & pos = *i;
-		double x = pos[0];
-		double y = pos[1];
-		assert(pos[0] < img.width());
-		assert(pos[1] < img.height());
-		double s = pos[2];
-		bool deleteFeature = false;
-		VL::Sift::Keypoint kp = sift.getKeypoint (x,y,s);
-
-		double angle = 0.0;
-
-		if ( pos.size() < 4 ) 
-		{
-			int nangles = sift.computeKeypointOrientations(angles, kp);
-
-			if ( nangles > 0 )
-			{
-				angle = angles[0]; 
-			} 
-			else 
-			{
-				if(deletemode)
-					deleteFeature = true;
-				else
-					angle = 0;
-			}
-		} 
-		else 
-		{
-			angle = pos[3];
-		}
-
-		if ( ! deleteFeature ) 
-		{
-			sift.computeKeypointDescriptor ( descr_pt, kp, angle ); 		
-			for ( int j = 0 ; j < descr_size ; j++ )
-				// Umwandlung in Integer moegl.
-				feature[j] = (integerValues ? (int)(512*descr_pt[j]) : descr_pt[j]);
-
-			descriptors.push_back ( feature );
-
-			i++;
-		} 
-		else 
-		{
-			i = positions.erase(i);
-		}
-	}
-
-	delete [] blockimgfl;
-	delete [] descr_pt;
- 
+  if ( usegpu )
+  {
+    LocalFeatureSiftGPU sift ( conf );
+    sift.computeDesc ( img, positions, descriptors );
+  }
+  else
+  {
+    int         O      = octaves ;
+    int const   S      = levels ;
+    int const   omin   = first_octave;
+    float const sigman = .5 ; //.5
+    float const sigma0 = 1.6 * powf ( 2.0f, 1.0f / S ) ;
+
+    if ( O < 1 )
+    {
+      O = std::max ( int ( std::floor ( log2
+                                        ( std::min ( img.width(), img.height() ) ) ) - omin - 3 ), 1 ) ;
+    }
+
+    const unsigned char *blockimg = ( unsigned char* ) img.getPixelPointer();
+    float *blockimgfl = new float[img.width() * img.height() ];
+    for ( int k = 0 ; k < img.width() * img.height() ; k++ )
+      blockimgfl[k] = blockimg[k];
+
+    VL::Sift sift ( blockimgfl, img.width(), img.height(),
+                    sigman, sigma0, O, S, omin, -1, S + 1 ) ;
+
+    sift.process ( blockimgfl, img.width(), img.height() );
+
+    sift.setMagnification ( magnif );
+    sift.setNormalizeDescriptor ( normalizeFeature );
+
+    const int descr_size = 128;
+    VL::float_t *descr_pt = new VL::float_t [descr_size];
+    VL::float_t angles[4] ;
+
+    NICE::Vector feature ( descr_size );
+    NICE::Vector pos ( 4 );
+
+
+    for ( vector< NICE::Vector >::iterator i  = positions.begin();
+          i != positions.end(); )
+    {
+      const NICE::Vector & pos = *i;
+      double x = pos[0];
+      double y = pos[1];
+      assert ( pos[0] < img.width() );
+      assert ( pos[1] < img.height() );
+      double s = pos[2];
+      bool deleteFeature = false;
+      VL::Sift::Keypoint kp = sift.getKeypoint ( x, y, s );
+
+      double angle = 0.0;
+
+      if ( pos.size() < 4 )
+      {
+        int nangles = sift.computeKeypointOrientations ( angles, kp );
+
+        if ( nangles > 0 )
+        {
+          angle = angles[0];
+        }
+        else
+        {
+          if ( deletemode )
+            deleteFeature = true;
+          else
+            angle = 0;
+        }
+      }
+      else
+      {
+        angle = pos[3];
+      }
+
+      if ( ! deleteFeature )
+      {
+        sift.computeKeypointDescriptor ( descr_pt, kp, angle );
+        for ( int j = 0 ; j < descr_size ; j++ )
+          // Umwandlung in Integer moegl.
+          feature[j] = ( integerValues ? ( int ) ( 512 * descr_pt[j] ) : descr_pt[j] );
+
+        descriptors.push_back ( feature );
+
+        i++;
+      }
+      else
+      {
+        i = positions.erase ( i );
+      }
+    }
+
+    delete [] blockimgfl;
+    delete [] descr_pt;
+  }
 }
 
 int LocalFeatureSift::getDescriptors ( const NICE::Image & img, VVector & positions, VVector & descriptors ) const
 {
-	sortPositions(positions);
-	
-	computeDesc(img, positions, descriptors);
-	
-    return 0;
+  sortPositions ( positions );
+
+  computeDesc ( img, positions, descriptors );
+
+  return 0;
 }
 
 void LocalFeatureSift::visualizeFeatures ( NICE::Image & mark,
-				 const VVector & positions,
-				 size_t color ) const
+    const VVector & positions,
+    size_t color ) const
 {
-	fthrow(Exception, "LocalFeatureSift::visualizeFeatures -- not yet implemented due to old ICE version.");
-//TODO check this!
-// #ifdef NICE_USELIB_ICE
-//     ice::Image mark_ice = ice::NewImg ( mark.width(), 
-// 	mark.height(), 255 );
-//     for ( size_t k = 0 ; k < positions.size() ; k++ )
-//     {
-// 		const NICE::Vector & pos = positions[k];
-// 		ice::Matrix points ( 0, 2 );
-// 		const int size = 6;
-// 		points.Append ( ice::Vector(-size, -size) );
-// 		points.Append ( ice::Vector(-size, size) );
-// 		points.Append ( ice::Vector(size, size) );
-// 		points.Append ( ice::Vector(size, -size) );
-// 
-// 		ice::Trafo tr;
-// 
-// 		tr.Scale ( 0, 0, pos[2] );
-// 		tr.Rotate ( 0, 0, pos[3] );
-// 		tr.Shift ( pos[0], pos[1] );
-// 
-// 		ice::TransformList(tr, points);
-// 
-// 		for ( int j = 0 ; j < points.rows(); j++ )
-// 		{
-// 			if (points[j][0] < 0 ) 
-// 			points[j][0] = 0;
-// 			if (points[j][0] >= mark_ice->xsize) 
-// 			points[j][0] = mark_ice->xsize - 1;
-// 			if (points[j][1] < 0 ) 
-// 			points[j][1] = 0;
-// 			if (points[j][1] >= mark_ice->ysize) 
-// 			points[j][1] = mark_ice->ysize - 1;
-// 		}
-// 		ice::DrawPolygon ( points, color, mark_ice );
-//     }
-// 
-//     for ( unsigned int y = 0 ; y < mark.height(); y++ )
-// 		for ( unsigned int x = 0 ; x < mark.width(); x++ )
-// 			mark.setPixel(x,y, GetVal(mark_ice,x,y));
-// #else
-// 	cerr << "uses ice visualization, please install ice or change to NICE visualization" << endl;
-// #endif
+  /*TODO: switch to NICE instead of ICE
+  ice::Image mark_ice = ice::NewImg ( mark.width(),
+                                      mark.height(), 255 );
+  for ( size_t k = 0 ; k < positions.size() ; k++ )
+  {
+    const NICE::Vector & pos = positions[k];
+    ice::Matrix points ( 0, 2 );
+    const int size = 6;
+    points.Append ( ice::Vector ( -size, -size ) );
+    points.Append ( ice::Vector ( -size, size ) );
+    points.Append ( ice::Vector ( size, size ) );
+    points.Append ( ice::Vector ( size, -size ) );
+
+    ice::Trafo tr;
+
+    tr.Scale ( 0, 0, pos[2] );
+    tr.Rotate ( 0, 0, pos[3] );
+    tr.Shift ( pos[0], pos[1] );
+
+    ice::TransformList ( tr, points );
+
+    for ( int j = 0 ; j < points.rows(); j++ )
+    {
+      if ( points[j][0] < 0 )
+        points[j][0] = 0;
+      if ( points[j][0] >= mark_ice->xsize )
+        points[j][0] = mark_ice->xsize - 1;
+      if ( points[j][1] < 0 )
+        points[j][1] = 0;
+      if ( points[j][1] >= mark_ice->ysize )
+        points[j][1] = mark_ice->ysize - 1;
+    }
+    ice::DrawPolygon ( points, color, mark_ice );
+  }
+
+  for ( unsigned int y = 0 ; y < mark.height(); y++ )
+    for ( unsigned int x = 0 ; x < mark.width(); x++ )
+      mark.setPixel ( x, y, GetVal ( mark_ice, x, y ) );
+    */
+  throw("not yet implemented");
 }
-

+ 84 - 57
features/localfeatures/LocalFeatureSift.h

@@ -1,6 +1,6 @@
-/** 
+/**
 * @file LocalFeatureSift.h
-* @brief local feature with sift (without detector)
+* @brief local feature with sift
 * @author Erik Rodner
 * @date 02/05/2008
 
@@ -13,71 +13,98 @@
 #include "core/image/ImageT.h"
 #include "core/imagedisplay/ImageDisplay.h"
 
+#include "core/basics/Config.h"
+
+// SIFTGPU includes
+#include <src/SiftGPU.h>
+
+// GL includes
+#include <GL/gl.h>
+
 #include "core/basics/Config.h"
 #include "LocalFeature.h"
 
+// GLEW include
+//#include <GL/glew.h>
+
 
 namespace OBJREC {
 
 /** local feature with sift */
 class LocalFeatureSift : public LocalFeature
 {
+  private:
+    const NICE::Config* conf;
+
+  protected:
+    int octaves;
+    int levels;
+    bool normalizeFeature;
+    int first_octave;
+    double magnif;
+    bool deletemode;
+    bool integerValues;
+
+    // for SiftGPU
+    bool usegpu;
+    int numOfGPU;
+
+    float threshold;
+    float edgeThreshold;
+
+  public:
+
+    /** simple constructor */
+    LocalFeatureSift ( const NICE::Config *conf );
+
+    /** simple destructor */
+
+    virtual ~LocalFeatureSift();
+
+    /**
+     * returns the size of each the SIFT-Feature
+     * @return 128
+     */
+    int getDescSize() const {
+      return 128;
+    };
+
+    /**
+     * returns the number of devices
+     * @return { -1 : sift without gpu, n (given devices) else }
+     */
+    int getNumOfDevices () const {
+      return numOfGPU;
+    };
+
+    /**
+     * get the descriptor
+     * @param img input image
+     * @param positions positions for the SIFT features
+     * @param descriptors output
+     * @return 0
+     */
+    virtual int getDescriptors ( const NICE::Image & img,
+                                 NICE::VVector & positions,
+                                 NICE::VVector & descriptors ) const;
+
+    /**
+     * computes the descriptor for a single image
+     * @param img
+     * @param positions
+     * @param descriptors
+     */
+    void computeDesc ( const NICE::Image & img, NICE::VVector & positions, NICE::VVector & descriptors ) const;
+
+    /**
+     * sort positions by scales for faster computing of the Keypoint orientation
+     * @param positions
+     */
+    void sortPositions ( NICE::VVector & positions ) const;
+
+    void visualizeFeatures ( NICE::Image & mark, const NICE::VVector & positions, size_t color ) const;
+
 
-    protected:
-	int octaves;
-	int levels;
-	bool normalizeFeature;
-	int first_octave;
-	double magnif;
-	bool deletemode;
-	bool integerValues;
-
-	float threshold;
-	float edgeThreshold;
-
-    public:
-  
-	/** simple constructor */
-	LocalFeatureSift ( const NICE::Config *conf );
-      
-	/** simple destructor */
-
-	virtual ~LocalFeatureSift();
-	
-	/**
-	 * returns the size of each the SIFT-Feature
-	 * @return 128
-	 */
-	int getDescSize() const { return 128; };
-	
-	/** 
-	 * get the descriptor
-	 * @param img input image
-	 * @param positions positions for the SIFT features
-	 * @param descriptors output
-	 * @return 0
-	 */
-	virtual int getDescriptors ( const NICE::Image & img, 
-			     NICE::VVector & positions,
-			     NICE::VVector & descriptors ) const;
-				     
-	/**
-	 * computes the descriptor for a single image
-	 * @param img 
-	 * @param positions 
-	 * @param descriptors 
-	 */
-	void computeDesc( const NICE::Image & img, NICE::VVector & positions, NICE::VVector & descriptors ) const;
-	
-	/**
-	 * sort positions by scales for faster computing of the Keypoint orientation
-	 * @param positions 
-	 */
-	void sortPositions(NICE::VVector & positions) const;
-	
-	void visualizeFeatures ( NICE::Image & mark, const NICE::VVector & positions, size_t color ) const;
-
-     
 };
 
 

+ 145 - 0
features/localfeatures/LocalFeatureSiftGPU.cpp

@@ -0,0 +1,145 @@
+/**
+* @file LocalFeaturesiftGPU.cpp
+* @brief A Sift-Implementation, which uses the GPU.
+* @author Eric Bach
+* @date 11/20/2011
+*/
+
+#include "LocalFeatureSiftGPU.h"
+
+#include "core/basics/StringTools.h"
+
+using namespace OBJREC;
+using namespace std;
+using namespace NICE;
+
+LocalFeatureSiftGPU::LocalFeatureSiftGPU (const Config* conf) : LocalFeatureSift (conf)
+{
+  const string section = "SIFTGPU";
+
+  gpuLanguage = conf->gS (section, "language", "cuda");
+  multiGPU    = conf->gB (section, "multigpu",  false);
+  numOfGPU    = conf->gI (section, "numgpu"  ,      1);
+
+  // for multiGPU its neccessary, that you got more the one devices
+  /*if( multiGPU && ( numOfGPU < 2 ) )
+    fthrow( Exception, "For multiple GPU, you need more the one device!");
+
+  // fill deviceStat: all devices are unused (=free)
+  for( unsigned int i=0; i < numOfGPU; i++ )
+    deviceStat.insert(pair<unsigned int, bool>(i, true));*/
+}
+
+LocalFeatureSiftGPU::~LocalFeatureSiftGPU ()
+{
+}
+
+int LocalFeatureSiftGPU::getNextDeviceID()
+{
+  StatTable::iterator it = deviceStat.begin();
+  for (; it != deviceStat.end(); ++it) {
+    bool free = it->second;
+    if (free) {
+      it->second = !free;
+      return it->first;
+    }
+  }
+  // no free device was found
+  return -1;
+}
+
+void LocalFeatureSiftGPU::releaseDevice (int id)
+{
+  StatTable::iterator it = deviceStat.find (id);
+  // if given id is associated with a device, set this gpu on free
+  if (it != deviceStat.end()) it->second = true;
+}
+
+void LocalFeatureSiftGPU::computeDesc (const NICE::Image & img, VVector & positions, VVector & descriptors) const
+{
+  // fill the parameter for
+  //char device[2] = {'0' + deviceID, '\0'};
+  char* argv[] = {
+    // First octave to detect DOG keypoints
+    "-fo" , const_cast<char*> (StringTools::convertToString<int> (first_octave).c_str()),
+    // Maximum number of Octaves
+    "-no" , const_cast<char*> (StringTools::convertToString<int> (octaves).c_str()),
+    // Number of DOG levels in an octave.
+    "-d"  , const_cast<char*> (StringTools::convertToString<int> (levels).c_str()),
+    // Write unnormalized descriptor if specified.
+    const_cast<char*> (normalizeFeature ? "" : "-unn"),
+    // Descriptor grid size factor (magnif ??)
+    "-dw" , const_cast<char*> (StringTools::convertToString<float> (magnif).c_str()),
+    // use cuda / which device TODO
+    const_cast<char*> (gpuLanguage == "cuda" ? "-cuda" : "-pack"),  const_cast<char*> (gpuLanguage == "cuda" ? "0" : ""),
+    // verbose levels
+    "-v", "0"
+  };
+  int argc = sizeof (argv) / sizeof (char*);
+
+  // sift Instanz
+  SiftGPU sift;
+
+  // give parameter to sift
+  sift.ParseParam (argc, argv);
+
+  // check, whether siftgpu is full supported
+  const int support = sift.CreateContextGL();
+//   const int support = sift.VerifyContextGL();
+  /*if( support == SiftGPU::SIFTGPU_PARTIAL_SUPPORTED ) 
+    clog << "·[log] LocalFeatureSift: SIFTGPU spartial supported" << endl;*/
+  
+  if ( support != SiftGPU::SIFTGPU_FULL_SUPPORTED) {
+    fthrow( Exception, "LocalFeatureSift: Its not able to use SIFTGPU, because it is not supported." );
+  }
+  else{ clog << "[log] LocalFeatureSift: SIFTGPU full supported" << endl; }
+
+  // set keypoints
+  const int numberOfKeypoints = positions.size();
+  SiftGPU::SiftKeypoint keys[numberOfKeypoints];
+
+  // copy the NICEKeypoints into SiftKeypoints
+  for (int i = 0; i < numberOfKeypoints; i++) {
+    keys[i].x = positions[i][0];
+    keys[i].y = positions[i][1];
+    keys[i].s = positions[i][2];
+    keys[i].o = positions[i][3];
+  }
+  sift.SetKeypointList (numberOfKeypoints, keys);
+
+  // run SIFT
+  const int imageWidth  = img.width();
+  const int imageHeight = img.height();
+  const unsigned char* rawImageData = img.getPixelPointer();
+
+  sift.RunSIFT (imageWidth, imageHeight, rawImageData, GL_LUMINANCE, GL_UNSIGNED_BYTE);
+
+  // get descriptors
+  const int descr_size = 128;
+  const int numberOfDescriptors = sift.GetFeatureNum();
+  float desc[descr_size * numberOfDescriptors];
+  
+  //vector<float> desc (descr_size * numberOfDescriptors);
+
+  sift.GetFeatureVector (keys, desc);
+
+  // TODO: kopieren durch Iterator erledigen
+
+  Vector localDesc (descr_size);
+  // copy the SiftDescriptors into NICEDescriptors
+  for (int i = 0; i < numberOfDescriptors; i++) {
+    for (int j = 0; j < descr_size; j++) {
+      localDesc[j] = (integerValues ? (int) (512 * desc[i*descr_size+j]) : desc[i*descr_size+j]);
+    }
+    descriptors.push_back (localDesc);
+  }
+}
+
+int LocalFeatureSiftGPU::getDescriptors (const NICE::Image & img, VVector & positions, VVector & descriptors) const
+{
+  sortPositions (positions);
+
+  computeDesc (img, positions, descriptors);
+
+  return 0;
+}

+ 62 - 0
features/localfeatures/LocalFeatureSiftGPU.h

@@ -0,0 +1,62 @@
+/** 
+* @file LocalFeaturesiftGPU.h
+* @brief A Sift-Implementation, which uses the GPU.
+* @author Eric Bach
+* @date 11/20/2011
+*/
+#ifndef LOCALFEATURESIFTGPUINCLUDE
+#define LOCALFEATURESIFTGPUINCLUDE
+
+#ifdef NOVISUAL
+#include <objrec/nice_nonvis.h>
+#else
+#include <objrec/nice.h>
+#endif
+
+/* NICE - include */
+#include "core/vector/VVector.h"
+#include "LocalFeatureSift.h"
+
+/* std - include */
+#include <map>
+#include <string>
+
+#ifdef NICE_USELIB_CUDASIFT
+/* SiftGPU - include */
+#include <src/SiftGPU.h>
+#endif
+
+typedef std::map<unsigned int, bool> StatTable;
+
+namespace OBJREC {
+  /** local feature interface */
+  class LocalFeatureSiftGPU: public LocalFeatureSift
+  {
+    private:
+    protected:
+      StatTable deviceStat;
+      int numOfGPU;
+      std::string gpuLanguage;
+      bool multiGPU;
+      
+      //! return the id of a unused device
+      int getNextDeviceID();
+      //! set the device (id) to stat unused
+      void releaseDevice(int id);
+      
+    public:
+      /** simple constructor */
+      LocalFeatureSiftGPU( const NICE::Config* conf );
+    
+      /** simple destructor */
+      ~LocalFeatureSiftGPU();
+      
+      //! returns the number of available devices
+      int getNumOfDevices() const { return numOfGPU; };
+      
+      void computeDesc( const NICE::Image & img, NICE::VVector & positions, NICE::VVector & descriptors) const;
+      
+      int getDescriptors( const NICE::Image & img, NICE::VVector & positions, NICE::VVector & descriptors) const;
+  };
+} // namespace
+#endif

+ 6 - 3
features/localfeatures/libdepend.inc

@@ -1,3 +1,6 @@
-$(call PKG_DEPEND_EXT,ICE)
-$(call PKG_DEPEND_INT,vislearning/segmentation)
-$(call PKG_DEPEND_INT,vislearning/features/fbase)
+$(call PKG_DEPEND_EXT,CUDASIFT)
+$(call PKG_DEPEND_EXT,OPENMP)
+$(call PKG_DEPEND_INT,core)
+$(call PKG_DEPEND_INT,vislearning/baselib)
+$(call PKG_DEPEND_INT,vislearning/image)
+$(call PKG_DEPEND_INT,vislearning/features/fbase)