我们在做好图像采集工作后,有时需要将图像特征或者视觉检测结果保存下来。由于保存的数据具有一定规律性,因此我们可以采用opencv提供的文件存储类函数实现序列化数据,并保存为文件。当然你要是不觉得麻烦,完全可以自己重写数据序列化方法,不必采用opencv提供的函数。下面是OpenCV中文件存储结构函数CvFileStorage与文件存储器节点函数CvFileNode的函数构成,及简单使用方法。

文件存储结构

构造函数 CvFileStorage 是将磁盘上存储的文件关联起来的“黑匣子” 。在下列函数描述中利用CvFileStorage 作为输入,允许存储或载入各种格式数据组成的层次集合,这些数据由标量值(scalar ),或者CXCore 对象(例如 矩阵,序列,图表 ) 和用户自定义对象。

CXCore 能将数据读入或写入 XML或者 YAML格式. 下面这个例子是利用CXCore函数将3×3单位浮点矩阵存入XML 和 YAML文档。

XML:

YAML:

从例子中可以看到, XML是用嵌套标签来表现层次,而 YAML用缩排来表现(类似于Python语言) 。

相同的 CXCore 函数也能够在这两种格式下读写数据,特殊的格式决定了文件的扩展名, .xml 是 XML 的扩展名, .yml 或 .yaml 是 YAML的扩展名。

CvFileNode

文件存储器节点

这个构造函数只是用于重新找到文件存储器上的数据(例如 ,从文件中下载数据)。 当数据已经写入文件时,按顺序写入,只用最小的缓冲完成,此时没有数据存放在文件存储器。

相反,当从文件中读数据时,所有文件在内存中像树一样被解析和描绘。树的每一个节点被CvFileNode表现出来。文件节点N的类型能够通过CV_NODE_TYPE(N->tag) 被重新找到。一些节点(叶结点)作为变量:字符串文本,整数,浮点数。其它的文件节点是集合文件节点,有两个类型集合:序列和图表 (我们这里使用 YAML 符号,无论用哪种方法,对于XML符号流也是同样有效)。序列(不要与CvSeq混淆) 是由有序的非指定文件节点(注:没有关键字)构成的,图表是由无序的指定文件节点(注:有关键字)构成的。因而 ,序列的数据是通过索引(cvGetSepElem)来存取,图形的数据是通过名字(cvGetFileNodeByName)来存取 下表描述不同类型的节点:

这里不需要直接存取图表内容(顺便说一下CvMap 是一个隐藏的构造函数)。图形中的数据可以用cvGetFileNodeByName函数得到,函数返回指向图表文件节点的指针。

一个用户对象是一个标准的类型实例,例如CvMat, CvSeq等,或者任何一个已注册的类型使用cvRegisterTypeInfo。这样的对象最初在文件中表现为一种层级关系,(像表现XML 和 YAM示例文件一样) 。在文件存储器打开并分析之后。当用户调用cvRead或cvReadByName函数时 那么对象将请求被解析 (按照原来的存储方式)。

参与评论