瀏覽代碼

adapted Centrist to LocalFeature layout, unit test still missing

Alexander Freytag 11 年之前
父節點
當前提交
a713d75afb

+ 0 - 277
features/localfeatures/Centrist.cpp

@@ -1,277 +0,0 @@
-/** 
- * @file Centrist.cpp
- * @brief Implementation of the Centrist feature published in  "CENTRIST: A Visual Descriptor for Scene Categorization" (PAMI 2011)
- * @author Alexander Lütz
- * @date 12/06/2011
-*/
-#include <iostream>
-
-#include "vislearning/features/localfeatures/Centrist.h"
-#include "core/vector/VVector.h"
-
-using namespace OBJREC;
-using namespace std;
-using namespace NICE;
-
-/* protected methods*/
-
-/**
- * @brief: perform centrist transformation for a single pixel 
- * @author Alexander Lütz
- * @date 12/06/2011
- */
-//TODO maybe inline?
-int CensusTransform(const NICE::Image & img, const int & x, const int & y)
-{
-	int index(0);
-	if (! img.isWithinImage(x,y)) return index;
-	
-	if( (img.isWithinImage(x-1,y-1)) && (img.getPixelInt(x,y)<=img.getPixelInt(x-1,y-1)) ) index |= 0x80;
-	if( (img.isWithinImage(x-1,y)) && (img.getPixelInt(x,y)<=img.getPixelInt(x-1,y)) ) index |= 0x40;
-	if( (img.isWithinImage(x-1,y+1)) && (img.getPixelInt(x,y)<=img.getPixelInt(x-1,y+1)) ) index |= 0x20;
-	if( (img.isWithinImage(x,y-1)) && (img.getPixelInt(x,y)<=img.getPixelInt(x,y-1)) ) index |= 0x10;
-	if( (img.isWithinImage(x,y+1)) && (img.getPixelInt(x,y)<=img.getPixelInt(x,y+1)) ) index |= 0x08;
-	if( (img.isWithinImage(x+1,y-1)) && (img.getPixelInt(x,y)<=img.getPixelInt(x+1,y-1)) ) index |= 0x04;
-	if( (img.isWithinImage(x+1,y)) && (img.getPixelInt(x,y)<=img.getPixelInt(x+1,y)) ) index |= 0x02;
-	if( (img.isWithinImage(x+1,y+1)) && (img.getPixelInt(x,y)<=img.getPixelInt(x+1,y+1)) ) index |= 0x01;
-	return index;
-}
-
-/**
- * @brief: perform centrist transformation for a single pixel 
- * @author Alexander Lütz
- * @date 12/06/2011
- */
-//TODO maybe inline?
-int CensusTransform(const NICE::ColorImage & img, const int & x, const int & y, const int & channel)
-{
-	int index(0);
-	if (! img.isWithinImage(x,y)) return index;
-	
-	if( (img.isWithinImage(x-1,y-1)) && (img.getPixelInt(x,y, channel)<=img.getPixelInt(x-1,y-1, channel)) ) index |= 0x80;
-	if( (img.isWithinImage(x-1,y)) && (img.getPixelInt(x,y, channel)<=img.getPixelInt(x-1,y, channel)) ) index |= 0x40;
-	if( (img.isWithinImage(x-1,y+1)) && (img.getPixelInt(x,y, channel)<=img.getPixelInt(x-1,y+1, channel)) ) index |= 0x20;
-	if( (img.isWithinImage(x,y-1)) && (img.getPixelInt(x,y, channel)<=img.getPixelInt(x,y-1, channel)) ) index |= 0x10;
-	if( (img.isWithinImage(x,y+1)) && (img.getPixelInt(x,y, channel)<=img.getPixelInt(x,y+1, channel)) ) index |= 0x08;
-	if( (img.isWithinImage(x+1,y-1)) && (img.getPixelInt(x,y, channel)<=img.getPixelInt(x+1,y-1, channel)) ) index |= 0x04;
-	if( (img.isWithinImage(x+1,y)) && (img.getPixelInt(x,y, channel)<=img.getPixelInt(x+1,y, channel)) ) index |= 0x02;
-	if( (img.isWithinImage(x+1,y+1)) && (img.getPixelInt(x,y, channel)<=img.getPixelInt(x+1,y+1, channel)) ) index |= 0x01;
-	return index;
-}
-
-/**
- * @brief: generate CT histogram for a given rectangle: pixels in [xi yi]-(xa,ya) -- including (xi,yi) but excluding (xa,ya)
- * @author Alexander Lütz
- * @date 12/06/2011
- */
-void Centrist::GenerateHistForOneRect(const NICE::Image & img, const int & xi, const int & xa, const int & yi, const int & ya, NICE::Vector & feature)
-{
-// 	double pixelSum(0.0);
-// 	double pixelSquare(0.0);
-	feature.resize(256);
-	feature.set(0.0);
-	
-	for (int j = yi; j < ya; j++)
-	{
-		for (int i = xi; i < xa; i++)
-		{
-// 			pixelSum += img.getPixelInt(i,j);
-// 			pixelSquare += img.getPixelInt(i,j)*img.getPixelInt(i,j);
-			feature[CensusTransform(img,i,j)]++;
-		}
-	}
-	
-// 	const double size ( (xa-xi)*(ya-yi));
-
-	// normalize histogram to have 0 mean, remove the first and last entry, and normalize to have unit norm
-	double sum(feature.Sum()/256.0);//shift more efficient?
-	
-	// normalize histogram to have 0 mean
-	//but why?
-	feature -= sum;
-	
-	//remove the first and last entry
-	feature[0] = 0.0;
-	feature[255] = 0.0;
-
-	//normalization - here done using unit L2-norm
-	feature.normalizeL2();
-}
-
-/**
- * @brief: generate CT histogram for a given rectangle: pixels in [xi yi]-(xa,ya) -- including (xi,yi) but excluding (xa,ya)
- * @author Alexander Lütz
- * @date 12/06/2011
- */
-void Centrist::GenerateHistForOneRect(const NICE::ColorImage & img, const int & xi, const int & xa, const int & yi, const int & ya, NICE::Vector & feature)
-{
-// 	double pixelSum(0.0);
-// 	double pixelSquare(0.0);
-	int nrChannel (img.channels());
-	feature.resize(256*nrChannel);
-	feature.set(0.0);
-	
-	for (int channel = 0; channel < nrChannel; channel++)
-	{
-		for (int j = yi; j < ya; j++)
-		{
-			for (int i = xi; i < xa; i++)
-			{
-// 				pixelSum += img.getPixelInt(i,j, channel);
-// 				pixelSquare += img.getPixelInt(i,j, channel)*img.getPixelInt(i,j, channel);
-				feature[256*channel+CensusTransform(img,i,j,channel)]++;
-			}
-		}
-	}
-	
-// 	const double size ( (xa-xi)*(ya-yi))
-
-	// normalize histogram to have 0 mean, remove the first and last entry, and normalize to have unit norm
-	double sum(feature.Sum()/256.0);//shift more efficient?
-	
-	// normalize histogram to have 0 mean
-	//but why?
-	feature -= sum;
-	
-	//remove the first and last entry
-	feature[0] = 0.0;
-	feature[255] = 0.0;
-
-	//normalization - here done using unit L2-norm
-	feature.normalizeL2();
-}
-
-/**
- * @brief Computes several CENTRIST descriptors for each of the given positions om a local neighborhood
- * @author Alexander Lütz
- * @date 12/06/2011
- */
-void Centrist::computeDesc( const NICE::Image & img, NICE::VVector & positions, NICE::VVector & descriptors )
-{
-	descriptors.clear();
-	for (NICE::VVector::const_iterator it = positions.begin(); it != positions.end(); it++)
-	{
-		NICE::Vector descriptor;
-		GenerateHistForOneRect(img, (*it)[0]-sizeNeighborhood/2, (*it)[0]+sizeNeighborhood/2, (*it)[1]-sizeNeighborhood/2, (*it)[1]+sizeNeighborhood/2, descriptor);
-		descriptors.push_back(descriptor);
-	}
-}
-
-/**
- * @brief Computes several CENTRIST descriptors for each of the given positions om a local neighborhood
- * @author Alexander Lütz
- * @date 12/06/2011
- */
-void Centrist::computeDesc( const NICE::ColorImage & img, NICE::VVector & positions, NICE::VVector & descriptors )
-{
-	descriptors.clear();
-	for (NICE::VVector::const_iterator it = positions.begin(); it != positions.end(); it++)
-	{
-		NICE::Vector descriptor;
-		GenerateHistForOneRect(img, (*it)[0]-sizeNeighborhood/2, (*it)[0]+sizeNeighborhood/2, (*it)[1]-sizeNeighborhood/2, (*it)[1]+sizeNeighborhood/2, descriptor);
-		descriptors.push_back(descriptor);
-	}
-}
-
-/* public methods*/
-
-/**
- * @brief Default constructor
- * @author Alexander Lütz
- * @date 12/06/2011
- */
-Centrist::Centrist()
-{
-	sizeNeighborhood = 16;
-}
-
-/**
- * @brief Recommended constructor
- * @author Alexander Lütz
- * @date 12/06/2011
- */
-Centrist::Centrist( const Config *conf, const std::string & section )
-{
-	sizeNeighborhood = conf->gI(section, "sizeNeighborhood", 16);
-}
-
-/**
- * @brief Default destructor
- * @author Alexander Lütz
- * @date 12/06/2011
- */
-Centrist::~Centrist()
-{
-}
-
-
-/**
- * @brief Computes several CENTRIST descriptors for each of the given positions on a local neighborhood
- * @author Alexander Lütz
- * @date 12/06/2011
- */
-int Centrist::getDescriptors ( const NICE::Image & img, VVector & positions, VVector & descriptors )
-{
-	computeDesc(img, positions, descriptors);
-	return 0;
-}
-
-/**
- * @brief Computes several CENTRIST descriptors for each of the given positions on a local neighborhood
- * @author Alexander Lütz
- * @date 12/06/2011
- */
-int Centrist::getDescriptors ( const NICE::ColorImage & img, NICE::VVector & positions, NICE::VVector & descriptors)
-{
-	computeDesc(img, positions, descriptors);
-	return 0;
-}
-
-/**
- * @brief Visualizes CENTRIST descriptors, not implemented yet!
- * @author Alexander Lütz
- * @date 12/06/2011
- */
-void Centrist::visualizeFeatures ( NICE::Image & mark,
-				 const VVector & positions,
-				 size_t color ) const
-{
-//     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));
-}
-

+ 0 - 62
features/localfeatures/Centrist.h

@@ -1,62 +0,0 @@
-/** 
-* @file Centrist.h
-* @brief Implementation of the Centrist feature published in  "CENTRIST: A Visual Descriptor for Scene Categorization" (PAMI 2011)
-* @author Alexander Lütz
-* @date 12/06/2011
-*/
-#ifndef CENTRISTINCLUDE
-#define CENTRISTINCLUDE
-
-#include "core/vector/VectorT.h"
-#include "core/vector/MatrixT.h"
-#include "core/image/ImageT.h"
-
-#include "core/vector/VVector.h"
-#include "LocalFeature.h"
-#include "core/basics/Config.h"
-  
-
-namespace OBJREC {
-
-/** interface to CENTRIST implementation*/
-class Centrist : public LocalFeature
-{
-
-    protected:
-		 int sizeNeighborhood;
-		 
-		 int CensusTransform(const NICE::Image & img, const int & x, const int & y);
-		 int CensusTransform(const NICE::ColorImage & img, const int & x, const int & y, const int & channel);
-		 void GenerateHistForOneRect(const NICE::Image & img, const int & xi, const int & xa, const int & yi, const int & ya, NICE::Vector & feature);
-		 void GenerateHistForOneRect(const NICE::ColorImage & img, const int & xi, const int & xa, const int & yi, const int & ya, NICE::Vector & feature);
-		 void computeDesc( const NICE::Image & img, NICE::VVector & positions, NICE::VVector & descriptors );
-		 void computeDesc( const NICE::ColorImage & img, NICE::VVector & positions, NICE::VVector & descriptors );
-
-    public:
-  
-	/** simple constructor */
-	Centrist();
-	/** default constructor */
-	Centrist(const NICE::Config *conf, const std::string & section="CENTRIST");
-      
-	/** simple destructor */
-	virtual ~Centrist();
-
-	// we have 8 neighbors, so the size is always 256 with the given implementation (without spatial levels, ...)
-	/** Beware: multiply this number by the number of channels you use in your color image*/
-	int getDescSize(){return 256;};
-
-	int getDescriptors ( const NICE::Image & img, NICE::VVector & positions, NICE::VVector & descriptors);
-	
-	int getDescriptors ( const NICE::ColorImage & img, NICE::VVector & positions, NICE::VVector & descriptors);
-	
-	void visualizeFeatures ( NICE::Image & mark,
-				 const NICE::VVector & positions,
-				 size_t color ) const;
-    
-};
-
-
-} // namespace
-
-#endif

+ 8 - 0
features/localfeatures/GenericLocalFeatureSelection.h

@@ -15,9 +15,12 @@
 #include "vislearning/features/localfeatures/LocalFeatureOpponnentSift.h"
 #include "vislearning/features/localfeatures/LocalFeatureColorWeijer.h"
 // non-color-descriptor
+#include "vislearning/features/localfeatures/LocalFeatureCentrist.h"
 #include "vislearning/features/localfeatures/LocalFeatureSift.h"
 
 
+
+
 /** NOTE: This class only returns Descriptors, which NEED given positions. NO Descriptors calculate there own positions. **/
 
 namespace OBJREC {
@@ -60,7 +63,12 @@ class GenericLocalFeatureSelection
       else if ( localfeature_type == "colornames" )
       {
         lf = new OBJREC::LocalFeatureColorWeijer ( conf );
+      }     
+      else if ( localfeature_type == "centrist" )
+      {
+        lf = new OBJREC::LocalFeatureCentrist ( conf );
       }      
+      
 
       // no correct localfeature_type was given
       if ( lf == NULL )

+ 247 - 0
features/localfeatures/LocalFeatureCentrist.cpp

@@ -0,0 +1,247 @@
+/** 
+ * @file LocalFeatureCentrist.cpp
+ * @brief Implementation of the LocalFeatureCentrist feature published in  "CENTRIST: A Visual Descriptor for Scene Categorization" (PAMI 2011)
+ * @author Alexander Freytag
+ * @date 12/06/2011
+*/
+
+// STL includes
+#include <iostream>
+
+// nice-vislearning includes
+#include "vislearning/features/localfeatures/LocalFeatureCentrist.h"
+
+
+using namespace OBJREC;
+using namespace std;
+using namespace NICE;
+
+/* protected methods*/
+
+/**
+ * @brief: perform centrist transformation for a single pixel 
+ * @author Alexander Freytag
+ * @date 12/06/2011
+ */
+int LocalFeatureCentrist::CensusTransform(const NICE::Image & img, const int & x, const int & y) const
+{
+  int index(0);
+  if (! img.isWithinImage(x,y)) return index;
+  
+  if( (img.isWithinImage(x-1,y-1)) && (img.getPixelInt(x,y)<=img.getPixelInt(x-1,y-1)) ) index |= 0x80;
+  if( (img.isWithinImage(x-1,y))   && (img.getPixelInt(x,y)<=img.getPixelInt(x-1,y)) )   index |= 0x40;
+  if( (img.isWithinImage(x-1,y+1)) && (img.getPixelInt(x,y)<=img.getPixelInt(x-1,y+1)) ) index |= 0x20;
+  if( (img.isWithinImage(x,y-1))   && (img.getPixelInt(x,y)<=img.getPixelInt(x,y-1)) )   index |= 0x10;
+  if( (img.isWithinImage(x,y+1))   && (img.getPixelInt(x,y)<=img.getPixelInt(x,y+1)) )   index |= 0x08;
+  if( (img.isWithinImage(x+1,y-1)) && (img.getPixelInt(x,y)<=img.getPixelInt(x+1,y-1)) ) index |= 0x04;
+  if( (img.isWithinImage(x+1,y))   && (img.getPixelInt(x,y)<=img.getPixelInt(x+1,y)) )   index |= 0x02;
+  if( (img.isWithinImage(x+1,y+1)) && (img.getPixelInt(x,y)<=img.getPixelInt(x+1,y+1)) ) index |= 0x01;
+  return index;
+}
+
+/**
+ * @brief: perform centrist transformation for a single pixel 
+ * @author Alexander Freytag
+ * @date 12/06/2011
+ */
+int LocalFeatureCentrist::CensusTransform(const NICE::ColorImage & img, const int & x, const int & y, const int & channel) const
+{
+  int index(0);
+  if (! img.isWithinImage(x,y)) return index;
+  
+  if( (img.isWithinImage(x-1,y-1)) && (img.getPixelInt(x,y, channel)<=img.getPixelInt(x-1,y-1, channel)) ) index |= 0x80;
+  if( (img.isWithinImage(x-1,y))   && (img.getPixelInt(x,y, channel)<=img.getPixelInt(x-1,y, channel)) )   index |= 0x40;
+  if( (img.isWithinImage(x-1,y+1)) && (img.getPixelInt(x,y, channel)<=img.getPixelInt(x-1,y+1, channel)) ) index |= 0x20;
+  if( (img.isWithinImage(x,y-1))   && (img.getPixelInt(x,y, channel)<=img.getPixelInt(x,y-1, channel)) )   index |= 0x10;
+  if( (img.isWithinImage(x,y+1))   && (img.getPixelInt(x,y, channel)<=img.getPixelInt(x,y+1, channel)) )   index |= 0x08;
+  if( (img.isWithinImage(x+1,y-1)) && (img.getPixelInt(x,y, channel)<=img.getPixelInt(x+1,y-1, channel)) ) index |= 0x04;
+  if( (img.isWithinImage(x+1,y))   && (img.getPixelInt(x,y, channel)<=img.getPixelInt(x+1,y, channel)) )   index |= 0x02;
+  if( (img.isWithinImage(x+1,y+1)) && (img.getPixelInt(x,y, channel)<=img.getPixelInt(x+1,y+1, channel)) ) index |= 0x01;
+  return index;
+}
+
+/**
+ * @brief: generate CT histogram for a given rectangle: pixels in [xi yi]-(xa,ya) -- including (xi,yi) but excluding (xa,ya)
+ * @author Alexander Freytag
+ * @date 12/06/2011
+ */
+void LocalFeatureCentrist::GenerateHistForOneRect(const NICE::Image & img, const int & xi, const int & xa, const int & yi, const int & ya, NICE::Vector & feature) const
+{
+// 	double pixelSum(0.0);
+// 	double pixelSquare(0.0);
+  feature.resize(256);
+  feature.set(0.0);
+  
+  for (int j = yi; j < ya; j++)
+  {
+    for (int i = xi; i < xa; i++)
+    {
+// 			pixelSum += img.getPixelInt(i,j);
+// 			pixelSquare += img.getPixelInt(i,j)*img.getPixelInt(i,j);
+      feature[CensusTransform(img,i,j)]++;
+    }
+  }
+  
+  // normalize histogram to have 0 mean, remove the first and last entry, and normalize to have unit norm
+  double sum(feature.Sum()/256.0);//shift more efficient?
+  
+  // normalize histogram to have 0 mean
+  //but why?
+  feature -= sum;
+  
+  //remove the first and last entry
+  feature[0] = 0.0;
+  feature[255] = 0.0;
+
+  //normalization - here done using unit L2-norm
+  feature.normalizeL2();
+}
+
+/**
+ * @brief: generate CT histogram for a given rectangle: pixels in [xi yi]-(xa,ya) -- including (xi,yi) but excluding (xa,ya)
+ * @author Alexander Freytag
+ * @date 12/06/2011
+ */
+void LocalFeatureCentrist::GenerateHistForOneRect(const NICE::ColorImage & img, const int & xi, const int & xa, const int & yi, const int & ya, NICE::Vector & feature) const
+{
+// 	double pixelSum(0.0);
+// 	double pixelSquare(0.0);
+  int nrChannel (img.channels());
+  feature.resize(256*nrChannel);
+  feature.set(0.0);
+  
+  for (int channel = 0; channel < nrChannel; channel++)
+  {
+    for (int j = yi; j < ya; j++)
+    {
+      for (int i = xi; i < xa; i++)
+      {
+// 				pixelSum += img.getPixelInt(i,j, channel);
+// 				pixelSquare += img.getPixelInt(i,j, channel)*img.getPixelInt(i,j, channel);
+        feature[256*channel+this->CensusTransform(img,i,j,channel)]++;
+      }
+    }
+  }
+
+  // normalize histogram to have 0 mean, remove the first and last entry, and normalize to have unit norm
+  double sum(feature.Sum()/256.0);//shift more efficient?
+  
+  // normalize histogram to have 0 mean
+  //but why?
+  feature -= sum;
+  
+  //remove the first and last entry
+  feature[0] = 0.0;
+  feature[255] = 0.0;
+
+  //normalization - here done using unit L2-norm
+  feature.normalizeL2();
+}
+
+/**
+ * @brief Computes several CENTRIST descriptors for each of the given positions om a local neighborhood
+ * @author Alexander Freytag
+ * @date 12/06/2011
+ */
+void LocalFeatureCentrist::computeDesc( const NICE::Image & img, NICE::VVector & positions, NICE::VVector & descriptors ) const
+{
+  descriptors.clear();
+  for (NICE::VVector::const_iterator it = positions.begin(); it != positions.end(); it++)
+  {
+    NICE::Vector descriptor;
+    
+    this->GenerateHistForOneRect(img, (*it)[0]-i_sizeNeighborhood/2, (*it)[0]+i_sizeNeighborhood/2, (*it)[1]-i_sizeNeighborhood/2, (*it)[1]+i_sizeNeighborhood/2, descriptor);
+    
+    descriptors.push_back(descriptor);
+  }
+}
+
+/**
+ * @brief Computes several CENTRIST descriptors for each of the given positions om a local neighborhood
+ * @author Alexander Freytag
+ * @date 12/06/2011
+ */
+void LocalFeatureCentrist::computeDesc( const NICE::ColorImage & img, NICE::VVector & positions, NICE::VVector & descriptors ) const
+{
+  descriptors.clear();
+  for (NICE::VVector::const_iterator it = positions.begin(); it != positions.end(); it++)
+  {
+    NICE::Vector descriptor;
+    
+    this->GenerateHistForOneRect(img, (*it)[0]-i_sizeNeighborhood/2, (*it)[0]+i_sizeNeighborhood/2, (*it)[1]-i_sizeNeighborhood/2, (*it)[1]+i_sizeNeighborhood/2, descriptor);
+    
+    descriptors.push_back(descriptor);
+  }
+}
+
+/* public methods*/
+
+/**
+ * @brief Default constructor
+ * @author Alexander Freytag
+ * @date 12/06/2011
+ */
+LocalFeatureCentrist::LocalFeatureCentrist()
+{
+  this->i_sizeNeighborhood = 16;
+}
+
+/**
+ * @brief Recommended constructor
+ * @author Alexander Freytag
+ * @date 12/06/2011
+ */
+LocalFeatureCentrist::LocalFeatureCentrist( const Config *conf, const std::string & section )
+{
+  this->i_sizeNeighborhood = conf->gI(section, "i_sizeNeighborhood", 16);
+}
+
+/**
+ * @brief Default destructor
+ * @author Alexander Freytag
+ * @date 12/06/2011
+ */
+LocalFeatureCentrist::~LocalFeatureCentrist()
+{
+}
+
+int LocalFeatureCentrist::getDescSize() const
+{
+  // we have 8 neighbors, so the size is always 256 with the given implementation (without spatial levels, ...)
+  return 256;
+}
+
+/**
+ * @brief Computes several CENTRIST descriptors for each of the given positions on a local neighborhood
+ * @author Alexander Freytag
+ * @date 12/06/2011
+ */
+int LocalFeatureCentrist::getDescriptors ( const NICE::Image & img, VVector & positions, VVector & descriptors ) const
+{
+  this->computeDesc( img, positions, descriptors );
+  return 0;
+}
+
+/**
+ * @brief Computes several CENTRIST descriptors for each of the given positions on a local neighborhood
+ * @author Alexander Freytag
+ * @date 12/06/2011
+ */
+int LocalFeatureCentrist::getDescriptors ( const NICE::ColorImage & img, NICE::VVector & positions, NICE::VVector & descriptors) const
+{
+  this->computeDesc( img, positions, descriptors );
+  return 0;
+}
+
+/**
+ * @brief Visualizes CENTRIST descriptors, not implemented yet!
+ * @author Alexander Freytag
+ * @date 12/06/2011
+ */
+void LocalFeatureCentrist::visualizeFeatures ( NICE::Image & mark,
+                                               const VVector & positions,
+                                               size_t color ) const
+{
+  throw NICE::Exception ( "LocalFeatureCentrist::visualizeFeatures -- currently not implemented." );
+}
+

+ 68 - 0
features/localfeatures/LocalFeatureCentrist.h

@@ -0,0 +1,68 @@
+/** 
+* @file LocalFeatureCentrist.h
+* @brief Implementation of the LocalFeatureCentrist feature published in  "CENTRIST: A Visual Descriptor for Scene Categorization" (PAMI 2011)
+* @author Alexander Freytag
+* @date 12/06/2011
+* @NOTE NEEDS PROPER UNIT TEST!
+*/
+#ifndef CENTRISTINCLUDE
+#define CENTRISTINCLUDE
+
+#include <core/basics/Config.h>
+// 
+#include <core/image/ImageT.h>
+// 
+#include <core/vector/MatrixT.h>
+#include <core/vector/VectorT.h>
+#include <core/vector/VVector.h>
+
+// nice-vislearning includes
+#include "LocalFeature.h"
+
+  
+
+namespace OBJREC {
+
+/** interface to CENTRIST implementation*/
+class LocalFeatureCentrist : public LocalFeature
+{
+
+    protected:
+      int i_sizeNeighborhood;
+      
+      int CensusTransform(const NICE::Image & img, const int & x, const int & y) const;
+      int CensusTransform(const NICE::ColorImage & img, const int & x, const int & y, const int & channel) const;
+      
+      void GenerateHistForOneRect(const NICE::Image & img, const int & xi, const int & xa, const int & yi, const int & ya, NICE::Vector & feature) const;
+      void GenerateHistForOneRect(const NICE::ColorImage & img, const int & xi, const int & xa, const int & yi, const int & ya, NICE::Vector & feature) const;
+      
+      void computeDesc( const NICE::Image & img, NICE::VVector & positions, NICE::VVector & descriptors ) const;
+      void computeDesc( const NICE::ColorImage & img, NICE::VVector & positions, NICE::VVector & descriptors )  const;
+
+    public:
+  
+      /** simple constructor */
+      LocalFeatureCentrist();
+      /** default constructor */
+      LocalFeatureCentrist(const NICE::Config *conf, const std::string & section="CENTRIST");
+          
+      /** simple destructor */
+      virtual ~LocalFeatureCentrist();
+
+      /** Beware: multiply this number by the number of channels you use in your color image*/
+      virtual int getDescSize() const;
+
+      virtual int getDescriptors ( const NICE::Image & img, NICE::VVector & positions, NICE::VVector & descriptors) const;
+      
+      virtual int getDescriptors ( const NICE::ColorImage & img, NICE::VVector & positions, NICE::VVector & descriptors) const;
+      
+      virtual void visualizeFeatures ( NICE::Image & mark,
+            const NICE::VVector & positions,
+            size_t color ) const;
+    
+};
+
+
+} // namespace
+
+#endif