/* +---------------------------------------------------------------------------+
   |          The Mobile Robot Programming Toolkit (MRPT) C++ library          |
   |                                                                           |
   |                   http://mrpt.sourceforge.net/                            |
   |                                                                           |
   |   Copyright (C) 2005-2008  University of Malaga                           |
   |                                                                           |
   |    This software was written by the Perception and Robotics               |
   |      research group, University of Malaga (Spain).                        |
   |    Contact: Jose-Luis Blanco  <jlblanco@ctima.uma.es>                     |
   |                                                                           |
   |  This file is part of the MRPT project.                                   |
   |                                                                           |
   |     MRPT is free software: you can redistribute it and/or modify          |
   |     it under the terms of the GNU General Public License as published by  |
   |     the Free Software Foundation, either version 3 of the License, or     |
   |     (at your option) any later version.                                   |
   |                                                                           |
   |   MRPT 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 General Public License for more details.                          |
   |                                                                           |
   |     You should have received a copy of the GNU General Public License     |
   |     along with MRPT.  If not, see <http://www.gnu.org/licenses/>.         |
   |                                                                           |
   +---------------------------------------------------------------------------+ */
#ifndef CImageConvolution_H
#define CImageConvolution_H

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

namespace MRVL
{
	/** This class performs filtering on a image based on Gaussian or DOG filters.
	  * \sa MRVL::CImageConvolution, MRVL
	  */
	class CImageConvolution
	{
	private:

	public:
		/** Performs a 2D convolution of "inImg" using "kernel" and saves the result in "outImg".
		  * NOTES:<br>
			- "inImg" and "outImg" MUST BE different objects!
			- The convolution is performed in two separable steps: vertical and horizontal.
		  */
		static void  convolutionHorzVert(
						CMRPTImageFloat				&inImg,
						CMRPTImageFloat				&outImg,
						CGaussianConvolutionKernel	&kernel);

		/** Performs a horizontal convolution of "inImg" using "kernel" and saves the result in "outImg".
		  * NOTE: "inImg" and "outImg" MUST BE different objects!
		  */
		/**** FAMD ******/
		// ROI added

		static void  convolutionHorizontal(
						CMRPTImageFloat				&inImg,
						CMRPTImageFloat				&outImg,
						CGaussianConvolutionKernel	&kernel,
						TROI						ROI = TROI(0,0,0,0,0,0));
		/****END FAMD***/

		/** Performs a vertical convolution of "inImg" using "kernel" and saves the result in "outImg".
		  * NOTE: "inImg" and "outImg" MUST BE different objects!
		  * \todo JL: There is bug in "convolutionVertical" (& probably convolutionHorizontal) for images much smaller than the kernel (run MonoSLAM!)
		  */
		/**** FAMD ******/
		// ROI added
		static void  convolutionVertical(
						CMRPTImageFloat				&inImg,
						CMRPTImageFloat				&outImg,
						CGaussianConvolutionKernel	&kernel,
						TROI						ROI = TROI(0,0,0,0,0,0));
		/****END FAMD***/

		/** Performs vertical/horizontal convolution of "inImg" using two different kernels and saves the result in "outImg".
		  * NOTE: "inImg" and "outImg" MUST BE different objects!
		  */
		/**** FAMD ******/
		// ROI added
		static void  convolutionSeparate(
						CMRPTImageFloat				&inImg,
						CMRPTImageFloat				&outImg,
						CGaussianConvolutionKernel	&kernelHorz,
						CGaussianConvolutionKernel	&kernelVert,
						TROI						ROI = TROI(0,0,0,0,0,0));
		/****END FAMD***/

		/** Performs convolution of "inImg" using a generic kernel and saves the result in "outImg".
		  * ROI = [x_min, x_min+x_length-1] x [y_min, y_min+y_length-1]
		  * NOTE: "inImg" and "outImg" MUST BE different objects!
		  * by FAMD @ JAN-2007
		  */
		static void  convolutionGeneric(
						const CMRPTImageFloat		&inImg,
						CMRPTImageFloat				&outImg,
						CMatrix						&kernel,
						unsigned int				x_min=0,
						unsigned int				x_length=0,
						unsigned int				y_min=0,
						unsigned int				y_length=0);

		static void  convolutionGeneric(
						const CMRPTImageFloat	&inImg,
						CMRPTImageFloat			&outImg,
						CMatrix					&kernel,
						TROI					ROI = TROI(0,0,0,0,0,0));

		/** Computes the gradient of an image for a given sigma (Gaussian + DOG filtering).
		  * NOTES: <br>
			- "inImg" and "outImg" MUST BE different objects!
			- Internally, the kernels are saved between calls, thus they are computed just the first time for each sigma value.
		  */
		static void  computeGradients(
						CMRPTImageFloat				&inImg,
						float						sigma,
						CMRPTImageFloat				&outGradientX,
						CMRPTImageFloat				&outGradientY);

		/** Computes the smoothed version of an image for a given sigma (Gaussian filtering).
		  * NOTES: <br>
			- "inImg" and "outImg" MUST BE different objects!
			- Internally, the kernel is saved between calls, thus it is computed just the first time for each sigma value.
		  */
		/**** FAMD ******/
		// ROI added
		static void  computeSmoothedImage(
						CMRPTImageFloat				&inImg,
						float						sigma,
						CMRPTImageFloat				&outImg,
						TROI						ROI = TROI(0,0,0,0,0,0));
		/****END FAMD***/

	};	// End of class

} // End of namespace


#endif
