
#ifndef __RV_CVFS_H_INCLUDED_
#define __RV_CVFS_H_INCLUDED_

 
    #include <rvb\rvtypes.h>
 

#define CVFS_API  WINAPI


//box2d规范化类型
//RECALC - 重新计算
//SWAP_CW - 顺时针交换
//SWAP_CCW - 逆时针交换
#define IRV_BN_NONE         0
#define IRV_BN_RECALC       1
#define IRV_BN_SWAP_CW      2
#define IRV_BN_SWAP_CCW     3

 
#define IRV_MAX_CHILD_CONTOURS    124
//get_contour_chain descriptor
typedef struct __irv_gcc_contour_
{
	int      level;      
	BOOL     bIsHole;
	int      count;
	RvPoint* pPtArr;
}IRV_GCC_CONTOUR;

typedef struct __irv_gcc_descriptor_
{
	int              type;
	IRV_GCC_CONTOUR* pRoot;
	int              childCount;
	IRV_GCC_CONTOUR* pChildArr[IRV_MAX_CHILD_CONTOURS];
}IRV_GCC_DESCRIPTOR;

#define ICV_MOP_OPEN         2
#define ICV_MOP_CLOSE        3
#define ICV_MOP_GRADIENT     4
#define ICV_MOP_TOPHAT       5
#define ICV_MOP_BLACKHAT     6

extern "C"  RvImage CVFS_API  irvMorphology(RvImage image,  int type, int times);


extern "C" void CVFS_API irvAdaptive(RvImage image, int method, int blockSize, double param1);


extern "C"  RvImage CVFS_API  irvErode(RvImage image, int times);
extern "C"  RvImage CVFS_API  irvDilate(RvImage image, int times);

extern "C" 	RvImage CVFS_API  irvSmooth(RvImage image, int type, RvSize kernelSize, double option1, double option2);
extern "C" RvImage CVFS_API   irvScharr(RvImage image, int direct);
extern "C" RvImage CVFS_API  irvCanny( RvImage image, double lowThresh, double highThresh, int aperture );
extern "C" RvImage CVFS_API   irvWarp(const RvImage image,  RvPoint_f* pSrcControls, RvPoint_f* pDestControls, RvImage dest );
extern "C" RvImage CVFS_API   irvWarpE1(const RvImage imSrc,  const RvPoint_f* pSrcControls, RvImage imDst, const RvPoint_f* pDestControls, BOOL bFillOutliers, RvColor fillColor );

extern "C" RvImage CVFS_API   irvPyramid(const RvImage image, BOOL bUp,  RvImage dest );



extern "C" void CVFS_API irvCalcMoment(const RvImage image, double* pM00, double* pM01, double* pM10);

//extern "C" RvBox2D CVFS_API irvGetBoundBox(const RvImage image );
extern "C" RvBox2D CVFS_API irvGetBoundBoxE2(RvPoint* pPtArr, int size );
extern "C" RvBox2D CVFS_API irvGetBoundBoxE1(RvPoint_f* pPtArr, int size );
extern "C" RvBox2D CVFS_API irvGetBoundBoxE3(RvPoint_f64* pPtArr, int size );




//chain mode
//产生和销毁contour chain链表，
// mode must be one of the following values
#define ICV_RETR_EXTERNAL   0 //retrives only the extreme outer contours
#define ICV_RETR_LIST       1 //retrieves all of the contours and puts them in the list
#define ICV_RETR_CCOMP      2 //retrieves all of the contours and organizes them into a two-level hierarchy:
//on the top level are the external boundaries of the components, on the second level are
//the boundaries of the holes
#define ICV_RETR_TREE       3 //retrieves all of the contours and reconstructs the full hierarchy of nested contours

//chain encoder
#define ICV_CHAIN_CODE               0
#define ICV_CHAIN_APPROX_NONE        1
#define ICV_CHAIN_APPROX_SIMPLE      2
#define ICV_CHAIN_APPROX_TC89_L1     3
#define ICV_CHAIN_APPROX_TC89_KCOS   4
#define ICV_LINK_RUNS                5

#define RV_GBB_MAX_LEN      1
#define RV_GBB_MAX_SIZE     (1<<1)
#define RV_GBB_NORMAL       (1<<2)


//extern "C" RvBox2D CVFS_API irvGetBoundBoxV2(const RvImage image, int structure = ICV_RETR_EXTERNAL, int approx = ICV_CHAIN_APPROX_NONE, int flags=RV_GBB_MAX_LEN );


  

//产生和销毁bound box 2d链表，
//irvRelBoxChain仅仅释放链表里面的内容，不释放sequence本身
//如果minWidth, minHeight, maxWidth, maxHeight小于等于0,将不限制该条件
//sequence必须为RDT_HANDLE数据类型
//extern "C" int      CVFS_API irvGenBoxChain(const RvImage image,  int minWidth , int minHeight, int maxWidth, int maxHeight, BOOL bExternal, RvSequence sequence );
//extern "C" void     CVFS_API irvRelBoxChain(RvSequence sequence);



// extern "C" int      CVFS_API irvGenContourChain(const RvImage image, int mode, int encoder, RvSequence sequence);

//最大的CONTOUR，
//extern "C" int      CVFS_API irvGenContourChainE1(const RvImage image,    RvSequence sequence, void* pStorage );

//小于最小周长的contour忽略,如果minLength<=0，将提取所有的轮廓。
extern "C" int      CVFS_API irvGetContourChain(const RvImage image,  int structure, int approx,   int minLength, RvSequence sequence);

//周长最大
extern "C" IRV_GCC_DESCRIPTOR*  CVFS_API irvGetMaxChain(const RvImage image,  int structure, int approx);

//释放由irvGetContourChain生成的描述符
extern "C" void     CVFS_API irvReleaseGccDescriptor(IRV_GCC_DESCRIPTOR* pDescriptor);

//提取轮廓到树里面,轮廓成嵌套的组织结构,没有实现，放在cvcls实现
extern "C" int      CVFS_API irvGetContourChainE1(const RvImage image,  int approx, RvTree tree);



//提取轮廓并保存为LIST, TREE, 或单个的contour， 由irvRelContourChainE2释放
//data wrapper
#define GCC_PLAIN    0
#define GCC_SEQ      1
#define GCC_EXTRA   -1

//contour type
#define GCC_NORMAL       ICV_RETR_EXTERNAL  
#define GCC_LIST         ICV_RETR_LIST  
#define GCC_TREE         ICV_RETR_TREE 
#define GCC_CLUST        4
//extern "C" HANDLE     CVFS_API irvGenContourChainE2(const RvImage image, int type, int coder, int wrapper = GCC_PLAIN);

//释放irvGenContourChainE2生成的轮廓链
//extern "C" void     CVFS_API   irvRelContourChainE2(HANDLE hContour);




//extern "C" void     CVFS_API irvRelContourChain(RvSequence sequence);

//extern "C" void     CVFS_API irvRemoveChain(RvSequence sequence, int index);


//extern "C" void*  CVFS_API irvCreateStorage(int nBlockSize=0);
//extern "C" void   CVFS_API irvDestroyStorage(void* pStorage);

//note 1///////////////////////////////////////////////////////////
//下面几个函数都假设Chain点位原始点，非压缩，即ICV_CHAIN_APPROX_NONE。
//extern "C" int   CVFS_API irvGetChainElems(RvSequence sequence, int index,  RvPoint* pPointArray, int nArraySize);
//extern "C" int   CVFS_API irvGetChainLength(RvSequence sequence, int index=-1);
//extern "C" void   CVFS_API irvPrintChain(RvSequence sequence, int index, int offsetX, int offsetY, RvImage image );
//获取梯度
//HORI: x2-x1, VERT: y2-y1  BOTH: sqrt((x2-x1) *  (x2-x1)+ (y2-y1) *  (y2-y1))
//extern "C" int   CVFS_API irvGetChainGrad(RvSequence sequence, int index,  int dir, int gap, int* pGradArray, int nArraySize);

//end of note1///////////////////////////////////////////////////////

#define ICV_CP_AREA       0  //面积，注意chain必需是external。否则可能会重复计算
#define ICV_CP_PERIM      1  //周长
#define ICV_CP_ANGLE      2  //角度(只能计算单个contour )
#define ICV_CP_CIRCULAR   3  //长宽比（圆度）(只能计算单个contour )
#define ICV_CP_KEYPOS     4  //关键点数量
#define ICV_CP_RAWPOS     5  //原始点数量

//extern "C" double   CVFS_API irvGetChainProperty(RvSequence sequence, int index, int type);
  
//前N最大的轮廓
//structure = ICV_RETR_EXTERNAL, approx =ICV_CHAIN_APPROX_NONE, selectBy = ICV_CP_AREA
//extern "C" int      CVFS_API irvGenContourChainE3(const RvImage image,   int maxNum, int structure , int approx, int selectBy, RvSequence sequence, void* pStorage );



//外接矩形,非最小
//extern "C" RvRect   CVFS_API irvGetChainRect(RvSequence sequence);

//sequence里面第一个contour
//extern "C" RvBox2D   CVFS_API irvGetChainBox(RvSequence sequence);


//共5个参数，第一个参数为最小的长度
#define RV_GCKP_DEFAULT     1

//两边距离rpa和rpb在dmin和dmax之间，theta ab<theta max的三角形找出了。
//然后保留对于距离dn（dn的大小不得超过dmax）有最小夹角theta ab的所有点p。
//dmin，dmax，dn，和theta的典型值可以是7,9,9,150
//（最好一个参数是以度数为单位的角的大小）。

//extern "C" int   CVFS_API irvGetChainKeyPoints(RvSequence sequence, int index, int method, double* pParamSet, int nSetSize, RvPoint_f64* pVertexArray, int nArraySize);
 

//cvApproxPoly
//目前只可使用CV_POLY_APPROx_DP.另外两个参数为逼近算法参数(目前只用到第一个).
//	eps参数指定逼近的精度.如果想了解这个参数如何起作用的的必须仔细了解具体的算法.
//	最后一个参数指定是否针对全部的轮廓(通过h_next和v_next可达的)进行逼近
//如果为0,则表示只处理src_seq指向轮廓.
#define RV_AC_DEFAULT     0
//extern "C" int   CVFS_API irvApproxChain(RvSequence sequence, int index, int method, double minLen, double eps, BOOL bRecursive, RvPoint_f64* pVertexArray, int nArraySize);


////////////////////////////////////////////////////////////////////////////////////////////////

 //if index <0, clone all chains in seq.
//extern "C" void   CVFS_API irvCloneChains(RvSequence src, int index,  RvSequence dest, void* pStorage);

//按照条件，保留最大的前几条chain图像
//extern "C" BOOL   CVFS_API irvFilterImageByChain(RvImage image, int maxNum, int  selectBy);


 



//图象增强和参数调整函数
extern "C"  void CVFS_API irvAdjustBrightYIQ(RvImage image, int yLimit  ,int iLimit ,int qLimit  );

extern "C" void CVFS_API irvDefog(RvImage image );

extern "C" void CVFS_API irvSharpenGs(RvImage image, int kernelSize );
extern "C" void CVFS_API irvBlurGs(RvImage image, int kernelSize );


#define IRV_HSV_HUE   0
#define IRV_HSV_VALUE 1
#define IRV_HSV_SAT   2 
extern "C" void CVFS_API irvAdjustHSV (RvImage image, int channel, double percentage);

//mask 为输出
//irvFloodFillM FLAGS
#define IRV_FF_DEFAULT_RANGE   0
#define IRV_FF_FIXED_RANGE     (1 << 16)
 

//irvFloodFillM connectivity
#define IRV_FF_CONN4    4
#define IRV_FF_CONN8    8

//该函数成功调用以后，输出的mask图将比image的长和宽分别多2个像素
//输入的mask图大小将自动调整大小
RvImage  CVFS_API  irvFloodFillM(const RvImage image, GPoint pos,  RvScalar_f64 lower, RvScalar_f64 upper, int connectivity = IRV_FF_CONN4, int flags =0 , RvImage imMask = NULL);


void  CVFS_API  irvFloodFill(RvImage image, GPoint pos, RvRgb newColor, RvScalar_f64 lodiff, RvScalar_f64 updiff, int connectivity =IRV_FF_CONN4, int flags =0 );




//image: RIT_GRAY
//minDist: 5
//winSize: 5
//zeroSize: -1
//nArraySize: 最大256
int  CVFS_API  irvFindCorner(RvImage image, int minDist, int winSize, int zeroSize,  RvFloat32 accuracy, RvPoint_f* pPosArray, int nArraySize);

//#define 
#define IRV_DIST_L1      1  
#define IRV_DIST_L2      2   
#define IRV_DIST_C       3  
#define IRV_DIST_L12     4   
#define IRV_DIST_FAIR    5    
#define IRV_DIST_WELSCH  6    
#define IRV_DIST_HUBER   7    

//pLineCoef必须为大于或等于4长度的数组，如果为5表示计算直线度
//默认：  reps(0.01), aeps(0.01)
extern "C"  BOOL CVFS_API irvFitLine(RvPoint_f64* pEdgeSet, int nSetSize , int method,  double reps, double aeps,  RvFloat* pLineCoef, int nCoefSize =4) ;
extern "C" BOOL CVFS_API irvFitLineE1(RvPoint* pEdgeSet, int nSetSize , int method,  double reps, double aeps,  RvFloat* pLineCoef, int nCoefSize =4) ;

//accuracy = 0.01
extern "C" int CVFS_API irvApploxPoly(const RvPoint* pEdgeSet, int nSetSize , double accuracy, BOOL bClosed, RvPoint* pPolySet, int nPolySize) ;


//norm : IRV_BN_NONE
//bNormalize为TRUE, 将规范化输出，否则为原始数据
//默认为FALSE
extern "C"  BOOL CVFS_API irvFitEllipse(RvPoint_f64* pEdgeSet, int nSetSize , int norm, RvBox2D* pBox2d ) ;
extern "C"  BOOL CVFS_API irvFitEllipseE1(RvPoint* pEdgeSet, int nSetSize , int norm, RvBox2D* pBox2d ) ;



#define IRV_CONTOURS_MATCH_I1  1
#define IRV_CONTOURS_MATCH_I2  2
#define IRV_CONTOURS_MATCH_I3  3
double CVFS_API irvMatchContour(const RvBlob cntr1,  const RvBlob cntr2, int method, double param =0 ) ;
 


//spk边缘结构
typedef struct __rv_spk_edges_{
	int				modelHeight;	 
	int				modelWidth;		 
	RvPoint			centerOfGravity;	 
    int		     	numOfCordinates;		         
	RvPoint			*pCoordinates;		 
	double			*pEdgeMagnitude;	 
	double			*pEdgeDerivativeX;	 
	double			*pEdgeDerivativeY;	 
}RvSpkEdges;

RvSpkEdges* CVFS_API irvCreateSpkEdges(const RvImage image, int minBright, int maxBright, const RvMask mask=NULL );
RvSpkEdges* CVFS_API irvCreateSpkEdgesE1(int count);
void     CVFS_API irvDestroySpkEdges(RvSpkEdges* pSpkEdges);
double   CVFS_API irvFitSpkEdges(RvSpkEdges* pSpkEdges,  const RvImage image, double speedRate, double minScore, RvPoint* pPosFind = NULL);



//ECD UTILS
#define ECD_RESAMPLE_NONE    0
#define ECD_RESAMPLE_LOW     2
#define ECD_RESAMPLE_MEDIAN  4
#define ECD_RESAMPLE_HIGH    8

//#define ECD_ACCURACY_NORMAL   0
//#define ECD_ACCURACY_LOW      1
//#define ECD_ACCURACY_MEDIAN   2
//#define ECD_ACCURACY_HIGH     3






//////////////////////////original ECD////////////////////////// 
//#define IRV_ECD_CLOSED    (1<<16)  
//#define IRV_ECD_COMPACT   (1<<17)  
//
//typedef struct __irv_ecd_cntr_
//{
//	int             opts;   //选项
//	int		     	count;
//	int*            pFlags; //IRV_ECD_POSIT， IRV_ECD_EXCLUDE
//	RvPoint	  		*pPts;  //边缘点	 
//	IRV_SE_FLOAT	*pMags; //强度 
//	IRV_SE_FLOAT	*pDx;   //梯度X	 
//	IRV_SE_FLOAT	*pDy;	//梯度Y
//}iRvEcdCntr;
//
//typedef struct __rv_extended_contour_descriptor{
//	int				width;
//	int				height;	 
//	RvPoint			centroid;
//	RvRect          rect;
//	int             total;  //valid point count
//	int             contourCount;
//    iRvEcdCntr**    ppArrContour;
//}RvEcd;
//
//
//
//extern "C" RvEcd* CVFS_API   irvCreateEcd(const RvImage image, int strength, int minBright, int maxBright, int resample, int minVertex,const RvMask mask=NULL );
//extern "C" RvEcd* CVFS_API   irvCreateEcdHeader(int count, int width=0, int height=0);
//extern "C" void     CVFS_API irvDestroyEcd(RvEcd*  pEcd);
//
//extern "C" RvEcd*     CVFS_API irvCloneEcd(RvEcd*  pEcd);
//
//
//extern "C" iRvEcdCntr* CVFS_API irvCreateEcdContour(int length, int opts);
//extern "C" void CVFS_API irvDestroyEcdContour(iRvEcdCntr* pEcdCntr);
//
//extern "C" iRvEcdCntr*  CVFS_API irvCloneEcdContour(iRvEcdCntr* pEcdCntr);
//
//extern "C" BOOL    CVFS_API irvUpdateEcdHeader(RvEcd* pEcd, int minVertex);
//extern "C" HANDLE  CVFS_API irvCreateEcdMaps(const RvImage image, int strength);
//extern "C" void     CVFS_API irvDestroyEcdMaps(HANDLE hEcdMaps);
 extern "C" RvImage   CVFS_API irvProcessEcdImage(const RvImage image, int strencth, int minBright, int maxBright);
// 
//extern "C" int   CVFS_API irvRegisterEcd(RvEcd* pEcd,  const RvImage image, int strength,  double overlap, double force, double minScore, RvPoint* pPtsArray, double* pScoreArray, int arraySize);
//extern "C" double   CVFS_API irvRegisterEcdE1(RvEcd* pEcd,  HANDLE hEcdMaps, RvPoint curpos, RvDiff toler, int strength,  double overlap, double force, double minScore, RvPoint* pFindPos);
//
//extern "C" int   CVFS_API irvRegisterEcdE2(RvEcd* pEcd,  HANDLE hEcdMaps, int strength,  double overlap, double force, double minScore, RvPoint* pPtsArray, double* pScoreArray, int arraySize);

///////*******************************************************
////////////ecd contour e1//////////////////////////////////////
#define MIN_VERTEX_COUNT     4

#ifdef  _WIN32
    #define IRV_SE_FLOAT   float
#endif
#define IRV_ECD_EXCLUDE    1  //是否排除

//   x,y不用对调
typedef struct __irv_ecd_cntr_e1_
{
	int				width;
	int				height;	 
	//RvPoint			centroid; //去掉之心，感觉没有多大用，直接使用图像中心
	int		     	count;
	int             posCnt;    //剔除排除的点以后的数量。
	RvBox2D         boundBox;  //用于计算重叠程度
	int*            pFlags; //IRV_ECD_POSIT， IRV_ECD_EXCLUDE
	RvPoint	  		*pPts;  //边缘点	 
	IRV_SE_FLOAT	*pMags; //强度 
	IRV_SE_FLOAT	*pDx;   //梯度X	 
	IRV_SE_FLOAT	*pDy;	//梯度Y
}iRvEcdCntrE1;



extern "C" iRvEcdCntrE1* CVFS_API   irvCreateEcdE1(const RvImage image, int strength, int minBright, int maxBright, int resample, int minVertex, const RvMask mask=NULL);

//场景点只按照强度的选择点，没有强度和梯度数据，只有点位置信息
//场景特征点没有规范化成0, 0为中心的点
extern "C" iRvEcdCntrE1* CVFS_API   irvCreateSceneEcdE1(const RvImage image, int strength, int minBright, int maxBright, int resample, int minVertex);

extern "C" iRvEcdCntrE1* CVFS_API   irvCreateEcdHeaderE1(int count/*, int width=0, int height=0*/);

extern "C" void   CVFS_API  irvDestroyEcdE1(iRvEcdCntrE1*  pEcd);
extern "C" iRvEcdCntrE1*   CVFS_API  irvCloneEcdE1(iRvEcdCntrE1*  pEcd);

//查找多个实例
extern "C" int   CVFS_API irvFindEcdE1(iRvEcdCntrE1** pEcdArray, int nEcdCount, const RvImage image,    double overlap, double force,  double minScore, int* pIdxArray, RvPoint* pPtsArray, double* pScoreArray, int arraySize);

//查找单个实例
//输出结果：int* pEcdIndex, RvPoint* pPosFind, double* pScore
//          点坐标：为模板质心为基点的位置(不是左上角，也不是模板中心位置)
extern "C" int   CVFS_API irvMatchEcdE1(iRvEcdCntrE1** pEcdArray, int nEcdCount, const RvImage image,    double force,   double minScore, int* pEcdIndex, RvPoint* pPosFind, double* pScore);

//指定位置在一定范围内查找,
extern "C" int   CVFS_API irvRefineEcdE1(iRvEcdCntrE1** pEcdArray, int nEcdCount, const RvImage image,   RvPoint pt, RvSize tolerSize, double force, double minScore, int* pEcdIndex, RvPoint* pPosFind, double* pScore);

 //按照惯量方式求得角度，质心，长宽
typedef struct __rv_contour_profile_
{
	double angle;            //角度
	RvPoint_f centroid;      //质心，非中心（最小圆）
	RvSize_f  size;          //长宽
	double    diameter;      //直径
	double    perimeter;     //周长
	double    area;          //面积
	double    roundness;     //圆滑度
	double    eccentricity;  //离心率
}RV_CONTOUR_PROFILE;

#define IRV_CCP_ANGLE           1
#define IRV_CCP_CENTROID        ( 1 <<1)
#define IRV_CCP_SIZE            ( 1 <<2)
#define IRV_CCP_PERIMETER       ( 1 <<3)
#define IRV_CCP_DIAMETER        ( 1 <<4)
#define IRV_CCP_AREA            ( 1 <<5)
#define IRV_CCP_ROUNDNESS       ( 1 <<6)
#define IRV_CCP_ECCENTRICITY    ( 1 <<7)
//角度没有经过进一步处理，原始角度
BOOL  CVFS_API   irvCalcContourProfile(const RvPoint* pPtArr, int count, int flags, RV_CONTOUR_PROFILE* pProfile);

//IRV_CCP_ANGLE, IRV_CCP_CENTROID, IRV_CCP_AREA only
BOOL  CVFS_API   irvCalcBinaryProfile(const RvImage image, int flags, RV_CONTOUR_PROFILE* pProfile);


#define IRV_CC_MATCH1    1
#define IRV_CC_MATCH2    2
#define IRV_CC_MATCH3    3
BOOL  CVFS_API   irvCompareContour(const RvPoint* pPtArr1 , int arr1Count, const RvPoint* pPtArr2 , int arr2Count, int method, double& threshold );


#endif
