/*======================================================================================

	Program:		Range Imaging Toolkit (RITK)
	Module:			ritkRGBMappingImageFilter.h
	Version:		$Revision: 2774 $
	Date:			$Date: 2012-03-13 10:52:35 +0100 (Di, 13 Mrz 2012) $

	Copyright (c) 2010-2011
	Pattern Recognition Lab, 
    University Erlangen-Nuremberg, Germany
    All rights reserved.

	This program 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 RITKCopyright.txt for more information.

	http://www5.informatik.uni-erlangen.de/research/software/ritk

========================================================================================*/

#ifndef RGBMAPPINGIMAGEFILTER_H__
#define RGBMAPPINGIMAGEFILTER_H__

#include "ritkCommon.h"

#include <itkProcessObject.h>
#include <itkImageToImageFilter.h>

#include <itkVector.h>
#include <itkMatrix.h>
#include <vnl/vnl_double_3x3.h>
#include <vnl/vnl_double_3.h>

#include "ritkCameraParameters.h"

namespace ritk
{

using namespace itk;

/**	@ingroup	Common
 *	@class		RGBMappingImageFilter
 *	@author		Sven Haase
 *	@brief		Filter that maps the rgb image correct according to the relative transformation
 *
 *	@details
 *	This filter maps the RGB image recorded by a different camera on to the chip of the range camera.
 *	The filter requires camera parameters that have at least to contain FX,FY,CX, and CY for both cameras. If undistortion is requested
 *	the parameters K1 and K2 have also to be provided. Additionally the relative transformation needs to be set.
 */
template<class TWorldCoordImage, class TRGBImage> 
class RGBMappingImageFilter : public itk::ImageToImageFilter<TWorldCoordImage, TRGBImage>
{
public:
	/** @name	Typedefs */
	//@{

	/**	@name	Transformation typedefs */
	//@{
	/*typedef itk::Vector<double, 3> TransVectorType;
	typedef itk::Matrix<double, 3, 3> RotMatrixType;*/
	typedef vnl_double_3x3	RotMatrixType;
	typedef vnl_double_3	TransVectorType;
	//@}

	/** @name	Standard typedefs */
	//@{
	typedef RGBMappingImageFilter			Self;
	typedef itk::ImageToImageFilter<TWorldCoordImage,TRGBImage>	Superclass;
	typedef itk::SmartPointer<Self>					Pointer;
	typedef itk::SmartPointer<const Self>				ConstPointer;
	typedef itk::DataObject::Pointer				DataObjectPointer;
	//@}

	/**	@name	Input, output and Flag typedefs */
	//@{
	typedef typename Superclass::InputImageType		InputImageType;
	typedef typename InputImageType::Pointer		InputImagePointer;
	typedef typename InputImageType::ConstPointer		InputImageConstPointer;
	typedef typename InputImageType::PixelType		InputPixelType;
	typedef typename Superclass::OutputImageType		OutputImageType;
	typedef typename OutputImageType::Pointer		OutputImagePointer;
	typedef typename OutputImageType::PixelType		OutputImagePixelType;
	//@}

	//@}

	/// Object creation
	itkNewMacro(Self);

	/// RTTI
	itkTypeMacro(RGBMappingImageFilter, itk::ImageToImageFilter);

	/**	@name	Set/Get the RGB image input */
	//@{
	itkSetInputMacro(RGBImage,OutputImageType,1);
	itkGetInputMacro(RGBImage,OutputImageType,1);
	//@}

	/**	@brief Set the rgb camera parameters
	 *	@param	Params	The rgb camera parameters
	 *
	 *	@details
	 *	Set the camera parameters that are used to generate the 2D coordinate .
	 */
	void SetCameraParametersRGB(CameraParameters Params);

	/**	@brief Set the rgb camera translation
	 *	@param	Params	The rgb camera translation
	 *
	 *	@details
	 *	Set the camera translation used for the mapping .
	 */
	void SetCameraTranslation(TransVectorType Trans);

	/**	@brief Set the rgb camera rotation
	 *	@param	Params	The rgb camera rotation
	 *
	 *	@details
	 *	Set the camera rotation used for the mapping .
	 */
	void SetCameraRotation(RotMatrixType Rot);

	/**	@brief	Set whether to undistort the image
	 *	@param	b	true or false
	 *
	 *	@details
	 *	Set whether to undistort the image. Default is false
	 *	@todo	What is the undistortion?
	 */
	void SetUseUndistortion(bool b);

	/// Activate exact mapping (interpolation when down projecting)
	void SetExactMapping(bool exact);

	/** Overloaded because of different input regions */
	virtual void GenerateInputRequestedRegion();

protected:
	/// Constructor
	RGBMappingImageFilter();
	/// Destructor
	~RGBMappingImageFilter();

	/** @name  Threaded data generation */
	//@{
	virtual void BeforeThreadedGenerateData();
	virtual void ThreadedGenerateData(const typename OutputImageType::RegionType &OutputRegionForThread, int threadId);
	virtual void AfterThreadedGenerateData();
	//@}

protected:
	/// The camera parameters
	CameraParameters m_CameraParametersRGB;
	/// The camera translation
	TransVectorType m_TransVector;
	/// The camera rotation
	RotMatrixType m_RotMatrix;
	/// Whether to use undistortion
	bool m_UseUndistortion;
	/// Whether to use interpolation when down projecting
	bool m_ExactMapping;
};


/** @name Template instantiations */
//@{
typedef RGBMappingImageFilter<itk::Image<itk::Vector<float,3>,2>, itk::Image<itk::Vector<unsigned char,3>,2> > RGBMappingImageFilterF2;
//@}

} // end namespace ritk


#endif // RGBMAPPINGIMAGEFILTER_H__
