 
#if !defined(__RV_PIXEL_MATCH_H_INCLUDED_)
#define      __RV_PIXEL_MATCH_H_INCLUDED_

#include "PatMat.h" 
#include <cali\MatchCal.h>
#include <rvb\pmat.h>
 




class PATMAT_API CPixelMatch :	public CMatchCal
{
public:
	CPixelMatch(void);
	virtual ~CPixelMatch(void);

	//image match method
	//小于PM_CNTRFIT的为相关性方法
	//大于的为定制的算法
	enum MATCH_METHOD{		 
		 PM_DIFF   = RV_MP_ABSDIFF_N , 
		 PM_SQDIFF = RV_MP_SQDIFF_N,
		 PM_CCORR  = RV_MP_CCORR_N,
		 PM_CCOEFF = RV_MP_CCOEFF_N,
		 PM_CNTRFIT   = 101,        //轮廓特征匹配,该方法在CEdgeFit类中支持
	};
   
	

	virtual BOOL Serialize(HANDLE device, BOOL bIn );
	virtual CUCObj* Clone(  CUCObj *twin) ;
	 
	virtual BOOL  Create(/*CDelegate* pDelegate ,*/ const TCHAR* strName = NULL, UINT id = -1, int style = RV_UC_DEFAULT_STYLE ) ;

	virtual BOOL    Learn(const RvImage image=NULL, int* pErrCode = NULL) ;
	virtual int     Recognize(const RvImage image=NULL, int* pErrCode = NULL);

	 
	//virtual void Reset();

	int  GetMatchMethod(){ return m_nMatchMethod; };
	void SetMatchMethod(MATCH_METHOD method) ;//{ m_nMatchMethod = method;  };

	void SetInitScore(float score);
	float GetInitScore(){ return m_nInitScore;};

	void SetMinScore(float score);
	float GetMinScore() { return m_nMinScore; };
	 

	//获取当前匹配的进展
	int GetReductionStep(){  return  m_nReductionStep; };
	int GetSampleIndex(){  return  m_nSampleIndex; };
 

	//获取模板各种属性
	virtual int GetPatternCount(){return m_nPatternCount;};	 
	virtual void* GetPatternSet(){ return m_pPatternSet; };


	virtual RvImage GetPatternImage(int mipLevel, int pattIndex,  int angleIndex);
	virtual RvMask  GetPatternMask(int mipLevel, int pattIndex,  int angleIndex);

	virtual void    GetPatternFreedom(int index, float* pScaleX, float* pScaleY, float* pAngle);
	virtual RvPoint_f GetPatternCenter(int index);
	
	//最顶层的模板样品图像的宽度和高度
	virtual int  GetPatternWidth(int index);
	virtual int  GetPatternHeight(int index);
	   
	int GetLearnedCoarseLevel() { return m_nLearnedCoarseLevel;};
	int GetLearnedFineLevel()   { return m_nLearnedFineLevel;};
	double GetLearnedCoarseAngleReso() { return  m_nLearnedCoarseAngleReso; }
	double GetLearnedFineAngleReso() { return  m_nLearnedFineAngleReso; }

	double GetLearnedStartAngle() { return  m_nLearnedStartAngle; }

	int GetLearnedCoarseAngleCount() { return  m_nLearnedCoarseAngleCount; }
	int GetLearnedFineAngleCount() { return  m_nLearnedFineAngleCount; }

	BOOL   IsRotationSupported(){ return m_bRotationSupported; };

	float    GetLearnedScaleReso(){ return m_nLearnedScaleReso ;};
	RvPoint_f  GetLearnedPos(){ return m_learnedCenter ;};

	 
	//降维的次数,输入模板图像大小，获得满足条件的降维次数，
	//0,表示不降，1降低1倍,,...
	//int CalcReductionCount(int width, int height);

//	virtual void SetMaxInstances(int count);
//	virtual void SetMaxInitInstances(int count);

public:
	BOOL       m_bBruteSearch;   //暴力搜索,用于粗级搜索
	int        m_nFilterType;
	BOOL       m_bCoarseOnly;   //仅糙匹配
	int        m_nCoarseReso;     //糙金字塔 
	int        m_nFineReso;       //精金字塔层，   

	//原始模板图像最大尺寸，如果超出将自动使用MIP图
	//该参数影响m_nLearnedMipLevel参数
	//识别阶段，搜索区图像应该相应地根据m_nLearnedMipLevel
	//降低尺寸
	UINT     m_nMaxPatternSize;

	//降维之后最小的图象面积
	UINT    m_nMinPatternSize;      
	 

	//角度初始细分,默认1/16
	//圆周为360，该参数与圆周角度乘积，得出一个初始角度
	//控制查找圆周方向模板的速度
	float m_nAngleBoost;


	//粗查找步长，范围0-1,默认为0.3
	//或加速度, 暗示度, 角度范围系数等（不同算法解释不一样）
	float m_nSearchForce;
	 

    //For debug only
	void DumpPatterns(const TCHAR* strFilePath, BOOL bCoarsePattern);

	//For storage consistent
	BOOL WriteSample(HANDLE device,void* pPatternSet, int size);
	BOOL ReadSample(HANDLE device,void** ppPatternSet, int* pPatterSize);
	void CloneSamples(void* pSourceSet, int nSrcSize, void** ppDestSet, int* pDestSize);

protected:
	  virtual RV_HANDLE DrawPatternInstances(HGDC dc, RV_HANDLE hStroke);

	  int  FindFineAngleIndex(int coarseAndleIndex);

	//初始化和释放临时的结果数组
//	BOOL InitMatchResultArray(void* pPatSet, int setCount, int maxInstance);
//	 void RelMatchResultArray();
	
	//RvImage CloneImage(const RvImage image, float scaleX, float scaleY );
	void SetInitPatt(void* pPatt, RvImage image, RvImage imMask, int coarseLevel , int fineLevel);
	
	//角度需要统一换算成角度单位，所以不能与比例一样，仅传入行或列。
	void InitScaledPatt(void* pPatSet, int setCount, const RvImage image, const RvImage imMask, BOOL bAniso, int cols, int rows);

	BOOL GenRotatedSamples(void* pPatSet, int setCount, BOOL bFixedAngleReso=FALSE);
	RvImage*  GenSceneMips(const RvImage image, int& nImageCount );
	
	  
	void  RelScenceMips( RvImage* pImageArray, int  nImageCount );

	//IMAGE, MASK都是输入输出
	int CheckPatternSize(RvImage image, int mipLevel, int maxsize, BOOL bCheckMax);
	//void CheckSceneSize(RvImage image, int mipLevels);

	int DoMatch(RvImage* pSceneMip, int nImageCount/*, int nPoiType, RvMask* pMaskMip*/);
	//int MatchSinglePattern(  void* pPattSet, RvImage* pSceneMip, int nImageCount, /*int poitype, RvMask* pMaskMip,*/ float initScore, float minScore);

	int ChooseResults(PM_MATCH_RESULT*  pMatResultArr,  int resultCount, int expectedCount);

//	void GetMaxScore(const RvImage imScene, const RvImage imPat, const RvMask mask,   MpResult* pResult);
	//void Evolve(const RvImage imScene, const RvImage imPat, const RvMask mask, int x0, int y0,   MpResult* pResult);
	

	//void NormalScore(MpResult* pResult, int count);
	 

	void ReleasePatSet(void** ppPatternSet, int* pSize);


	BOOL BuildSampleTree(const RvImage image, const RvMask mask, int left, int top);

	//inline float GetRealScore(int method, float score) 
	//{
	//	if (method == PM_DIFF) return (1.0f - score);
	//	if (method == PM_SQDIFF) return (1.0f - score);

	//	if (PM_CCORR == method) return (  score);
	//	if (PM_CCOEFF == method) return (  score);

	//	return score;
	//};

protected:

	int      m_nLearnedFineLevel;
	int      m_nLearnedCoarseLevel;
	double   m_nLearnedCoarseAngleReso ;
	double   m_nLearnedFineAngleReso ;
	
	BOOL     m_bRotationSupported; //表示学习后的模板支持旋转

	int      m_nLearnedCoarseAngleCount ;
	int      m_nLearnedFineAngleCount;

	double   m_nLearnedStartAngle;
	float    m_nLearnedScaleReso;
	//float    m_nLearnedScaleYReso;


	RvPoint_f  m_learnedCenter; //学习的中心位置

	

	//用于显示当前匹配的进程。运行时变量
	int  m_nSampleIndex;
	int  m_nReductionStep;
	//*******************************

	//插值类型
	//int   m_nFilterType;
	int   m_nMatchMethod;
	 
	 
	//double m_nMinAngle; //学习以后最小角度，以度为单位。用于最终模板匹配

	float  m_nMinScore;  //最小分数，阈值, 0-1.0
	float  m_nInitScore; //初始分数,       0-1.0
	 
	//缩放样本的数量和旋转样本数量 
    //int    m_nScaleCount, m_nRotationCount;
	//**************************************
	 

	int    m_nPatternCount;
	void*  m_pPatternSet;

	////检测结果，每种实例对应一组
	////临时变量
	//int        m_pattFindSize;// 
	//int        m_patternFindCount; 
	//MpResult*  m_patternFindArray; 
			 
private:
 
	  
};




#endif


