OpenCV3之XML文件和YAML文件的文件读写


一、XML文件和YAML文件

这两种文件可以作为参数配置文件。

这两种文件有着特定的格式,表示这是能被opencv读取的。你不要记住这格式怎么写,只需要大概了解样子就行,格式填充会由程序编译自动填写

1.XML文件

<?xml version="1.0"?>
<opencv_storage>
	<!--主体内容-->
</opencv_storage>

2.YAML文件

也叫xxx.yml文件

%YAML:1.0
---

如果你想了解这东西怎么手动写:配置文件 .yml 写法小结

3.指定文件

对于这两种文件,读写的函数操作都一样,只要你指定文件名的后缀xxx.xml还是xxx.yaml,就能输出读取相应格式的文件。

二、cv库函数

注意:不能用一个FileStorage句柄同时读写,也不能使用两个FileStorage句柄同时读写,必须一个执行完关闭后再打开另一个进行操作。

1.打开 FileStorage

我们使用FileStorage类作为文件的句柄,类似c的FILE

(1)带参构造函数

cv::FileStorage::FileStorage(	
	const String & 	filename,
	int 			flags,
	const String & 	encoding = String() 
)	

参数:

  • filenamexxx.xml是xml文件,xxx.yaml是yaml文件
  • flags:操作类型。不能同时读写,可执行但无结果。
    • FileStorage::WRITE:写入
    • FileStorage::READ:读取
    • FileStorage::APPEND:附加
  • encoding:编码格式UTF-8,不用管。

例如:

// 打开文件,写操作
string filename = "myXML.xml";
FileStorage fs(filename, FileStorage::WRITE);

(2)无参构造+open()

virtual bool cv::FileStorage::open	(
	const String & 	filename,
	int 			flags,
	const String & 	encoding = String() 
)	

例如:

// 打开文件,写操作
string filename = "myXML.xml";
FileStorage fs;
fs.open(filename, FileStorage::WRITE);

2.是否打开成功 isOpened

virtual bool cv::FileStorage::isOpened()	const

返回值:

  • true:成功
  • false:失败

3.关闭 release

virtual void cv::FileStorage::release()	

虽然会自动关闭,但建议手动调用。

4.C++基本类型的读写

类型写入xml中读出
int100100100
double100.11.0009999999999999e+02100.1
booltrue1true
string"hello"hellohello
string"hello world""hello world""hello world"

(1)写

使用操作符<<fs_write << "xml中变量的名字" << 变量的值;

fs_write << "speed" << 100;

xml中:

<speed>100</speed>

(2)读

方式一:

使用操作符>>:先声明变量变量的类型 变量的名字;,再fs_read["xml中变量的名字"] >> 变量的名字;

int speed;
fs_read["speed"] >> speed;

方式二:

强制类型转化:(变量的类型)fs_read["xml中变量的名字"];

int speed = (int)fs_read["speed"];
cout << (int)fs_write["speed"] << endl;

5.c++的STL

可以用vector

// 读
vector<int> v1(2, 2);
fs_write << "std_vector" << v1;

// 写
vector<int> v2;
fs_read["std_vector"] >> v2;
for (int i = 0; i < v2.size(); i++)
{
    cout << v2[i] << endl;
}

在这里插入图片描述

6.OpenCV数据类型的读写

操作同上

类型写入xml中读出
Mat(Mat_<uchar>(2, 3) << 1, 2, 3, 4, 5, 6);在这里插入图片描述一样
SizeSize(200,100);在这里插入图片描述一样
Vec3iVec3i(1,2,3);在这里插入图片描述一样

后面就不试了

都只有第一种读法,比如Mat类型:

// 写

fs_write << "opencv_matrix" << (Mat_<uchar>(2, 3) << 1, 2, 3, 4, 5, 6);

// 读    
Mat result;
fs_read["opencv_matrix"] >> result;
cout << result << endl;

// 报错
// cout << (Mat)fs_read["opencv_matrix"] << endl;

7.sequence和mapping的读写

(1)介绍

sequence是处理类型STL的vector的xml和yaml的数据类型。
mapping是处理类型STL的map的xml和yaml的数据类型。

(2)实际意义

sequence模仿vector,而opencv的数据类型中也有模仿vectorVec,而Vec中只能存数字类型。所以简单的数字类型直接用Vec就行,复杂的数据类型如string,我们再用sequence
在这里插入图片描述

(3)sequence的读写

写:在数据前后加了个[]表示sequence类型。

读:类似List链表遍历,先读取该链表块FileNode,再用迭代器FileNodeIterator遍历链表节点,每个节点的读的方式和上面一样有两种。

// 写
fs_write << "sequence_names"
         << "["
         << 132
         << 223
         << 323
         << "]";

// 读
FileNode fn_sequence_names = fs_read["sequence_names"];
if (fn_sequence_names.type() != FileNode::SEQ)
{
    cout << "the type is not sequence!\n";
    return 0;
}
int v[3];
int i = 0;
for (FileNodeIterator fni = fn_sequence_names.begin(); fni != fn_sequence_names.end(); fni++)
{
    *fni >> v[i++];		    // 或者(int)*fni >> v[i++];
}

xml中:可以看到和opencv的存储样式一样。
在这里插入图片描述

(4)mappping的读写

写:在数据前后加了个{}表示mappping类型,单个键值对是先键后值 << "键名" << 值

读:类似map根据键获得值,先读取该链表块FileNode,再用键获得值。每个键值对的读的方式和上面一样有两种。

PS:键必须字符串类型,键不能重复;同一个mapping中的值的类型可以不一样,值可以重复。

// 写
fs_write << "mapping_names"
         << "{"
         << "banana" << "chicken"
         << "apple" << 223
         << "lemon" << 323
         << "}";

// 读
FileNode fn_mapping_names = fs_read["mapping_names"];
if (fn_mapping_names.type() != FileNode::MAP)
{
    cout << "the type is not mapping!\n";
    return 0;
}
string banana;
fn_mapping_names["banana"] >> banana;
int apple = (int)fn_mapping_names["apple"];

在这里插入图片描述

三、例子

1.给定类型

#include <iostream>
#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;

int main()
{
    string filename = "myXML.xml";
    /*********************************** 打开文件,写操作 ************************************/
    FileStorage fs_write;
    fs_write.open(filename, FileStorage::WRITE);

    /* 写入 */

    // c++
    fs_write << "cpp_speed" << 100;

    // std::vector
    vector<int> v1(2, 2);
    fs_write << "std_vector" << v1;

    // Opencv
    fs_write << "opencv_matrix" << (Mat_<uchar>(2, 3) << 1, 2, 3, 4, 5, 6);

    // sequence
    fs_write << "sequence_names"
             << "["
             << 132
             << 223
             << 323
             << "]";

    // mapping
    fs_write << "mapping_names"
             << "{"
             << "banana"
             << "chicken"
             << "apple" << 223
             << "lemon" << 323
             << "}";
    fs_write.release();

    /************************************* 打开文件,读操作 ************************************/
    FileStorage fs_read;
    fs_read.open(filename, FileStorage::READ);

    /* 读取 */

    // c++
    cout << (int)fs_read["cpp_speed"] << endl;

    // std::vector
    vector<int> v2;
    fs_read["std_vector"] >> v2;
    for (int i = 0; i < v2.size(); i++)
    {
        cout << v2[i] << endl;
    }

    // Opencv
    Mat result;
    fs_read["opencv_matrix"] >> result;
    cout << result << endl;
    // !cout << (Mat)fs_read["opencv_matrix"] << endl;

    // sequence
    FileNode fn_sequence_names = fs_read["sequence_names"];
    if (fn_sequence_names.type() != FileNode::SEQ)
    {
        cout << "the type is not sequence!\n";
        return 0;
    }
    for (FileNodeIterator fni = fn_sequence_names.begin(); fni != fn_sequence_names.end(); fni++)
    {
        cout << (int)*fni << endl;
    }

    // mapping
    FileNode fn_mapping_names = fs_read["mapping_names"];
    if (fn_mapping_names.type() != FileNode::MAP)
    {
        cout << "the type is not mapping!\n";
        return 0;
    }
    cout << (string)fn_mapping_names["banana"] << endl;
    cout << (int)(fn_mapping_names)["apple"] << endl;
    cout << (int)(fn_mapping_names)["lemon"] << endl;

    fs_read.release();
    return 0;
}

在这里插入图片描述
在这里插入图片描述

2.自定义类型

#include <iostream>
#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;

class MyData
{
public:
    MyData() : A(0), X(0), id() {}
    explicit MyData(int A) : A(A), X(CV_PI), id("mydata1234") {}

public:
    int A;
    double X;
    string id;

public:
    // inside of your class
    void write(FileStorage &fs) const //Write serialization for this class
    {
        fs << "{"
           << "A" << A << "X" << X << "id" << id << "}";
    }
    void read(const FileNode &node) //Read serialization for this class
    {
        A = (int)node["A"];
        X = (double)node["X"];
        id = (string)node["id"];
    }
};

// outside of your class
void write(FileStorage &fs, const std::string &, const MyData &x)
{
    x.write(fs);
}
void read(const FileNode &node, MyData &x, const MyData &default_value = MyData())
{
    if (node.empty())
        x = default_value;
    else
        x.read(node);
}

// 这个和主题无关,只是让其可以直接用cout输出MyData的值是什么而已
ostream &operator<<(ostream &out, const MyData &m)
{
    out << "id = " << m.id << ", "
        << "X = " << m.X << ", "
        << "A = " << m.A;
    return out;
}

int main()
{
    string filename = "myXML.xml";
    /*********************************** 打开文件,写操作 ************************************/
    FileStorage fs_write;
    fs_write.open(filename, FileStorage::WRITE);

    MyData m1(1);
    fs_write << "MyData" << m1;

    fs_write.release();

    /************************************* 打开文件,读操作 ************************************/
    FileStorage fs_read;
    fs_read.open(filename, FileStorage::READ);

    MyData m2;
    fs_read["MyData"] >> m2;
    cout << m2 << endl;

    fs_read.release();
    return 0;
}

在这里插入图片描述
在这里插入图片描述


reference

opencv3.4.6官方文档:tutorial_file_input_output_with_xml_yml.html

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
OpenCVXML文件是一种用于存储和读取数据的格式。XML文件通常用于存储和传输结构化的数据,而OpenCV则使用XML文件来保存和加载图像处理中的参数和配置信息。 在OpenCV中,可以使用cv::FileStorage类来读取和写入XML文件。通过这个类,可以打开XML文件并从中读取或写入数据。对于读取XML文件,可以使用cv::FileStorage::READ参数来指定读取模式。例如,可以使用以下代码来读取XML文件中的深度数据并显示深度图像: ``` cv::FileStorage fs; cv::Mat DepthData; std::string filename = "test.xml"; // XML文件的路径和名称 fs.open(filename, cv::FileStorage::READ); // 打开指定的XML文件 if (!fs.isOpened()) { std::cerr << "Error: cannot open XML file"; return -1; } fs["Depth_Data"] >> DepthData; // 将XML文件中的深度数据导入到变量中 fs.release(); cv::imshow("DepthImage", DepthData); // 显示导入的数据 cv::waitKey(30); // 等待30ms,防止显示图像不响应 ``` 另外,如果需要写入数据到XML文件中,可以使用cv::FileStorage::WRITE参数来指定写入模式。例如,可以使用以下代码来创建一个新的XML文件并写入数据: ``` cv::FileStorage fswrite; fswrite.open("test.xml", cv::FileStorage::WRITE); // 打开或创建XML文件 // 在这里添加需要写入的数据 fswrite.release(); // 关闭XML文件 ``` 综上所述,OpenCVXML文件是一种用于存储和读取数据的格式,通过cv::FileStorage类可以方便地读取和写入XML文件中的数据。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [Opencvxml文件操作](https://blog.csdn.net/u013752202/article/details/50224049)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] - *2* [OpenCV 读取.xml文件](https://blog.csdn.net/weixin_30505485/article/details/96203474)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值