博客专栏

EEPW首页 > 博客 > 独家|OpenCV1.8 使用XML和YAML文件实现文件的输入/输出

独家|OpenCV1.8 使用XML和YAML文件实现文件的输入/输出

发布人:数据派THU 时间:2021-08-20 来源:工程师 发布文章

目标

本小节将回答以下问题:

如何使用YAML或XML文件打印和读取文本输入到文件和OpenCV?

如何对OpenCV数据结构做相同的操作?

如何为自定义的数据结构做相同的操作?

OpenCV中cv::FileStorage , cv::FileNode 和 cv::FileNodeIterator 的数据结构和使用方法。

源代码

C ++

可以在原文下载源代码,也可以在以下目录中

samples/cpp/tutorial_code/core/file_input_output/file_input_output.cpp 找到 OpenCV的源代码库。

这里还有完整的示例代码。

1.png2.png3.png4.png

代码详解

在这里,只讲解XML和YAML文件输入。你的输出(及其对应的输入)只能是具有XML和YAML扩展名的文件,并带有XML和YAML数据结构。这里有两种可以串行化的数据结构:映射(诸如STL映射和Python字典)和元素序列(如STL向量)。二者之间的区别是,映射中的每一个元素均有唯一的名称,可以通过该名称进行访问。对于序列而言,则需要通过遍历来查询一个具体的项目。

1. 打开和关闭XML / YAML文件。在读写文件内容之前,首先需要打开文件,在使用结束时关闭文件。OpenCV中的XML / YAML数据结构是CV :: FileStorage。具体来说,该结构可以将文件与硬盘驱动器绑定起来,这样便可以使用它的构造函数或open()函数:

5.png

无论是哪一种数据结构,它的第二个参数都是一个常数,可以用来指定操作类型,比如:写入读取或追加。文件的扩展名还决定了输出文件的格式。如果输出文件的扩展名为*.xml.gz*,甚至能够输出压缩文件。

当释放CV :: FileStorage对象之后,该文件将自动关闭。可以通过调用release 函数显式地自动关闭文件:

6.png

2. 文本和数字的输入/输出。C ++中,数据结构使用STL库中的<<输出操作符。Python中,则使用了 )。输出任何类型的数据结构,首先需要指定其名称,在C++中,只需要单纯地将名称推给数据流。在Python中,写函数的第一个参数便是名称。可以用以下命令打印文本和数字:

7.png

读取是一种简单的寻址方式(使用 []操作符)、casting操作或使用>>操作符读出。在Python中,使用real()和getNode()函数来寻址:

8.png

3. OpenCV数据结构的输入/输出。该操作与基础C ++和Python的类型完全相同。

9.png

4. 向量(数组)的输入/输出和相关映射。正如前文所述,输出可以是映射和序列(数组,向量)。同样,可以先打印变量的名称,然后指定输出的序列或映射。

在序列的第一个元件之前打印“[”字符,在序列的最后一个元素之后打印 “]”字符。在Python语言中,调用 FileStorage.startWriteStruct(structure_name,struct_type) , 其中struct_type为 cv2.FileNode_MAP或cv2.FileNode_SEQ结构,最后调用FileStorage.endWriteStruct()来实现结构:

10.png

同理,对用映射,可以使用“{”和“}”分隔符来代替“[”和]”字符:

11.png

在读操作中,可以使用的和cv::FileNodeIterator两种数据结构。cv::FileStorage 类中的[]操作符(在Python中为 getNode()函数)可以返回一个数据类型。如果节点为序列结构,则可以使用CV :: FileNodeIterator进行迭代。在Python中,可以调用at()函数访问序列中的元素,并用size() 函数返回序列长度:

12.png

对于映射,可以使用[]操作符(在Python中为at()函数)来访问数据(也可使用>>操作符):

13.png

5. 读/写自定义的数据结构。假定有一个数据结构,如下所示:

微信图片_20210820192839.jpg

在C ++中,通过OpenCV 的XML / YAML I / O接口实现串行化?(仅针对OpenCV的数据结构),为自定义的类添加读取和写入函数。在Python中,可以在类的内部一个读取和写入函数来完成类似的操作。内部情况如下:

15.png

在C ++中,需要在类的外部添加下列函数的定义:

16.png

如果用户试图读取一个不存在的节点时,只返回默认初始值。而更为详细的解决方案则是为对象ID返回一个为-1的值。

一旦添加了该函数定义,则这四个函数便会使用>>操作符写入和<<操作符读取(或是Python中的输入/输出函数)

17.png

或者可以尝试读取一个不存在的节点:

18.png

程序运行结果

在大多情况下,只需要将定义好的数值打印出来,在显示屏幕上可以看到以下运行输出结果:

19.png

更加有趣的是:还可以在输出的XML文件中看到以下结果:

20.png

或者在输出的YAML文件中看到以下结果:

21.png

可以在YouTube网站观看这个示例的运行视频。

注:本文以C++语言代码为例,获取Java和python版本可在原文中查看:

https://docs.opencv.org/4.5.2/dd/d74/tutorial_file_input_output_with_xml_yml.html

*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。



关键词: AI

相关推荐

技术专区

关闭