/* ImLib3D
 * Copyright (c) 2001, ULP-IPB Strasbourg.
 *
 * This program 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 2 of the License, or (at
 * your option) any later version.
 * 
 * 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 the GNU
 * General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
/*! \file   Normalization.hpp */


#ifndef _Normalization_hpp
#define _Normalization_hpp

#include<ImLib3D/ImageProcessor.hpp>
#include<ImLib3D/ImageStats.hpp>
#include<ImLib3D/Signal1D.hpp>


namespace IP3D
{
/*! #&NormalizeAverageAndVariance&#     Forces average and variance to be the same as in reference image.
        Uses masks.
     <UL>Args:
      <LI>Source image     type:Image3Df
      <LI>Reference image  type:Image3Df
      <LI>Result image     type:Image3Df
     </UL>
~*/
		void NormalizeAverageAndVariance(const Image3Df& src,const Image3Df& ref,Image3Df& res);
};

namespace IP3D
{
/*! #&NormalizeAverageAndVariance&#     Forces average and variance to be the same as in reference image.
        Uses masks.
     <UL>Args:
      <LI>Source image     type:Image3Df
      <LI>Reference image  type:Image3Df
      <LI>Result image     type:Image3Df
     </UL>
~*/
		void NormalizeJointHistogram(const Image3Df& src,const Image3Df& ref,Image3Df& res,int nbSrcBins=100,int nbRefBins=200);
};


//! Computing joint histograms, and associated  intensity normalization
class JointHistogram
{
public:
	int nbSrcBins;
	int nbRefBins;
	Image3Df jointHisto;
	double srcMedian;
	//! min value for src image 
	double srcMin;
	//! max value for src image 
	double srcMax;
	//! min value for ref image 
	double refMin;
	//! max value for ref image 
	double refMax;

	
    //@{ \name conversion from bin number to real value
	//! index of src bin for src value=v
	inline int    SrcBin(float v)   {return ((int)(nbSrcBins  *(v-srcMin)/(srcMax-srcMin)));}
	inline int    RefBin(float v)   {return ((int)(nbRefBins  *(v-refMin)/(refMax-refMin)));}
	inline double SrcVal(int x)     {return (srcMin+x*(srcMax-srcMin)/(double)nbSrcBins );}
	inline double SrcVal(double x)  {return (srcMin+x*(srcMax-srcMin)/(double)nbSrcBins );}
	inline double RefVal(int y)     {return (refMin+y*(refMax-refMin)/(double)nbRefBins);}
	inline double RefVal(double y)  {return (refMin+y*(refMax-refMin)/(double)nbRefBins);}
	inline int    SSrcBin(float v)  {return min(nbSrcBins -1,max(0,SrcBin(v)));}
	inline int    SRefBin(float v)  {return min(nbRefBins-1 ,max(0,RefBin(v)));}
    //@}
	float SrcLimit(float v){return min((float)srcMax,max(v,(float)srcMin));}
	float RefLimit(float v){return min((float)refMax,max(v,(float)refMin));}
private:
	//! Simple computation of joint histo 
	void ComputeFromIndependentSamples(const Image3Df &src,const Image3Df &ref);
	//! Computation of joint histo using *linear* interpolation (smoother, much better quality results) 
	void ComputeFromDirectionalLinearInterpolation(const Image3Df &src,const Image3Df &ref,int dir);
public:
	//! Adds a display grid to joint histogram image. Only for visualisation purposes.
	void AddDisplayGrid();
	//! Computes total probability of a source bin (adds all corresponding ref bins) 
	float GetSrcBinTotalProba(int x);
	//! Compute median normalization fct
	Signal1Df MedianTransferFct();
	JointHistogram(const Image3Df &src,const Image3Df &ref,int _nbSrcBins=100,int _nbRefBins=400);
};

#endif// _Normalization_hpp
