/*---------------------------------------------------------------
	FILE: CFeatureExtraction.h
	USE: See doc above

   Part of the MRPT Library
   ISA - Universidad de Malaga - http://www.isa.uma.es
  ---------------------------------------------------------------*/
#ifndef CFeatureExtraction_H
#define CFeatureExtraction_H

#include <MRPT/UTILS/CMRPTImage.h>
#include <MRPT/UTILS/CMRPTImageFloat.h>
#include <MRPT/UTILS/CTicTac.h>
#include <MRPT/MRVL/CImageConvolution.h>
#include <MRPT/MRVL/VisionUtils.h>

namespace MRVL
{
	class CFeatureExtraction
	{
	public:
		enum TMethodExtraction
			{
				msKLT = 0,
				msHarris,
				msBCD,
				msSIFT
			};

		struct TOptions
		{
			/** Initalizer
			*/
			TOptions();

			/** Method of the extraction
			*/
			TMethodExtraction method;

			struct TKLTOptions
			{
				/** KLT Options
				  */

			} KLTOptions;

			struct THarrisOptions
			{
				/** Harris Options
				  */
				float threshold;
				float k;
				float sigma;
				int radius;		//pixels measured
			} harrisOptions;

			struct TBCDOptions
			{
				/** BCD Options
				  */
			} BCDOptions;

			struct TSIFTOptions
			{
				/** SIFT Options
				  */
			} SIFTOptions;


		} options;

		/** Constructor
		*/
		CFeatureExtraction();

		/** Virtual destructor.
		*/
		virtual ~CFeatureExtraction();

		/** Extract features from the image based on the method defined in TOptions.
		* \param img The image from where to extract the images.
		* \param x Vector containing the feature 'x' coordinates.
		* \param y Vector containing the feature 'y' coordinates.
		* \param nDesiredFeatures Number of features to be extracted. Default: authomatic.
		* \param x_min Minimum x coordinate in the image where the extraction is performed. Default: All the image.
		* \param x_length X Length of the region of interest. Default: All the image.
		* \param y_min Minimum y coordinate in the image where the extraction is performed. Default: All the image.
		* \param y_length X Length of the region of interest. Default: All the image.
		*/
		void  extractFeatures(
			const CMRPTImageFloat	&img,
			vector_float			&x,
			vector_float			&y,
			int						nDesiredFeatures = -1,
			unsigned int			x_min = 0,
			unsigned int			x_length = 0,
			unsigned int			y_min = 0,
			unsigned int			y_length = 0);

		//// ********************** FAMD ***********************//
		//// Por ahora he puesto esta funcion en la seccion publica para que se pueda llamar desde fuera y no meterla en el 'switch' principal
		///** Extract features from the image based on the SIFT binary provided by Lowe Demo.
		//* \param img File name of the image to be processed (must be in PGM format).
		//* \param features (out) List of detected features (all field in the feature struct are filled).
		//*/
		//void  extractFeaturesSIFT(
		//	std::string &img,
		//	TSIFTFeatureList &features,
		//	unsigned int nFeatures = 0);
		// ********************** END FAMD ***********************//

	private:
		/** Extract features from the image based on the Harris method.
		* \param img The image from where to extract the images.
		* \param x Vector containing the feature 'x' coordinates.
		* \param y Vector containing the feature 'y' coordinates.
		* \param nDesiredFeatures Number of features to be extracted. Default: authomatic.
		* \param x_min Minimum x coordinate in the image where the extraction is performed. Default: All the image.
		* \param x_length X Length of the region of interest. Default: All the image.
		* \param y_min Minimum y coordinate in the image where the extraction is performed. Default: All the image.
		* \param y_length X Length of the region of interest. Default: All the image.
		*/
		void  extractFeaturesHarris(
			const CMRPTImageFloat	&img,
			vector_float			&x,
			vector_float			&y,
			int						nDesiredFeatures = -1,
			unsigned int			x_min = 0,
			unsigned int			x_length = 0,
			unsigned int			y_min = 0,
			unsigned int			y_length = 0);

		/** Extract features from the image based on the Harris method employing the classical algorithm.
		* \param img The image from where to extract the images.
		* \param x Vector containing the feature 'x' coordinates.
		* \param y Vector containing the feature 'y' coordinates.
		* \param nDesiredFeatures Number of features to be extracted. Default: authomatic.
		* \param x_min Minimum x coordinate in the image where the extraction is performed. Default: All the image.
		* \param y_min Minimum y coordinate in the image where the extraction is performed. Default: All the image.
		*/
		void  HarrisCommon(const CMRPTImageFloat	&imgR,
									 vector_float			&x,
									 vector_float			&y,
									 int					nDesiredFeatures,
									 unsigned int			x_min,
									 unsigned int			y_min);


		/** Extract features from the image based on the Harris method and distributing the features over the image.
		* \param img The image from where to extract the images.
		* \param x Vector containing the feature 'x' coordinates.
		* \param y Vector containing the feature 'y' coordinates.
		* \param nDesiredFeatures Number of features to be extracted. Default: authomatic.
		* \param x_min Minimum x coordinate in the image where the extraction is performed. Default: All the image.
		* \param y_min Minimum y coordinate in the image where the extraction is performed. Default: All the image.
		*/
		void  HarrisMask(const CMRPTImageFloat	&imgR,
								   vector_float			&x,
								   vector_float			&y,
								   int					nDesiredFeatures,
								   unsigned int			x_min,
								   unsigned int			y_min);

		/** Extract features from the image based on the KLT method.
		* \param img The image from where to extract the images.
		* \param x Vector containing the feature 'x' coordinates.
		* \param y Vector containing the feature 'y' coordinates.
		* \param nDesiredFeatures Number of features to be extracted. Default: authomatic.
		* \param x_min Minimum x coordinate in the image where the extraction is performed. Default: All the image.
		* \param x_length X Length of the region of interest. Default: All the image.
		* \param y_min Minimum y coordinate in the image where the extraction is performed. Default: All the image.
		* \param y_length X Length of the region of interest. Default: All the image.
		*/
		void  extractFeaturesKLT(
			const CMRPTImageFloat	&img,
			vector_float			&x,
			vector_float			&y,
			int						nDesiredFeatures = -1,
			unsigned int			x_min = 0,
			unsigned int			x_length = 0,
			unsigned int			y_min = 0,
			unsigned int			y_length = 0);

		/** Extract features from the image based on the BCD method.
		* \param img The image from where to extract the images.
		* \param x Vector containing the feature 'x' coordinates.
		* \param y Vector containing the feature 'y' coordinates.
		* \param nDesiredFeatures Number of features to be extracted. Default: authomatic.
		* \param x_min Minimum x coordinate in the image where the extraction is performed. Default: All the image.
		* \param x_length X Length of the region of interest. Default: All the image.
		* \param y_min Minimum y coordinate in the image where the extraction is performed. Default: All the image.
		* \param y_length X Length of the region of interest. Default: All the image.
		*/
		void  extractFeaturesBCD(
			const CMRPTImageFloat	&img,
			vector_float			&x,
			vector_float			&y,
			int						nDesiredFeatures = -1,
			unsigned int			x_min = 0,
			unsigned int			x_length = 0,
			unsigned int			y_min = 0,
			unsigned int			y_length = 0);

		/** Extract features from the image based on the SIFT method.
		* \param img The image from where to extract the images.
		* \param x Vector containing the feature 'x' coordinates.
		* \param y Vector containing the feature 'y' coordinates.
		* \param nDesiredFeatures Number of features to be extracted. Default: authomatic.
		* \param x_min Minimum x coordinate in the image where the extraction is performed. Default: All the image.
		* \param x_length X Length of the region of interest. Default: All the image.
		* \param y_min Minimum y coordinate in the image where the extraction is performed. Default: All the image.
		* \param y_length X Length of the region of interest. Default: All the image.
		*/
		void  extractFeaturesSIFT(
			const CMRPTImageFloat	&img,
			vector_float			&x,
			vector_float			&y,
			int						nDesiredFeatures = -1,
			unsigned int			x_min = 0,
			unsigned int			x_length = 0,
			unsigned int			y_min = 0,
			unsigned int			y_length = 0);

	}; // end of class
} // end of namespace
#endif
