// BlobExtractor.h: interface for the CBlobExtractor class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(__RV_BLOB_EXTRACTOR_H_INCLUDED_)
#define __RV_BLOB_EXTRACTOR_H_INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "AreaCal.h"
#include <rvb\rvtypes.h>


#define BE_MAX_SIZE    (65535)
#define BE_MIN_SIZE    (16)
//#define BE_MAX_COUNT    1028




class CALIX_API CBlobExtractor : public CAreaCal  
{
public:
	CBlobExtractor();
    virtual ~CBlobExtractor();

	//display style
	enum{
		BE_DEFAULT = RS_DEFAULT,
		BE_SOLID = RS_SOLID ,
		BE_GRID = RS_GRID ,
		BE_DIAG = RS_DIAG  ,
		BE_CROSS = RS_CROSS ,
		BE_OUTLINE = RS_OUTLINE,
		BE_PREVIEW = RS_PREVIEW,  //显示原图(不是二值图)
		BE_BLOB_COLORED,          //已经分割
		BE_BLOB_ENCLOSED,         //BOX2D
		BE_BOUND_RECT,            //chang
	};

	//make real type
	enum MAKE_REAL{
		BE_MR_NONE = -1,
		BE_MR_DILATE =0, // dilate only
		BE_MR_ERODE, // erode only
		BE_MR_DFEL , //dilate first, erode last 
		BE_MR_EFDL , //erode first, dilate last
	};

	//segment mode
	enum {
		BE_SM_DEFAULT=0,   //按照默认方法进行分割
		BE_SM_EXTERNAL,    //最外围轮廓作为一个物体,里面隶属的轮廓忽略，仅支持CNTR编码
		BE_SM_NOTSEG=100,    //所有BLOB作为一个物体(即不分割)，仅支持RAW,CLUSTER编码
	};
	 
	//enum {
	//   BE_RAW     = RV_BEC_RAW,
	//   BE_CLUSTER = RV_BEC_CLUST,
	//   BE_CONTOUR = RV_BEC_CNTR,
	//};

	//filter type
	//因涉及排序取消前最大N个刷选类型，降低逻辑处理
	enum {
		BE_FT_MINSIZE =0, //大于最小尺寸,结果:N
		BE_FT_INRANGE,    //区间大小,结果:N
		BE_FT_MAXSIZE,    //最大尺寸，结果:1
		BE_FT_MINCIRC,    //最小圆度, 大于最小圆度，结果N
		BE_FT_MAXCIRC,    //最大圆度，结果1
	};

	virtual BOOL Serialize(HANDLE device, BOOL bIn ) ;
    virtual CUCObj* Clone(  CUCObj *twin) ;

	 
	virtual void Show(CDelegate* pDelegate, int mode, BOOL bForce) ;

	virtual void Shot(int mode ,const RvImage image )   ;

	virtual void  SetDisplayStyle(int style);
 

	RvBlob  GetBlobAt(int index);
	int     GetBlobCount();
  
	virtual void Reset();


	//segment仅使用RGB 和GRAY格式的图像
	//1. mip进行计算
	//2. 将图像转成二值图, 调用SegmentEx(  RvImage image, const RvImage mask);
	virtual int Segment();	

	//分隔并选择大小
	//1. 调用 Segment, 
	//2. 按照blob大小筛选
	//virtual int  SegmentEx();	

	//直接使用二值图像进行分割, 没有进行mip运算
	int  SegmentEx(  RvImage image, const RvMask mask);

	 
	//选择满足大小的BLOB
	int  Select(  UINT nMinSize /*=49*/ );	
	 
	int  SelectEx(UINT nMinSize, UINT nMaxSize/* = BE_MAX_SIZE*/ );	

	//选择前最大的BLOB
	int  SelectMax();

	//指定条件选择, BE_FT_MAXCIRC, 其它待补充
	int  Select(int criteria, DWORD_PTR param1/*=0*/, DWORD_PTR param2/*=0*/);

	//待完成
	void Sort();  //按照面积从大到小排序


	//合并近距离BLOB
    int  Merge(UINT nDistThres);

	const RvImage GetBin() { return m_imBin; };
	 

//BLOB属性
public:
	RvPoint_f Centroid(int index);
	
	RvBox2D  BoundBox( int index);
	RvPoint  Offset(int index );
	RvRect   Rect(int index);

	double  Area(int index  );
	double  Summary(int index  );
	double  Average(int index  );
	double  Variance(int index);
	double  Strength(int index );

	double  Perimeter(int index);	 
	double  Circular(int index);
	double  Density(int index);
	double  Slope(int index);

	//主干大小 ,长度方向比较主干大小，获得新长度。
	RvSize  StemSize(int index);
	
public:

	BOOL  m_bFillHole;
	BOOL  m_bCutEdge;

	BOOL        m_bConn8;   //是否为8连通性
	//int         m_nMaxSizeBlobCount; //最大BLOB的数量，默认为1
	//物体主干长度
	BOOL    m_bCheckStemLen;
	int     m_nMinStemThick;

	int         m_nBlobCoder; //blob编码类型

	MAKE_REAL   m_nMakeReal; //是否通过形态算法是图象更接近真实
	int         m_nErodeTimes;	//腐蚀次数， 最多15次，
	int         m_nDilateTimes;	//膨胀次数， 最多15次
	int         m_nSegMode; //分割模式


	//
	//使用BE_SM_HDY分割方法进行分割的时候，m_nMinBlobWidth和m_nMinBlobHeight有效
	//int         m_nMinBlobWidth , m_nMinBlobHeight;

	//后面的继承类需要用到 
	UINT  m_nSizeThres ;              //最小尺寸
	int   m_nFilterType;               //刷选类型，BE_FT_MINSIZE
	UINT  m_nLowerSize, m_nUpperSize;  //按照方位刷选
	

protected:
	virtual void UpdateShape(CDelegate* pDelegate,HGPD hGpd, BOOL bMove) ;
	 
	void ClearBlobCollecter();

	//仅清除临时属性，不重新分配数据
	//void ClearPropArray();

	//该函数可以清除临时属性
	//void ResetPropArray();
	void UpdateBlobCollecter(  RvSequence seq);

	void  MakeReal(  RvImage image, const RvMask mask);

protected:
	
	//该数组用于优化
	//void* m_propArray;
	//int   m_nPropSize; 
	
	RvSequence m_blobCollecter; 
	//RvBlob     m_lblBlob;
	double    m_nMipScale ; //临时变量，记录分隔时的比例。

	RvImage m_imBin;
	  
	//是否进行了图像处理，临时变量
	BOOL    m_bPreprecessed;
	int   m_nGridSize;
	int   m_nMinStrength;

};





#endif // !defined(__RV_BLOB_EXTRACTOR_H_INCLUDED_)
