OpenCV CvSeq 结构
一直困惑于CvSeq到底是个什么样的东西,因为曾经拿到别人写的一个函数库,其返回值是一个CvSeq指针,我的任务是遍历所有的Sequence,然后删除其中不符合要求的Sequence。由于没有文档,我当时并不知道我需要遍历的是
Sequence还是Sequence中的Element。于是我写下了类似如下的代码:
CvSeq *pCurSeq = pInputSeq;
int index = 0;
while( pCurSeq=pCurSeq->h_next )
{
if( process(pCurSeq) )
{
pCurSeq = pCurSeq->h_prev; //这里为了简单不考虑是否为列表头
cvSeqRemove(pInputSeq, index);
--index;
}
++index;
}
事实证明这段代码是错误的,而且往往返回的错误信息是
> OpenCV ERROR: One of arguments' values is out of range (Invalid index)
> in function cvSeqRemove, cxdatastructs.cpp(1587)

为什么会有这样的错误呢?看一下CvSeq的源代码就可略见一斑。下面是OpenCV1.0版本有关CvSeq的定义
#define CV_TREE_NODE_FIELDS(node_type) \
int flags; \
int header_size; \
struct node_type* h_prev; \
struct node_type* h_next; \
struct node_type* v_prev; \
struct node_type* v_next

#define CV_SEQUENCE_FIELDS() \
CV_TREE_NODE_FIELDS(CvSeq); \
int total; \
int elem_size; \
char* block_max; \
char* ptr; \
int delta_elems; \
CvMemStorage* storage; \
CvSeqBlock* free_blocks; \
CvSeqBlock* first;

typedef struct CvSeq
{
CV_SEQUENCE_FIELDS()
}
CvSeq;
原来CvSeq本身就是一个可增长的序列,CvSeq::total是指序列内部有效元素的个数;而h_next和h_prev并不是指向CvSeq内部元素的指针,它们是指向其它CvSeq的。再回到文章最初的代码,我们可以看到该代码具有逻辑上的错误,首先while语句遍历的是所有的CvSeq,使用 process处理每一个CvSeq,而遇到需要删除的CvSeq时,又使用才cvSeqRemove删除当前CvSeq中的第index个元素。实际上此时index很可能超出了当前CvSeq中总元素的个数,所以出现了超出边界的错误。正确的做法是直接删除该CvSeq。
CvSeq *pCurSeq = pInputSeq;
CvSeq *pOldSeq = NULL;
while( pCurSeq )
{
if( process(pCurSeq) )
{
pOldSeq = pCurSeq;
if(pOldSeq->h_prev)
{
pCurSeq = pOldSeq->h_prev;
pCurSeq->h_next = pOldSeq->h_next;
pOldSeq->h_next->h_prev = pCurSeq;
pCurSeq=pCurSeq->h_next;
cvClearSeq( pOldSeq );
}
else
{
pCurSeq = pOldSeq->h_next;
pCurSeq->h_prev = NULL;
cvClearSeq( pOldSeq );
}
}
else
{
pCurSeq=pCurSeq->h_next; 
}

后来在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.
OpenCV中的数据结构CvSeq(序列)
OpenCV中的基本数据结构 —-  序列:
动态结构序列CvSeq是所有OpenCv动态数据结构的基础。有两种类型的序列:稠密序列,稀疏序列:
(1) 稠密序列都派生自CvSeq,他们用来代表可扩展的一维数组 — 向量、栈、队列和双端队列。数据间不存在空隙(连续存储)。如果元素元素从序列中间被删除或插入新的元素到序列,那么此元素后边的相关元素全部被移动。
(2)稀疏序列派生自CvSet,CvSet也是基于CvSeq的,他们都是由节点所组成,每一个节点要么被占用,那么为空,由标志位flag决定。这些序列作为无序数据结构被使用,如点集合、图、Hash表等。
结构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;

total表示稠密序列的元素个数,或者稀疏序列被分配的节点数。
elem_size表示序列中每个元素占用的字节数。block_max是最近一个内存的最大边界指针。
ptr表示当写指针。delta_elems表示序列间隔尺寸。storage指向序列存储的内存块的指针。
free_blocks表示空的块列表。first指向第一个序列块。

转自:openCV中 cvSeq的用法说明

相关博文:OpenCV中如何剔除检测到的不符合要求的对象

【OpenCV学习笔记】【函数学习】十四(cvSeq的用法说明(功能很多,按照需求使用))相关推荐

  1. mysql循环查询一个表中的数据并进行修改_JavaScript学习笔记(二十四)-- MYSQL基础操作...

    MYSQL mysql 是一个数据库的名字 和 php 合作的比较好的数据库 之前我们说过一个问题,前端向后端索要数据,后端就是去数据库中查询数据,返回给前端 接下来就聊聊使用 php 操作数据库 M ...

  2. Slicer学习笔记(五十四)slicer分割结果3D显示

    Slicer学习笔记(五十四)slicer分割结果3D显示 1.Create a segmentation from a labelmap volume and display in 3D 2.Exp ...

  3. OpenCV学习笔记(五十四)——概述FaceRecognizer人脸识别类contrib

    在最新版的2.4.2中,文档的更新也是一大亮点,refrence manual扩充了200多页的内容,添加了contrib部分的文档.contrib就是指OpenCV中新添加的模块,但又不是很稳定,可 ...

  4. 【OS学习笔记】三十四 保护模式十:中断和异常区别

    上几篇文章学习了分页机制的一些原理: [OS学习笔记]三十 保护模式九:段页式内存管理机制概述 [OS学习笔记]三十一 保护模式九:页目录.页表和页三者的关系详解 今天继续学习保护模式下的关于中断与异 ...

  5. 链接mysql_JavaScript学习笔记(二十四)-- MYSQL基础操作

    MYSQL mysql 是一个数据库的名字 和 php 合作的比较好的数据库 之前我们说过一个问题,前端向后端索要数据,后端就是去数据库中查询数据,返回给前端 接下来就聊聊使用 php 操作数据库 M ...

  6. 系统架构师学习笔记_第十四章_连载

    第十四章  基于ODP的架构师实践 14.1  基于ODP的架构开发过程 系统架构 反映了功能在系统系统构件中的 分布.基础设施相关技术.架构设计模式 等,它包含了架构的 原则 和 方法.构件关系 与 ...

  7. 【Java基础学习笔记】- Day11 - 第四章 引用类型用法总结

    Java基础学习笔记 - Day11 - 第四章 引用类型用法总结 Java基础学习笔记 - Day11 - 第四章 引用类型用法总结 4.1 class作为成员变量 4.2 interface作为成 ...

  8. OpenCV开发笔记(七十四):OpenCV3.4.1+ffmpeg3.4.8交叉编译移植到海思平台Hi35xx平台

    若该文为原创文章,转载请注明原文出处 本文章博客地址:https://blog.csdn.net/qq21497936/article/details/123696821 各位读者,知识无穷而人力有穷 ...

  9. OpenCV学习笔记(三十四)——OpenCV路在何方

    之前做了haartraining的东西,感觉到OpenCV里面实现的东西还不是很好,这个老版本的haartraining的东西在新版本仍然是用老版本的函数来实现的,让我很不爽.于是好期待下一版本的到来 ...

  10. 高等数学学习笔记——第三十四讲——函数的单调性与凹凸性(凹凸性)

    1. 凸函数(向上凸函数和向下凸函数) 2. 凸曲线的几何特征分析("弦在弧上") 3. 向下凸函数(凸函数.严格凸函数.严格向下凸函数)的定义 4. 向上凸函数(严格向上凸函数) ...

最新文章

  1. 北大发布最新《图神经网络推荐系统》2020综述论文,27页pdf
  2. Java窗口(JFrame)从零开始(8)——文本框+文本域+密码框
  3. 创客运动引发第三次工业革命
  4. xlwt写入单元格,xlrd读出单元格
  5. 微软+开源,那些亲爱的以及热爱的
  6. Linux字符设备驱动剖析
  7. mysql主从配置错误_mysql主从配置常见错误处理
  8. 产品运营必备的素质有哪些
  9. 数学模型方法分类总结
  10. 人工智能AI对客户服务的影响正在形成
  11. 用C#实现一个zip解压功能,无需引入dll(可直接放到Unity中使用)
  12. c语言:四位数为AABB些型,并且是另一个书的平方,求这昂的四位数
  13. java 订单减库存_订单和库存处理方案
  14. PDMS二次开发之PML开发一些常见查询语句
  15. 计科实训 餐馆点菜系统
  16. 214 情人节来袭,电视剧 《点燃我温暖你》李峋同款 Python爱心表白代码,赶紧拿去用吧
  17. K8S StatefulSet方式部署elasticsearch集群 —— 筑梦之路
  18. 为什么要在csdn开一个博客
  19. Wiener Filtering
  20. c语言编程代码大全(c语言简单代码大全)

热门文章

  1. 28. Avoid returning handles to object internals
  2. maya嵌入python_#113 如何给Maya添加一个Python Command Shell ? | 一半君的总结纸
  3. java 反射 对象的方法_Java通过反射调用对象的方法
  4. ROS学习记录:动作编程
  5. 如何使用nacos配置中心统一管理配置
  6. python from import 和 import 区别_python import和from import的区别
  7. 江苏2021168查询高考成绩,重磅!高考成绩查询!!
  8. Java编程:克鲁斯卡尔算法(未知起点求最小生成树)
  9. Java编程:分治算法
  10. 热流体动压润滑matlab_仿真加快摩擦润滑研究进程