/** 
* @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

// nice-core includes
#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:
      
    /////////////////////////
    /////////////////////////
    // PROTECTED VARIABLES //
    /////////////////////////
    /////////////////////////  
      
    int i_sizeNeighborhood;
      
    /////////////////////////
    /////////////////////////
    //  PROTECTED METHODS  //
    /////////////////////////
    /////////////////////////         
      
    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:
    
    ///////////////////// ///////////////////// /////////////////////
    //                   CONSTRUCTORS / DESTRUCTORS
    ///////////////////// ///////////////////// /////////////////////     
    
    /** 
     * @brief default constructor
     * @date 09-02-2014 (dd-mm-yyyy )
     * @author Alexander Freytag
     */
    LocalFeatureCentrist ( );    
    
    /**
     * @brief recommended constructor, calls initFromConfig
     * @date 09-02-2014 (dd-mm-yyyy )
     * @author Alexander Freytag
     */
    LocalFeatureCentrist ( const NICE::Config * _conf );

    /**
     * @brief simple destructor
     */
    virtual ~LocalFeatureCentrist();
    
    /** 
     * @brief Jobs previously performed in the config-version of the constructor, read settings etc.
     * @author Alexander Freytag
     * @date 09-02-2014 ( dd-mm-yyyy )
     */    
    virtual void initFromConfig ( const NICE::Config * _conf, const std::string & _confSection = "CENTRIST");    
    
    ///////////////////// ///////////////////// /////////////////////
    //                      FEATURE STUFF
    ///////////////////// ///////////////////// //////////////////       

    /** 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;
          
    ///////////////////// INTERFACE PERSISTENT /////////////////////
    // interface specific methods for store and restore
    ///////////////////// INTERFACE PERSISTENT /////////////////////   
    
    /** 
     * @brief Load object from external file (stream)
     * @author Alexander Freytag
     * @date 09-02-2014 ( dd-mmyyyy)
     */     
    virtual void restore ( std::istream & is, int format = 0 );
    
    /** 
     * @brief Save object to external file (stream)
     * @author Alexander Freytag
     * @date 09-02-2014 ( dd-mmyyyy)
     */       
    virtual void store( std::ostream & os, int format = 0 ) const;
    
    /** 
     * @brief Clear  object
     * @author Alexander Freytag
     * @date 09-02-2014 ( dd-mmyyyy)
     */    
    virtual void clear ();            
    
};


} // namespace

#endif
