OpenCV读写XML和YAML格式文件

1.什么是XML,YAML

  • XML:最早的通用信息标记语言,可扩展性好,但繁琐
  • YAML:非标记语言,相比XML利用空各缩进分行,显示了数据的结构性,简化了书写格式,降低了复杂度,提升易读性

2.XML,YAML文件的打开和关闭

//OpenCV中标识XML和YAML的数据结构是 FileStorage
string filename = "I.xml";
FileStorage fs(filename, FileStorage::WRITE);
//...
fs.open(filename, FileStorage::READ);
//当 FileStorage 对象被销毁时,文件将自动关闭,也可以显示调用 release 
fs.release();

3.文本和数字的输入及输出

//输出
fs << "iterationNr" << 100;
//输入
int itNr;
fs["iterationNr"] >> itNr;
itNr = (int) fs["iterationNr"];

4.OpenCV数据结构的输入及输出

Mat R = Mat_<uchar >::eye  (3, 3),
    T = Mat_<double>::zeros(3, 1);
fs << "R" << R;                                      // Write cv::Mat
fs << "T" << T;
fs["R"] >> R;                                      // Read cv::Mat
fs["T"] >> T;
  1. vectors(数组)和相应的maps的输入及输出
//对于序列,在第一个元素前输出”[“字符,并在最后一个元素后输出”]“字符
fs << "strings" << "[";                              // text - string sequence
fs << "image1.jpg" << "Awesomeness" << "baboon.jpg";
fs << "]";                                           // close sequence

//对于maps使用相同的方法,但采用”{“和”}“作为分隔符
fs << "Mapping";                              // text - mapping
fs << "{" << "One" << 1;
fs <<        "Two" << 2 << "}";

//数据读取,可使用 FileNode 和 FileNodeIterator 数据结构。 FileStorage 的[] 操作符将返回一个 FileNode 数据类型。如果这个节点是序列化的,我们可以使用 FileNodeIterator 来迭代遍历所有元素
FileNode n = fs["strings"];                         // Read string sequence - Get node
if (n.type() != FileNode::SEQ)
{
    cerr << "strings is not a sequence! FAIL" << endl;
    return 1;
}
FileNodeIterator it = n.begin(), it_end = n.end(); // Go through the node
for (; it != it_end; ++it)
    cout << (string)*it << endl;
//对于maps类型,可以用 [] 操作符访问指定的元素(或者 >> 操作符)
n = fs["Mapping"];                                // Read mappings from a sequence
cout << "Two  " << (int)(n["Two"]) << "; ";
cout << "One  " << (int)(n["One"]) << endl << endl;

6.自定义数据类型的读写

class MyData
{
public:
      MyData() : A(0), X(0), id() {}
public:   // Data Members
   int A;
   double X;
   string id;
};

添加内部和外部的读写函数,就可以使用OpenCV I/O XML/YAML接口对其进行序列化(就像对OpenCV数据结构进行序列化一样)。内部函数定义如下

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"];
}

接下来在类的外部定义以下函数

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);
}

示例:
写文件(单个变量)

#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
int main()
{
	FileStorage fs("test.yaml", FileStorage::WRITE); //换成xml效果一样,yaml文件格式相对更直观

	fs << "v" << 1.23;

	fs.release();

	cout << "文件读写完毕!" << sendl;

	return 0;
}

读文件(单个变量)

#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;

int main()
{
    FileStorage fs("test.yaml", FileStorage::READ); //换成xml效果一样,yaml文件格式相对更直观

    if (!fs.isOpened())
    {
        cout << "No file!" << endl;
        return false;
    }

    double v = (double)fs["v"];
    cout << "v: " << v << endl;

    fs.release();

    cout << "文件读取完毕!" <<endl;

    return 0;
}

写文件(多个变量)

#include <opencv2/opencv.hpp>
using namespace cv;

int main()
{
	FileStorage fs("test.yaml", FileStorage::WRITE); //换成xml效果一样,yaml文件格式相对更直观
	//FileStorage fs("test.xml", FileStorage::WRITE);

	fs << "v" << 1.23;

	Mat Matrix1 = (Mat_<double>(3, 3) << 1000, 0, 320, 0, 1000, 240, 0, 0, 1);
	Mat Matrix2 = (Mat_<double>(3, 3) << 100, 0, 32, 0, 100, 24, 0, 0, 0.1);
	std::vector<Mat> Mat_vector;

	Mat_vector.push_back(Matrix1);
	Mat_vector.push_back(Matrix2);

	fs << "Matrix1" << Matrix1;
	fs << "Mat_vector"
	   << "[" << Mat_vector << "]";

	Point3d p1(1.1, 2.2, 3.3);
	Point3d p2(1.11, 2.22, 3.33);
	std::vector<Point3d> point_vector;
	point_vector.push_back(p1);
	point_vector.push_back(p2);

	fs << "p1" << p1;
	fs << "point_vector"
	   << "[" << point_vector << "]";

	fs.release();

	std::cout << "文件读写完毕!" << std::endl;

	return 0;
}

读文件(多个变量)

#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;

int main()
{
    FileStorage fs("test.yaml", FileStorage::READ); //换成xml效果一样,yaml文件格式相对更直观
    //FileStorage fs("test.xml", FileStorage::READ);

    if (!fs.isOpened())
    {
        cout << "No file!" << endl;
        return false;
    }

    double v = (double)fs["v"];
    cout << "v: " << v << endl;

    Mat Matrix1;
    fs["Matrix1"] >> Matrix1;
    cout << "Matrix1: " << Matrix1 << endl;

    vector<Mat> Mat_vector;
    fs["Mat_vector"][0] >> Mat_vector;
    cout << "Mat_vector: " << endl;
    for (Mat temp : Mat_vector)
    {
        cout << temp << endl;
    }

    Point3d p1;
    fs["p1"] >> p1;
    cout << "p1: " << p1 << endl;

    vector<Point3d> point_vector;
    fs["point_vector"][0] >> point_vector;
    cout << "point_vector: " << endl;
    for (Point3d temp : point_vector)
    {
        cout << temp << endl;
    }

    fs.release();

    std::cout << "文件读取完毕!" << std::endl;

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值