OpenCV 使用内存储器(memory storage)来统一管理各种动态对象分配的内存。内存存储器在底层被实现为一个有许多相同大小的内存块组成的双向链表,通过这种结构,OpenCv可以从内存存储器中快速地分配内存或将内存返回给存储器。
内存储器结构
typedef struct CvMemStorage { int signature; CvMemBlock* bottom; /* First allocated block. */ CvMemBlock* top; /* Current memory block - top of the stack. */ struct CvMemStorage* parent; /* We get new blocks from parent as needed. */ int block_size; /* Block size. */ int free_space; /* Remaining free space in current block. */ } CvMemStorage;
创建内存储器
CVAPI(CvMemStorage*) cvCreateMemStorage( int block_size CV_DEFAULT(0));
block_size:存储块的大小以字节表示。如果大小是 0 byte,则将该块设置成默认值当前默认大小为64k.函数
cvCreateMemStorage创建一内存块并返回指向块首的指针。起初,存储块是空的。头部(即:header)的所有域值都为 0,除了 block_size外.
释放内存块
CVAPI(void) cvReleaseMemStorage( CvMemStorage** storage );
storage:指向被释放了的存储块的指针函数 cvReleaseMemStorage释放所有的存储(内存)块或者将它们返回给各自的 parent(如果需要的话)。接下来再释放 header块(即:释放头指针 head指向的块 = free(head))并清除指向该块的指针(即:head = NULL)。在释放作为 parent的块之前,先清除各自的 child 块。
清空内存存储块
CVAPI(void) cvClearMemStorage( CvMemStorage* storage );
storage:存储存储块函数 cvClearMemStorage将存储块的 top置到存储块的头部(注:清空存储块中的存储内容)。该函数并不释放内存(仅清空内存)。假使该内存块有一个父内存块(即:存在一内存块与其有父子关系),则函数就将所有的块返回给其 parent.
分配以内存缓冲区
CVAPI(void*) cvMemStorageAlloc( CvMemStorage* storage, size_t size );
storage:内存块.size:缓冲区的大小.函数 cvMemStorageAlloc在存储块中分配一内存缓冲区。该缓冲区的大小不能超过内存块的大小,否则就会导致运行时错误。缓冲区的地址被调整为CV_STRUCT_ALIGN字节(当前为sizeof(double)).
序列CVSeq定义
#define CV_SEQUENCE_FIELDS() \ CV_TREE_NODE_FIELDS(CvSeq); \ int total; /* Total number of elements. */ \ int elem_size; /* Size of sequence element in bytes. */ \ schar* block_max; /* Maximal bound of the last block. */ \ schar* ptr; /* Current write pointer. */ \ int delta_elems; /* Grow seq this many at a time. */ \ CvMemStorage* storage; /* Where the seq is stored. */ \ CvSeqBlock* free_blocks; /* Free blocks list. */ \ CvSeqBlock* first; /* Pointer to the first sequence block. */ typedef struct CvSeq { CV_SEQUENCE_FIELDS() }
CvSeq;CVSeq是CvMemStorage中的一种存储对象,CVSeq是某种结构的链表。在OpenCv中,CVSeq可以存储多种不同的结构,序列好比c++中vecotor,在内存中被实现为双端队列。
创建序列
CVAPI(CvSeq*) cvCreateSeq( int seq_flags, size_t header_size, size_t elem_size, CvMemStorage* storage );
功能:创建一序列 参数:seq_flags为序列的符号标志。如果序列不会被传递给任何使用特定序列的函数,那么将它设为0,否则从预定义的序列类型中选择一合适的类型。Header_size为序列头部的大小;必须大于或等于sizeof(CvSeq)。如果制定了类型或它的扩展名,则此类型必须适合基类的头部大小。Elem_size为元素的大小,以字节计。这个大小必须与序列类型(由seq_flags指定)相一致。例如,对于一个点的序列,元素类型CV_SEQ_ELTYPE_POINT应当被指定,参数elem_size必须等同于sizeof(CvPoint)。Storage为指向前面定义的内存存储器。
序列操作常见函数
Char* cvSeqSearch(CvSeq* seq,const void* elem,CvCmpFunc func,int is_sorted,int *elem_idx,void *userdata=NULL)
功能:查询序列中的元素
Void cvClearSeq(CvSeq* seq); 功能:
清空序列
Char* cvSeqPush(CvSeq* seq,void* element=NULL)
功能:添加元素到序列的尾部
void cvSeqPop(CvSeq* seq,void* element=NULL)
功能:删除序列尾部元素
Char* cvSeqPushFront(CvSeq* seq,void* element=NULL)
功能:在序列头部添加元素
Void cvSeqPopFront(CvSeq* seq,void* element=NULL)
功能:删除在序列的头部的元素
Void cvSeqPushMulti(CvSeq* seq,void* elements,int count,int in_front=0);
功能:添加多个元素到序列尾部或头部
Void cvSeqPopMulti(CvSeq* seq,void* elements,int count,int in_front=0)
功能:删除多个序列头部或尾部元素
Char* cvSeqInsert(CvSeq* seq,int before_index,void* element=NULL)
功能:在序列中的指定位置添加元素
Void cvSeqRemove(CvSeq* seq,int index)
功能:删除序列中的指定位置的元素
Char* cvGetSeqElem(const CvSeq* seq,int index)
功能:返回索引所指定的元素指针
Int cvSeqElemIdx(const CvSeq* seq,const void* element,CvSeqBlock** block=NULL)
功能:返回序列中元素的索引
Void cvStartAppendToSeq(CvSeq* seq,CvSeqWriter* writer)
功能:将数据写入序列中,并初始化该过程
Void cvStartWriteSeq(int seq_flags,int header_size,int elem_size,CvMemStorage* storage,CvSeqWriter* writer)
功能:创建新序列,并初始化写入部分
CvSeq* cvEndWriteSeq(CvSeqWriter* writer)
功能:完成写入操作
Void cvStartReadSeq(const CvSeq* seq,CvSeqReader* reader,int reverse=0)
功能:初始化序列中的读取过程