CvSeq
可增长的元素序列
int flags ; /* micsellaneous flags */ \
int header_size ; /* 序列头的大小 */ \
struct CvSeq * h_prev ; /* 前一个序列 */ \
struct CvSeq * h_next ; /* 后一个序列 */ \
struct CvSeq * v_prev ; /* 第二级前一个序列 */ \
struct CvSeq * v_next ; /* 第二级后一个序列 */ \
int total ; /* 元素的总个数 */ \
int elem_size ; /* 元素的尺寸 */ \
char * block_max ; /* 上一块的最大块 */ \
char * ptr ; /* 当前写指针 */ \
int delta_elems ; /*序列中快的大小
(序列粒度) */ \
CvMemStorage * storage ; /*序列的存储位置 */ \
CvSeqBlock * free_blocks ; /* 未分配的块序列 */ \
CvSeqBlock * first ; /* 指向第一个快序列 */
typedef struct CvSeq
{
CVgSEQUENCE\_FIELDS ()
} CvSeq ;
使用者用一种不常见的通过宏定义的帮助来实现结构的定义,使CvSeq结构可扩展,增加参数。用过可以自定义一个结构,然后通过宏定义CV_SEQUENCE_FIELDS()将自己定义的结构放在CvSeq的参数后面组成一个新的结构。
有两种类型的序列:密集型、稀疏型。密集型序列的基本类型就是CvSeq,这样的序列用来表示可增长的一维数组:向量、栈,队列和双向队列。他们中间没有间隔,如果从中间插入或者删除一个元素,那么从它到离它比较近的一个终点的元素都要移动。稀疏型序列的基本类型是CvSet,这将在后面作更详细讨论,他们是一个个节点的序列,每个节点,每个可以通过节点标识来申请或者释放,这种用于无序的数据结构,例如:集合元素,图标,哈希表等等
成员header_size表示了序列头的实际尺寸,这个值大于等于sizeof(cvSeq)(译者注:因为这个序列头是可扩展的)。
成员h_prev,h_next,v_prev,v_next可以用来创造独立的序列层次结构。成员h_prev,h_next用于指向统一成的前一个和后一个序列结构,而v_prev,v_next则用来指向垂直方向上的上一个和想一个序列,也就是指向他的父节点和第一个孩子节点序列结构。但这只是一个名称,指针可以通过不同的方式使用。
成员first指针指向第一块序列块,它的结构描述如下。
成员total表示密集型序列中所包含的元素的个数,以及稀疏型序列中截个的个数。
成员flags包含了动态类型签名(稠密型:CV_SEQ_MAGIC、稀疏型:CV_SET_MAGIC)的最多16位的有关序列的各种信息的标志。在最低的CV_SEQ_ELTYPE_BITS位包含了元素的类型ID,但是大多数序列处理函数不适用元素类型而是用元素大小的slem_size位。如果一个序列包含了与CvMat类型相匹配的CvMat元素类型比如:2可用于序列二维点的CV_32SC
浮点值序列:CV_32FC1等等。可通过宏定义CV_SEQ_ELTYPE(seq_header_ptr)来检索序列中元素的类型,在用来处理计算序列元素个数的elem_size值的函数可以用到。除了兼容CvMat类型,有些元素类型定义在cvtypes.h()头中:
标准的序列元素类型:
#define CV_SEQ_ELTYPE_CODE CV_8UC1 /* freeman code: 0..7 */
#define CV_SEQ_ELTYPE_GENERIC 0 /* unspecified type of
sequence elements */
#define CV_SEQ_ELTYPE_PTR CV_USRTYPE1 /* =6 */
#define CV_SEQ_ELTYPE_PPOINT CV_SEQ_ELTYPE_PTR /* &elem: pointer to
element of other sequence */
#define CV_SEQ_ELTYPE_INDEX CV_32SC1 /* #elem: index of element of
some other sequence */
#define CV_SEQ_ELTYPE_GRAPH_EDGE CV_SEQ_ELTYPE_GENERIC /* &next_o,
&next_d, &vtx_o, &vtx_d */
#define CV_SEQ_ELTYPE_GRAPH_VERTEX CV_SEQ_ELTYPE_GENERIC /* first_edge,
&(x,y) */
#define CV_SEQ_ELTYPE_TRIAN_ATR CV_SEQ_ELTYPE_GENERIC /* vertex of the
binary tree */
#define CV_SEQ_ELTYPE_CONNECTED_COMP CV_SEQ_ELTYPE_GENERIC /* connected
component */
#define CV_SEQ_ELTYPE_POINT3D CV_32FC3 /* (x,y,z) */
后面的CV_SEQ_KIND_BITS位表示了序列的种类。
标准的序列种类有:
#define CV_SEQ_KIND_GENERIC ( 0 << CV_SEQ_ELTYPE_BITS )
/* dense sequence suntypes */
#define CV_SEQ_KIND_CURVE ( 1 << CV_SEQ_ELTYPE_BITS )
#define CV_SEQ_KIND_BIN_TREE ( 2 << CV_SEQ_ELTYPE_BITS )
/* sparse sequence (or set) subtypes */
#define CV_SEQ_KIND_GRAPH ( 3 << CV_SEQ_ELTYPE_BITS )
#define CV_SEQ_KIND_SUBDIV2D ( 4 << CV_SEQ_ELTYPE_BITS )
剩下的位用来指定有不同特征的包括序列种类和元素类型。比如说曲线点(CV_SEQ_KIND_CURVE|CV_SEQ_ELTYPE_POINT),连同标识CV_SEQ_FLAG_CLOSED,就属于类型CV_SEQ_POLYGON或者再加上其他标识。很多处理轮廓的函数要做类型检查,如果不支持该类型就会报错。文件cvtypes.h存储了所有支持预定义类型的序列类型以及获得序列的其他属性的宏定义的完整列表。序列块的地组合快可以再在下面找到。