
#if !defined(__RV_WIRE_CHECK_H_INCLUDED_)
#define __RV_WIRE_CHECK_H_INCLUDED_

#pragma once
#include <cali\blobextractor.h>

#include "gauge.h"


#define WC_MAX_SEG_COUNT    128

//检测标识
#define SC_CF_MAX_WID         1
#define SC_CF_MIN_WID        (1<<1)
#define SC_CF_START_WID      (1<<2)   
#define SC_CF_END_WID        (1<<3)  

#define SC_CF_SYMM_RATE      (1<<4)   
#define SC_CF_SYMM_DIFF      (1<<5)   
/*#define SC_CF_MAX_SYMM_RATE  (1<<6)   
#define SC_CF_MAX_SYMM_DIFF  (1<<7)   
#define SC_CF_MIN_SYMM_RATE  (1<<8)  
#define SC_CF_MIN_SYMM_DIFF  (1<<9) */  

#define SC_CF_ABOVE_DIFF     (1<<10)   
#define SC_CF_BELOW_DIFF     (1<<11)   
/*#define SC_CF_MAX_ABOVE_DIFF  (1<<12)   
#define SC_CF_MAX_BELOW_DIFF  (1<<13)   
#define SC_CF_MIN_ABOVE_DIFF  (1<<14)   
#define SC_CF_MIN_BELOW_DIFF  (1<<15)  */ 

//扩展标识,计算主根宽度
#define SC_CF_STEM_WIDTH            (1<<24)
#define SC_CF_REMOVE_PROTRUSION     (1<<25)  //移除突出物



class GAUGE_API CSymmetryCheck :	public CBlobExtractor
{
public:
	enum SC_MERGE
	{
		SC_NEVER =-1,  //不合并
		SC_NORMAL=0 ,   //常规
		SC_SMALL    ,   //小线段合并
		SC_BACKWARD ,   //反向合并
		SC_NOSTEP,     //移除过度段		 
	};

	enum SC_STEP
	{
		SC_DEF =0,    //默认（混合型，但不计算两边diff）
		SC_DOWN,      //减小,左大右小
		SC_UP,        //增大,左小右大
		SC_MIX,       //混合
	};

	CSymmetryCheck(void);
	virtual ~CSymmetryCheck(void);

	

	virtual void Show(CDelegate* pDelegate, int mode, BOOL bForce);
	virtual CUCObj* Clone( CUCObj* twin) ;
	virtual BOOL Serialize(HANDLE device, BOOL bIn );
	 
	virtual RV_BOOL Inspect(int* pErrCode );
    virtual void Reset();

 	RvPoint_f64 GetTopPos();   //顶部
  	RvPoint_f64 GetRootPos();  //根部
 	double GetSegLength(int index); 
 	double GetSegWidth(int index);
	double GetSegMaxWidth(int index);
	double GetSegMinWidth(int index);
	double GetSegStartWidth(int index);
	double GetSegEndWidth(int index);
	


	double GetSymmRate(int index); 
 	double GetSymmDiff(int index);
	double GetMaxSymmRate(int index);
	double GetMaxSymmDiff(int index);
	double GetMinSymmRate(int index);
	double GetMinSymmDiff(int index);

	double GetAboveDiff(int index); 
 	double GetBelowDiff(int index);
	double GetMaxAboveDiff(int index);
	double GetMinAboveDiff(int index);
	double GetMaxBelowDiff(int index);
	double GetMinBelowDiff(int index);

 	int    GetSegCount();
	
	double GetAngle();

	double GetSymmetry() { return m_nSymmetry; };
	BOOL  IsResultValid(){ return m_bValidResult; };

//内部调试用
public:

	RvCut GetCurCut() { return m_cut; };
	int   GetPosCount() { return m_nPosCount; }
	RvPoint_f*   GetPosArray() { return m_pPosArray; }

public:
	UINT m_nMinAreaSize;   
	int  m_nMaxSegCount;  //常规段数，目前保留，无实际使用

	int  m_nMinBodyWidth; //最小实体宽度,该参数过滤最小段。
	int  m_nSampleDist;    //横向扫描步长，默认为1
	int  m_nStepHeight;    //最小台阶高度
	int  m_nStepGap;       //最大台阶跨度，如果大于0，而台阶长度小于该值，则合并台阶 。
	                        //小于等于0不合并

	int  m_nMergeType;   //合并类型
	int  m_nStepType;    //阶梯类型

	BOOL m_bUpright;     //垂直物体(保留参数)

	//后期处理
	int  m_nSpurSize;  //毛刺宽度
	int  m_nDeltaErr;  //边缘高度差错误,用于边缘平滑处理

	int  m_nCheckFlags;  //检测标记



public:
	virtual void  OnEndTrack(CDelegate* pDelegate, HGPD hCur,  GPoint point, int type)  ;

protected:
	RV_HANDLE DrawMarks(HGDC dc, RV_HANDLE hStroke);
	  
	RvPoint_f*  FindSteps(RvPoint_f64* pEdge1Array, RvPoint_f64* pEdge2Array, double* pWidArray, int size,  int sampleDist, int stepHeight, int minWidth, int& nSegSize, int* pStepCount);
 
	RvPoint_f*  FindStepsE1(RvPoint_f64* pEdge1Array, RvPoint_f64* pEdge2Array, double* pWidArray, int size,  int sampleDist, int stepHeight, int minWidth, int& nSegSize, int* pStepCount, int stepType);

	int  MergeSmallSegs(int maxGap,   int segCount, RvPoint_f* pPosArr, int& nPosSize);
	int  MergeSegsNormal(int maxGap,  int segCount, RvPoint_f* pPosArr, int& nPosSize);
	int  MergeSegsBackward(int maxGap,  int segCount, RvPoint_f* pPosArr, int& nPosSize);
	int  MergeRemoveSteps(int maxGap,  int segCount, RvPoint_f* pPosArr, int& nPosSize);  //移除过渡段

private:

//	CRITICAL_SECTION m_cs;

	void ReleaseObjectsArrays();
	RvCut GenCut(RvBox2D& box, RvBlob blob);
	BOOL PickEdges(RvCut cut);
	   

	//以下为检测结果相关变量，不进行序列化
	float m_segLens[WC_MAX_SEG_COUNT];
	float m_segWids[WC_MAX_SEG_COUNT]; //平均宽度

	float m_segMaxWids[WC_MAX_SEG_COUNT];   //一段中最大宽度
	float m_segMinWids[WC_MAX_SEG_COUNT];   //一段中最小宽度
	float m_segStartWids[WC_MAX_SEG_COUNT]; //一段中起始快读
	float m_segEndWids[WC_MAX_SEG_COUNT];   //一段中结束宽度

	float m_segSymmRates[WC_MAX_SEG_COUNT];     //平均对称性
	float m_segSymmDiffs[WC_MAX_SEG_COUNT];     //平均对称偏差
	float m_segMaxSymmRates[WC_MAX_SEG_COUNT];  //最大对称性
	float m_segMaxSymmDiffs[WC_MAX_SEG_COUNT];  //最大对称偏差
	float m_segMinSymmRates[WC_MAX_SEG_COUNT];  //最大对称性
	float m_segMinSymmDiffs[WC_MAX_SEG_COUNT];  //最大对称偏差


	//仅使用与
	float m_segAboveDiffs[WC_MAX_SEG_COUNT];     //上边偏差
	float m_segBelowDiffs[WC_MAX_SEG_COUNT];     //下边偏差
	float m_segMaxAboveDiffs[WC_MAX_SEG_COUNT];  //最大上边偏差
	float m_segMinAboveDiffs[WC_MAX_SEG_COUNT];  //最小上边偏差
	float m_segMaxBelowDiffs[WC_MAX_SEG_COUNT];  //最大下边偏差
	float m_segMinBelowDiffs[WC_MAX_SEG_COUNT];  //最小下边偏差
	 

	int    m_nSegCount;
	 
	BOOL m_bValidResult;
	double     m_nSymmetry; //对称性，0~1
	 
	RvPoint_f* m_pPosArray;
    int        m_nPosCount;

	RvPoint_f64 m_topPos, m_rootPos;
	double      m_nAngle;
	RvCut      m_cut;
 
};




#endif
