码迷,mamicode.com
首页 > 其他好文 > 详细

OpenCV Tutorials —— File Input and Output using XML and YAML files

时间:2014-11-17 15:45:16      阅读:291      评论:0      收藏:0      [点我收藏+]

标签:des   style   http   io   ar   os   sp   for   文件   

They are two kinds of data structures you may serialize: mappings(like the STL map) and element sequence (like the STL vector>. The difference between these is that in a map every element has a unique name through what you may access it. For sequences you need to go through them to query a specific item.

 

The XMLYAML data structure in OpenCV is FileStorage. To specify that this structure to which file binds on your hard drive you can use either its constructor or the open() function of this:

string filename = "I.xml";
FileStorage fs(filename, FileStorage::WRITE);
\\...
fs.open(filename, FileStorage::READ);

WRITE, READ or APPEND.

The extension specified in the file name also determinates the output format that will be used. The output may be even compressed if you specify an extension such as .xml.gz.

文件的类型由文件扩展名决定,如果定义为 .xml.gz  竟然还能压缩,太残暴了

The file automatically closes when the FileStorage objects is destroyed. However, you may explicitly call for this by using the release function:

fs.release();                                       // explicit close

 

For outputting any type of data structure we need first to specify its name. We do this by just simply printing out the name of this. For basic types you may follow this with the print of the value :  XML 以键值对的形式保存数据~~

fs << "iterationNr" << 100;

Reading in is a simple addressing (via the [] operator) and casting operation or a read via the >> operator :  两种方式均可~~

int itNr;
fs["iterationNr"] >> itNr;
itNr = (int) fs["iterationNr"];

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;

 

For sequence before the first element print the “[” character and after the last one the “]” character:  数组(队列)中的元素,写在中括号中

fs << "strings" << "[";                              // text - string sequence
fs << "image1.jpg" << "Awesomeness" << "baboon.jpg";
fs << "]";    

For maps the drill is the same however now we use the “{” and “}” delimiter characters:

fs << "Mapping";                              // text - mapping
fs << "{" << "One" << 1;
fs <<        "Two" << 2 << "}";

To read from these we use the FileNode and the FileNodeIterator data structures. The [] operator of theFileStorage class returns a FileNode data type. If the node is sequential we can use the FileNodeIterator to iterate through the items:  读取数组(队列)

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;

For maps you can use the [] operator again to acces the given item (or the >> operator too):

n = fs["Mapping"];                                // Read mappings from a sequence
cout << "Two  " << (int)(n["Two"]) << "; ";
cout << "One  " << (int)(n["One"]) << endl << endl;

 

 

ALL  Code

#include "stdafx.h"

#include <opencv2/core/core.hpp>
#include <iostream>
#include <string>

using namespace cv;
using namespace std;

static void help(char** av)
{
	cout << endl
		<< av[0] << " shows the usage of the OpenCV serialization functionality."         << endl
		<< "usage: "                                                                      << endl
		<<  av[0] << " outputfile.yml.gz"                                                 << endl
		<< "The output file may be either XML (xml) or YAML (yml/yaml). You can even compress it by "
		<< "specifying this in its extension like xml.gz yaml.gz etc... "                  << endl
		<< "With FileStorage you can serialize objects in OpenCV by using the << and >> operators" << endl
		<< "For example: - create a class and have it serialized"                         << endl
		<< "             - use it to read and write matrices."                            << endl;
}

class MyData
{
public:
	MyData() : A(0), X(0), id()
	{}
	explicit MyData(int) : A(97), X(CV_PI), id("mydata1234") // explicit to avoid implicit conversion
	{}
	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"];
	}
public:   // Data Members
	int A;
	double X;
	string id;
};

//These write and read functions must be defined for the serialization in FileStorage to work
static void write(FileStorage& fs, const std::string&, const MyData& x)
{
	x.write(fs);
}
static void read(const FileNode& node, MyData& x, const MyData& default_value = MyData()){
	if(node.empty())
		x = default_value;
	else
		x.read(node);
}

// This function will print our custom class to the console
static ostream& operator<<(ostream& out, const MyData& m)
{
	out << "{ id = " << m.id << ", ";
	out << "X = " << m.X << ", ";
	out << "A = " << m.A << "}";
	return out;
}

int main(int ac, char** av)
{
	if (ac != 2)
	{
		help(av);
		return 1;
	}

	string filename = av[1];
	{ //write
		Mat R = Mat_<uchar>::eye(3, 3),
			T = Mat_<double>::zeros(3, 1);
		MyData m(1);

		FileStorage fs(filename, FileStorage::WRITE);

		fs << "iterationNr" << 100;
		fs << "strings" << "[";                              // text - string sequence
		fs << "image1.jpg" << "Awesomeness" << "baboon.jpg";
		fs << "]";                                           // close sequence

		fs << "Mapping";                              // text - mapping
		fs << "{" << "One" << 1;
		fs <<        "Two" << 2 << "}";

		fs << "R" << R;                                      // cv::Mat
		fs << "T" << T;

		fs << "MyData" << m;                                // your own data structures

		fs.release();                                       // explicit close
		cout << "Write Done." << endl;
	}

	{//read
		cout << endl << "Reading: " << endl;
		FileStorage fs;
		fs.open(filename, FileStorage::READ);

		int itNr;
		//fs["iterationNr"] >> itNr;
		itNr = (int) fs["iterationNr"];
		cout << itNr;
		if (!fs.isOpened())
		{
			cerr << "Failed to open " << filename << endl;
			help(av);
			return 1;
		}

		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;


		n = fs["Mapping"];                                // Read mappings from a sequence
		cout << "Two  " << (int)(n["Two"]) << "; ";
		cout << "One  " << (int)(n["One"]) << endl << endl;


		MyData m;
		Mat R, T;

		fs["R"] >> R;                                      // Read cv::Mat
		fs["T"] >> T;
		fs["MyData"] >> m;                                 // Read your own structure_

		cout << endl
			<< "R = " << R << endl;
		cout << "T = " << T << endl << endl;
		cout << "MyData = " << endl << m << endl << endl;

		//Show default behavior for non existing nodes
		cout << "Attempt to read NonExisting (should initialize the data structure with its default).";
		fs["NonExisting"] >> m;
		cout << endl << "NonExisting = " << endl << m << endl;
	}

	cout << endl
		<< "Tip: Open up " << filename << " with a text editor to see the serialized data." << endl;

	return 0;
}

OpenCV Tutorials —— File Input and Output using XML and YAML files

标签:des   style   http   io   ar   os   sp   for   文件   

原文地址:http://www.cnblogs.com/sprint1989/p/4103580.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!