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