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

	Program:		Range Imaging Toolkit (RITK)
	Module:			ritkRangeImageToWorldCoordImageFilter.h
	Version:		$Revision: 1817 $
	Date:			$Date: 2011-09-30 16:52:28 +0200 (Fr, 30 Sep 2011) $

	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 RANGEIMAGETOWORLDCOORDIMAGEFILTER_H__
#define RANGEIMAGETOWORLDCOORDIMAGEFILTER_H__

#include "ritkCommon.h"

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

#include "ritkCameraParameters.h"

namespace ritk
{

using namespace itk;

/**	@ingroup	Common
 *	@class		RangeImageToWorldCoordImageFilter
 *	@author		Jakob Wasza
 *	@brief		Filter that generates a world coord image from a range image
 *
 *	@details
 *	This filter generates a world coord image (3D points at each pixel) from a range image (radial distances at each pixel).
 *	The filter requires camera parameters that have at least to contain FX,FY,CX, and CY. If undistortion is requested
 *	the parameters K1 and K2 have also to be provided.
 *	@todo Formulas how the world coord image is computed
 *	@todo Documentation on the parameters.
 */
template<class TRangeImage, class TFlagImage, class TWorldCoordImage> 
class RangeImageToWorldCoordImageFilter : public itk::ImageToImageFilter<TRangeImage, TWorldCoordImage>
{
public:
	/** @name	Typedefs */
	//@{

	/** @name	Standard typedefs */
	//@{
	typedef RangeImageToWorldCoordImageFilter			Self;
	typedef itk::ImageToImageFilter<TRangeImage,TWorldCoordImage>	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;
	typedef TFlagImage					FlagImageType;
	typedef typename FlagImageType::Pointer			FlagImagePointer;
	//@}

	//@}

	/// Object creation
	itkNewMacro(Self);

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

	/**	@name	Set/Get the Flag image input */
	//@{
	itkSetInputMacro(FlagImage,FlagImageType,1);
	itkGetInputMacro(FlagImage,FlagImageType,1);
	//@}

	/**	@brief Set the camera parameters
	 *	@param	Params	The camera parameters
	 *
	 *	@details
	 *	Set the camera parameters that are used to generate the worldcoord image from the range image.
	 */
	void SetCameraParameters(CameraParameters Params);

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

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

	/** @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_CameraParameters;
	/// Whether to use undistortion
	bool m_UseUndistortion;
};


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

} // end namespace ritk


#endif // RANGEIMAGETOWORLDCOORDIMAGEFILTER_H__
