#ifndef __RV_BLOB_H_INCLUDED_
#define __RV_BLOB_H_INCLUDED_

#include <rvb\rvtypes.h>
#include <rvb\rdg.h>
#include <rvb\anlz.h> 

/*
#ifdef BLOB_EXPORTS
#define BLOB_API __declspec(dllexport)
#else
#define BLOB_API __declspec(dllimport)
#endif
*/

#define BLOB_API  WINAPI


 

 

  

#define RV_COMP_DEF    0 //默认
#define RV_COMP_LIST   1 //列表组织方式
#define RV_COMP_TREE   2 //树形组织方式

#define RV_COMP_CHILD     10
#define RV_COMP_SIBLING   11

//#define RV_BT_UNK      -1   //default, 
//#define RV_BT_DEF      0   //default, 
//#define	RV_BT_LAB      1   //label ,编码仅支持CNTR和CLUST
//#define	RV_BT_MIXED    2   //组合的，合并的
//  
 

extern "C" RvBlob BLOB_API rvCreateBlob(  /*RvImage base=NULL*/);

//仅支持RAW, CLUSTER
extern "C" RvBlob BLOB_API rvCreateBlobEx(const RvImage image, RV_BLOB_ENCODER encoder);

//extern "C" RvBlob BLOB_API rvCreateBlobEx(RV_BLOB_TYPE type,  RvImage base=NULL);


//extern "C" RvBlob BLOB_API  rvCreateBlobEx(int left, int top, int width, int height/*, BOOL bExtended=FALSE*/);
extern "C" void BLOB_API  rvDestroyBlob(RvBlob blob);
//extern "C" void BLOB_API  rvDestroyBlobE1(RvBlob blob);


extern "C" void BLOB_API     rvbClear(RvBlob blob);
extern "C" BOOL   BLOB_API   rvbIsEmpty(const RvBlob blob);

//是否为正常的BLOB
extern "C" BOOL   BLOB_API   rvbIsNormal(const RvBlob blob);

//extern "C" int   BLOB_API   rvbGetType(const RvBlob blob);

 
extern "C" RV_BLOB_ENCODER   BLOB_API   rvbGetEncoder(const RvBlob blob);


extern "C" RvBlob BLOB_API   rvbClone(const RvBlob blob, RvBlob dest = NULL);

//指定坐标的像素是否为blob，该函数考虑blob在原图中的偏移量
extern "C" BOOL BLOB_API   rvbHitTest(const RvBlob blob, int x, int y);


//
////将二元图象转换成默认格式的BLOB对象（原图）
//extern "C" RvBlob   BLOB_API  rvTransformToBlob(RvImage imBin, RvBlob destBlob=NULL);
//
////目前，支持RV_BEC_RAW, RV_BEC_CLUST和RV_BEC_CNTR
//extern "C"  RvBlob  BLOB_API  rvTransformToLabel(RvImage imBin, RV_BLOB_ENCODER encoder = RV_BEC_CNTR, int tinySize=4, RvBlob destBlob = NULL);
//
////获得最大的前N个BLOB, 编码为CNTR
//extern "C"  RvBlob  BLOB_API  rvTransformToLabelE1(RvImage imBin, int maxCount =1,  RV_CONTOUR_CODE chainCoder = RV_CC_DEFAULT, RV_CONTOUR_TYPE types = RV_CT_ANY, int selectBy = RV_CF_PERIM,  RvBlob destBlob = NULL);
//
////CNTR编码，转换以后类型为LAB, 可以按照轮廓类型进行筛选
//extern "C"  RvBlob  BLOB_API  rvTransformToLabelE2(RvImage imBin,   RV_CONTOUR_CODE chainCoder , RV_CONTOUR_TYPE types, int minLength=14, BOOL bReserveBorder =TRUE,  RvBlob destBlob = NULL);
//
//
//
////获得最大的BLOB,CNTR编码, blob类型为默认类型(RBT_DEF)
//extern "C"  RvBlob  BLOB_API  rvTransformToBlobE1(RvImage imBin,   RvBlob destBlob = NULL);
//
////获得RV_BEC_CLUST编码BLOB（不分开）
//extern "C"  RvBlob  BLOB_API  rvTransformToBlobE2(RvImage imBin,   RvBlob destBlob = NULL);
//
////获得最大的BLOB, blob类型为默认类型(RBT_DEF)
//extern "C"  RvBlob  BLOB_API  rvTransformToBlobE3(RvImage imBin,   RV_CONTOUR_CODE chainCoder = RV_CC_DEFAULT,  RV_CONTOUR_TYPE types = RV_CT_ANY, RvBlob destBlob = NULL);
//
////获得最大BLOB, RAW, CLUST编码(外围矩形框最大)
//extern "C"  RvBlob  BLOB_API  rvTransformToBlobE4(RvImage imBin,    RV_BLOB_ENCODER encoder = RV_BEC_RAW, BOOL bConn8= TRUE, int tinySize =5,  RvBlob destBlob = NULL);
//

/////////////////////////////////////////////////////////
//   
//直接转换成BLOB，  编码DEF(RAW),
extern "C"  RvBlob  BLOB_API  rvTransToRawBlob(const RvImage imBin,  RvBlob destBlob = NULL);

//最大的BLOB或最大的前面N个blob，按照面积计算
//如seq=NULL, 最多返回1个
//上层程序应该将seqOut清空
//4连通性
extern "C"  int  BLOB_API  rvTransToRawBlobE1(const RvImage imBin, int maxCount =1, RvSequence seqOut = NULL);
 
//***********************************************
//直接转换成BLOB，  编码DEF(Cluster)
extern "C"  RvBlob  BLOB_API  rvTransToClusterBlob(const RvImage imBin,    RvBlob destBlob = NULL);
//最大的BLOB或最大的前面N个blob
//如seq=NULL, 最多返回1个
//上层程序应该将seqOut清空
//4连通性
extern "C"  int  BLOB_API  rvTransToClusterBlobE1(const RvImage imBin,  int maxCount =1,  RvSequence seqOut = NULL);
 
//如有，返回最大的blob,最小尺寸为7pix.
 extern "C"  RvBlob  BLOB_API  rvTransToContourBlob(const RvImage imBin,  RV_CONTOUR_CODE chainCoder = RV_CC_DEFAULT, /*RV_CONTOUR_FILTER filter = RV_CF_ANY,*/ RvBlob destBlob = NULL);

 //最大的BLOB或最大的前面N个blob
 //上层程序应该将seqOut清空
 extern "C"  int  BLOB_API  rvTransToContourBlobE1(const RvImage imBin,  int maxCount, RV_CONTOUR_CODE chainCoder = RV_CC_DEFAULT, RV_CONTOUR_FILTER filter = RV_CF_ANY, RvSequence seqOut = NULL);


//直接转换成BLOB(mip加速算法)，  CLUSTER
//如果没有BLOB，返回NULL
//使用rvbReleaseBlobList释放
extern "C"  RvSequence  BLOB_API  rvTransToClusterList(const RvImage imBin,   BOOL bConn8= FALSE, int mip=2);

//直接转换成BLOB，  RAW
//bConn8为保留参数
//使用rvbReleaseBlobList释放
//如果没有BLOB，返回NULL
extern "C"  RvSequence  BLOB_API  rvTransToRawList(const RvImage imBin,  BOOL bConn8= FALSE, int minSize =4);

///如果没有BLOB，返回NULL
//使用rvbReleaseBlobList释放
extern "C"  RvSequence  BLOB_API  rvTransToContourList(const RvImage imBin,   RV_CONTOUR_CODE chainCoder = RV_CC_DEFAULT, RV_CONTOUR_FILTER filter = RV_CF_ANY, int minSize = 4);
//提取最大的几个BLOB
extern "C"  RvSequence  BLOB_API  rvTransToContourListE1(const RvImage imBin,   RV_CONTOUR_CODE chainCoder = RV_CC_DEFAULT, RV_CONTOUR_FILTER filter = RV_CF_ANY, int maxCount =1);


//extern "C"  RvBlob  BLOB_API  rvTransformToLabelEx(RvImage imBin, RvBlob destBlob = NULL, int minWidth=4, int minHeight=4, BOOL bCutEdge=TRUE  );

//内部使用
 //extern "C" RvBlob   BLOB_API  rvTransformToContour(RvImage imBin, int chainType = ICV_RETR_EXTERNAL, int chainCoder = ICV_CHAIN_APPROX_NONE, int tinySize = 4, RvBlob destBlob=NULL);

extern "C"  RvImage BLOB_API  rvTransformToImage(const RvBlob blob, RvImage dest = NULL);

//如果过dest=null,处理在image里面, 该函数可以过滤掉空洞
//extern "C"  RvImage BLOB_API  rvGetMaxBlobImage(RvImage image );


extern "C"  RvMask BLOB_API  rvTransformToMask(const RvBlob blob , RvMask dest = NULL );

//CNTR类型，仅接受轮廓型BLOB,角度单位：度
//extern "C"  int BLOB_API  rvGetKeyPoints(const RvBlob blob, double minLen, double maxLen, double maxAngle, RvPoint_f64* pPointArray, int nArraySize);

//仅接受CNTR类型BLOB
//extern "C"  int BLOB_API  rvApproxEdge(const RvBlob blob, double accuracy, RvPoint_f64* pPointArray, int nArraySize);
//extern "C"  int BLOB_API  rvApproxEdgeE1(const RvBlob blob, int method, double minLen, double accuracy, BOOL bRecursive, RvPoint_f64* pPointArray, int nArraySize);

//获得轮廓
//extern "C"  const RvContour BLOB_API  rvbGetContourAt(const RvBlob blob, int index );

//获得图像数据
//extern "C"  const RvImage BLOB_API  rvbGetImageAt(const RvBlob blob, int index );


//cluster类型LAB类函数,
//外部程序不可以释放RvPoint* 
//extern "C"  const RvPoint* BLOB_API  rvbGetClusterDataAt(const RvBlob blob, int index);
//extern "C"  const RvPoint* BLOB_API  rvbGetClusterAt(const RvBlob blob, int index, int* pSize);

//extern "C"  int BLOB_API  rvbGetClusterSizeAt(const RvBlob blob, int index);

//CLUSTER类型的点数据
//外部程序不可以释放RvPoint* 
extern "C"  const RvPoint* BLOB_API  rvbGetClusterData(const RvBlob blob,   int* pSize = NULL);
extern "C"  int BLOB_API  rvbGetClusterSize(const RvBlob blob);




 
//将转成CLUSTER编码的BLOB，仅支持RV_BEC_DEF类型 
//extern "C"  RvBlob BLOB_API  rvbForceToNorm(RvBlob blob );




 
 
//transcode type
//该函数目前没有实现，仅用于将来升级
//#define RV_TC_RAW   0
//#define RV_TC_RLE   1
//extern "C" RvBlob   BLOB_API  rvbTranscode(RvBlob blob, int type);

 
extern "C" int  BLOB_API    rvbGetWidth(const RvBlob blob);
extern "C" int  BLOB_API    rvbGetHeight(const RvBlob blob);
 
 
//extern "C" void    BLOB_API   rvbSetBase(RvBlob blob, const RvImage image);
//extern "C" RvImage BLOB_API   rvbGetBase(const RvBlob blob);

extern "C" void  BLOB_API     rvbSetTag(RvBlob blob, int tag);
extern "C" int   BLOB_API     rvbGetTag(const RvBlob blob);

 
//几何信息,下面的函数不支持LAB
extern "C" RvPoint_f BLOB_API   rvbGetCentroid(const RvBlob blob );
extern "C" UINT  BLOB_API       rvbGetArea(const RvBlob blob  );
extern "C" RvBox2D BLOB_API  rvbGetBoundBox(  RvBlob blob );
extern "C" RvPoint  BLOB_API    rvbGetOffset(const RvBlob blob );
extern "C" RvRect  BLOB_API     rvbGetRect(const RvBlob blob);


//下面的函数需要设置BASE图象
//仅支持RAW, CLUSTER
extern "C"  UINT   BLOB_API    rvbGetSummary(const RvBlob blob, const RvImage image, double* pAvg, double* pVar );
extern "C"  double   BLOB_API  rvbGetSummaryF64(const RvBlob blob, const RvImage image, double* pAvg, double* pVar );
extern "C" double BLOB_API   rvbGetAverage(const RvBlob blob, const RvImage image, double* pVar );
extern "C" double BLOB_API   rvbGetVariance(const RvBlob blob, const RvImage image);
extern "C" double BLOB_API   rvbGetStrength(const RvBlob blob, const RvImage image);


//获得轮廓梯度,仅适用RBT_CNTR类型的BLOB
//extern "C" int BLOB_API rvbGetGrads(const RvBlob blob, int dir, int gap, int* pGradArray, int nArraySize);

//for contour blob only,
//如果pPointArray =NULL, nArraySize<=0将返回edge点数量,返回最外围轮廓边
extern "C" int BLOB_API rvbGetEdges(const RvBlob blob, RvPoint* pPointArray, int nArraySize);

//for contour blob only
//extern "C" int BLOB_API  rvbGetContourCount(RvBlob blob );
//for contour blob only
//extern "C" RvBlob BLOB_API rvbGetContourAt(RvBlob blob, int index, RvBlob dest=NULL);

//计算二值对象边界长度
extern "C" UINT BLOB_API rvbGetPerimeter(const RvBlob blob);


//计算一个二值对象的圆度，计算各向异性,r1/r2  描述一个二值区域的细长程度
extern "C" double BLOB_API rvbGetCircular(const RvBlob blob);
 
extern "C" double BLOB_API rvbGetDensity(const RvBlob blob, int part = RV_BSP_WHOLE, RvMask mask =NULL);

//计算二值对象的方向
extern "C" double  BLOB_API rvbGetSlope(const RvBlob blob);


//以下3个函数仅为内部使用
//获得BLOCK原始数据，原始数据由点云组成，这些点是动态生成，采用指针方式进行使用
// 类型为LAB
//返回的句柄数据与编码有关
//extern "C" const RV_HANDLE BLOB_API  rvbGetBlockData(RvBlob blob, int index);

//获得block成员的数量，类型为LAB
//extern "C" int BLOB_API  rvbGetBlockCount(RvBlob blob); 

//类型为DEF, 获得block原始数据的大小，对于CNTR编码为边缘点长度（数量），
//DEF编码为原始点数量。
//extern "C" UINT BLOB_API  rvbGetBulkSize(RvBlob blob); 


//#define rvbGetRowData(blob, index)   rvbGetBlockData((blob), (index))
//#define rvbGetRowCount(blob)         rvbGetBlockCount( blob  )

//for label blob only
// extern "C" int BLOB_API rvbFilter(RvBlob blob, int size );

 //blob filter type
//#define RV_BF_AREA    0
//#define RV_BF_PERI    1
//#define RV_BF_CIRC    2
//#define RV_BF_ANGLE   3
//extern "C" int BLOB_API rvbFilterE1(RvBlob blob, int size, int critera );


//for label blob only
 //如果bInner为TRUE，表示保留大于或等于lower，且小于upper的BLOB
 //如果bInner为FALSE，表示保留小于lower，或大于upper的BLOB
// extern "C" int BLOB_API rvbFilterEx(RvBlob blob, int lower, int upper, BOOL bInner=TRUE );
//extern "C" int BLOB_API rvbFilterE2(RvBlob blob, int lower, int upper, int critera ); //内部
//extern "C" int BLOB_API rvbFilterE3(RvBlob blob, int lower, int upper, int critera ); //外部



 //for label blob AND contour blob only
 //extern "C" void BLOB_API  rvbRemoveSpecific(RvBlob blob, int index );

 //for label blob only
 //extern "C" int BLOB_API  rvbGetLabelCount(RvBlob label );
 

 //for label blob only
 //用于输出的dest必须是RBT_DEF类型，如果dest 为NULL，将自动创建一个新的RvBlob
 //obsolete
//extern "C" RvBlob BLOB_API rvbGetSpecific(RvBlob label, int index, RvBlob dest=NULL);

//new interface
//LABEL 仅支持RV_BEC_CNTR, RV_BEC_CLUST编码
//extern "C" RvBlob BLOB_API rvbGetLabelAt(RvBlob blob, int index, RvBlob dest=NULL);
 

//Blob distance type
//计算blob之间最近的距离
#define RV_BD_DEFAULT    0  //质心距离
#define RV_BD_RECT       1  //外接矩形
#define RV_BD_FITBOX     2  //最小矩形
#define RV_BD_CONTOUR    3  //轮廓目前不支持，仅用于升级
extern "C" float BLOB_API rvbDistance(RvBlob blob0, RvBlob blob1, int type);


//////////////////////////////////combined blob relatives @10////////////////////////////////
//下面的函数暂时未实现
//rvbMerge按照链表方式合并
//将blob和dest合并，结果放在dest.
//blob和dest都不能为空。
//blob和dest支持RBT_DEF和 RBT_MIXED两种类型。
//如果dest为RBT_DEF, dest将变成RBT_MIXED
//合并后,blob将不再有效。
//返回dest。
extern "C" RvBlob BLOB_API rvbMerge(RvBlob blob, RvBlob dest);

//将blob和dest合并，结果放在dest，未实现
extern "C" RvBlob BLOB_API rvbMergeTree(RvBlob blob, int relation,  RvBlob dest);

//
//释放blob List, 如果需要，客户程序必须另外调用rvDestroySequence(seq)
//释放seq。
//
extern "C" void BLOB_API rvbReleaseBlobList(RvSequence seq);

//该函数除了释放blob外，还调用rvDestroySequence(seq)释放seq。
extern "C" void BLOB_API rvReleaseBlobList(RvSequence& seq);

//将blob沿长度或宽度方向，按照一定的比例进行拆分，头部分放在dest里面。
//剩下部分放在原来部分，类型必需为默认
//extern "C" RvBlob BLOB_API rvbSplit(RvBlob blob, int direct, float ratio, RvBlob dest);

//////////////////////////////////////////////end of @10/////////////////////////////////////

#endif