openCV中 cvSeq的用法说明
openCV中 cvSeq的用法说明
函数原型 | 说明 |
CvSeq* cvCreateSeq(int seq_flags,int header_size,int elem_size,CvMemStorage* storage) | 功能:创建一序列 参数:seq_flags为序列的符号标志。如果序列不会被传递给任何使用特定序列的函数,那么将它设为0,否则从预定义的序列类型中选择一合适的类型。 Header_size为序列头部的大小;必须大于或等于sizeof(CvSeq)。如果制定了类型或它的扩展名,则此类型必须适合基类的头部大小。 Elem_size为元素的大小,以字节计。这个大小必须与序列类型(由seq_flags指定)相一致。例如,对于一个点的序列,元素类型 CV_SEQ_ELTYPE_POINT应当被指定,参数elem_size必须等同于sizeof(CvPoint)。Storage为指向前面定义的 内存存储器 |
CvSeq* cvCloneSeq(const CvSeq* seq,CvMemStorage* storage=NULL) | 功能:创建序列的一份拷贝 |
Void cvSeqInvert(CvSeq* seq) | 功能:将序列中的元素进行逆序操作 |
Void cvSeqSort(CvSeq* seq,CvCmpFunc func,void *userdata=NULL) |
功能:使用特定的比较函数对序列中的元素进行排序 |
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) |
功能:初始化序列中的读取过程 |
OpenCV CvSeq的内部结构探讨
一直困惑于CvSeq到底是个什么样的东西,因为曾经拿到别人写的一个函数库,其返回值是一个CvSeq指针,我的任务是遍历所有的Sequence,然
后删除其中不符合要求的Sequence。由于没有文档,我当时并不知道我需要遍历的是Sequence还是Sequence中的Element。于是我
写下了类似如下的代码:
事实证明这段代码是错误的,而且往往返回的错误信息是
>
OpenCV ERROR: One of arguments' values is out of range
(Invalid index)
>
in function cvSeqRemove, cxdatastructs.cpp(1587)
为
什么会有这样的错误呢?看一下CvSeq的源代码就可略见一斑。下面是OpenCV2.0版本有关CvSeq的定义
原来CvSeq本身就是一个可增长的序列,CvSeq::total是指序列内部有效元素的个数;而h_next和h_prev并不是指向CvSeq内部元
素的指针,它们是指向其它CvSeq的。再回到文章最初的代码,我们可以看到该代码具有逻辑上的错误,首先while语句遍历的是所有的CvSeq,使用
process处理每一个CvSeq,而遇到需要删除的CvSeq时,又使用才cvSeqRemove删除当前CvSeq中的第index个元素。实际上
此时index很可能超出了当前CvSeq中总元素的个数,所以出现了超出边界的错误。正确的做法是直接删除该CvSeq。
后来在Google Book里查了一下,发现《Learning OpenCV:Computer Vision with the OpenCV
Library》中有这么一段话描述的不错:
The sequence structure itself has some important
elements that you should be aware of. The first, and one you will
use often, is total
. This is the
total number of points or objects in the sequence. The next four important
elements are pointers to other sequence: h_prev
, h_next
, v_prev
and v_next
. These four pointers are part of what are called CV_TREE_NODE_FIELDS
; they are used
not to indicate elements inside of the sequence but rather to connect
different sequences to one another. Other objects in the OpenCV
universe also contain these tree node fields.
参考:http://hi.baidu.com/ltbing/blog/item/490d88948af27c14d21b7008.html
http://jackchongsun.blog.163.com/blog/static/4071607201019101312221/
出处:https://www.cnblogs.com/wqvbjhc/
版权:本文版权归作者和博客园共有
转载:欢迎转载,但未经作者同意,必须保留此段声明;必须在文章中给出原文连接;否则必究法律责任
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 智能桌面机器人:用.NET IoT库控制舵机并多方法播放表情
· Linux glibc自带哈希表的用例及性能测试
· 深入理解 Mybatis 分库分表执行原理
· 如何打造一个高并发系统?
· .NET Core GC压缩(compact_phase)底层原理浅谈
· 新年开篇:在本地部署DeepSeek大模型实现联网增强的AI应用
· DeepSeek火爆全网,官网宕机?本地部署一个随便玩「LLM探索」
· Janus Pro:DeepSeek 开源革新,多模态 AI 的未来
· 互联网不景气了那就玩玩嵌入式吧,用纯.NET开发并制作一个智能桌面机器人(三):用.NET IoT库
· 上周热点回顾(1.20-1.26)