我们会很现实的问
这个用来干嘛噢?
工程界很注重实用和效率
没用的大家都会懒得去认知吧 = =
我目前也没接触过用到这个文件的东西
Goolge it。。
立体视觉 立体标定参数之后,就可以把参数放入xml文件
训练器 训练结果保存为xml格式用以进行编码
恩哼。。差不多是这样
【8】file_input_output
OpenCV2.3.1\opencv\samples\cpp\tutorial_code\core\file_input_output
XML和YAML的串行化分别采用两种不同的数据结构:
mappings (就像STL map) 和 element sequence (比如 STL vector>。
二者之间的区别
在map中每个元素都有一个唯一的标识名供用户访问;
在sequences中你必须遍历所有的元素才能找到指定元素。
》》》》》》》》》》》》》》》》
XML\YAML 文件的打开和关闭。
string filename = "I.xml";
FileStorage fs(filename, FileStorage::WRITE);
\\...
fs.open(filename, FileStorage::READ);
fs.release(); // 显示关闭
》》》》》》》》》》》》》》》》》》》
输入\输出文本和数字。
数据结构使用与STL相同的 << 输出操作符。
输出任何类型的数据结构时,首先都必须指定其标识符,这通过简单级联输出标识符即可实现。
fs << "iterationNr" << 100;
读入则通过简单的寻址(通过 [] 操作符)操作和强制转换或 >> 操作符实现:
int itNr;
fs["iterationNr"] >> itNr;
itNr = (int) fs["iterationNr"];
输入\输出OpenCV数据结构。 其实和对基本类型的操作方法是相同的:
Mat R = Mat_<uchar >::eye (3, 3),
T = Mat_<double>::zeros(3, 1);
fs << "R" << R; // 写 cv::Mat
fs << "T" << T;
fs["R"] >> R; // 读 cv::Mat
fs["T"] >> T;
》》》》》》》》》》》》》》》》》》》》》》》
输入\输出 vectors(数组)和相应的maps. 之前提到我们也可以输出maps和序列(数组, vector)。同样,首先输出变量的标识符,接下来必须指定输出的是序列还是map。
》》
对于序列,在第一个元素前输出”[“字符,并在最后一个元素后输出”]“字符:
fs << "strings" << "["; // 文本 - 字符串序列
fs << "image1.jpg" << "Awesomeness" << "baboon.jpg";
fs << "]"; // 序列结束
》》
对于maps使用相同的方法,但采用”{“和”}“作为分隔符。
fs << "Mapping"; // 文本 - mapping
fs << "{" << "One" << 1;
fs << "Two" << 2 << "}";
》》》》》》》》》》》》》》》》》》》
对于数据读取,可使用 FileNode 和 FileNodeIterator 数据结构。
FileStorage 的[] 操作符将返回一个 FileNode 数据类型。
如果这个节点是序列化的,我们可以使用 FileNodeIterator 来迭代遍历所有元素。
FileNode n = fs["strings"]; // 读取字符串序列 - 获取节点
if (n.type() != FileNode::SEQ)
{
cerr << "strings is not a sequence! FAIL" << endl;
return 1;
}
FileNodeIterator it = n.begin(), it_end = n.end(); // 遍历节点
for (; it != it_end; ++it)
cout << (string)*it << endl;
》》》》》》》》》》》》》》》》》》》》》》》》》》
对于maps类型,可以用 [] 操作符访问指定的元素(或者 >> 操作符):
n = fs["Mapping"]; // 从序列中读取map
cout << "Two " << (int)(n["Two"]) << "; ";
cout << "One " << (int)(n["One"]) << endl << endl;
》》》》》》》》》》》》》》》》》》》》》》》》》》
读写自定义数据类型。 假设你定义了如下数据类型:
class MyData
{
public:
MyData() : A(0), X(0), id() {}
public: // 数据成员
int A;
double X;
string id;
};
添加内部和外部的读写函数,就可以使用OpenCV I/O XML/YAML接口对其进行序列化(就像对OpenCV数据结构进行序列化一样)。内部函数定义如下:
void write(FileStorage& fs) const //对自定义类进行写序列化
{
fs << "{" << "A" << A << "X" << X << "id" << id << "}";
}
void read(const FileNode& node) //从序列读取自定义类
{
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);
}
这儿可以看到,如果读取的节点不存在,我们返回默认值。更复杂一些的解决方案是返回一个对象ID为负值的实例。
一旦添加了这四个函数,就可以用 >> 操作符和 << 操作符分别进行读,写操作:
MyData m(1);
fs << "MyData" << m; // 写自定义数据结构
fs["MyData"] >> m; // 读自定义数据结构
》》》》》》》》》》》》》》》》》》》》》》》
或试着读取不存在的值:
fs["NonExisting"] >> m; // 请注意不是 fs << "NonExisting" << m
cout << endl << "NonExisting = " << endl << m << endl;
这个用来干嘛噢?
工程界很注重实用和效率
没用的大家都会懒得去认知吧 = =
我目前也没接触过用到这个文件的东西
Goolge it。。
立体视觉 立体标定参数之后,就可以把参数放入xml文件
训练器 训练结果保存为xml格式用以进行编码
恩哼。。差不多是这样
【8】file_input_output
OpenCV2.3.1\opencv\samples\cpp\tutorial_code\core\file_input_output
XML和YAML的串行化分别采用两种不同的数据结构:
mappings (就像STL map) 和 element sequence (比如 STL vector>。
二者之间的区别
在map中每个元素都有一个唯一的标识名供用户访问;
在sequences中你必须遍历所有的元素才能找到指定元素。
》》》》》》》》》》》》》》》》
XML\YAML 文件的打开和关闭。
string filename = "I.xml";
FileStorage fs(filename, FileStorage::WRITE);
\\...
fs.open(filename, FileStorage::READ);
fs.release(); // 显示关闭
》》》》》》》》》》》》》》》》》》》
输入\输出文本和数字。
数据结构使用与STL相同的 << 输出操作符。
输出任何类型的数据结构时,首先都必须指定其标识符,这通过简单级联输出标识符即可实现。
fs << "iterationNr" << 100;
读入则通过简单的寻址(通过 [] 操作符)操作和强制转换或 >> 操作符实现:
int itNr;
fs["iterationNr"] >> itNr;
itNr = (int) fs["iterationNr"];
输入\输出OpenCV数据结构。 其实和对基本类型的操作方法是相同的:
Mat R = Mat_<uchar >::eye (3, 3),
T = Mat_<double>::zeros(3, 1);
fs << "R" << R; // 写 cv::Mat
fs << "T" << T;
fs["R"] >> R; // 读 cv::Mat
fs["T"] >> T;
》》》》》》》》》》》》》》》》》》》》》》》
输入\输出 vectors(数组)和相应的maps. 之前提到我们也可以输出maps和序列(数组, vector)。同样,首先输出变量的标识符,接下来必须指定输出的是序列还是map。
》》
对于序列,在第一个元素前输出”[“字符,并在最后一个元素后输出”]“字符:
fs << "strings" << "["; // 文本 - 字符串序列
fs << "image1.jpg" << "Awesomeness" << "baboon.jpg";
fs << "]"; // 序列结束
》》
对于maps使用相同的方法,但采用”{“和”}“作为分隔符。
fs << "Mapping"; // 文本 - mapping
fs << "{" << "One" << 1;
fs << "Two" << 2 << "}";
》》》》》》》》》》》》》》》》》》》
对于数据读取,可使用 FileNode 和 FileNodeIterator 数据结构。
FileStorage 的[] 操作符将返回一个 FileNode 数据类型。
如果这个节点是序列化的,我们可以使用 FileNodeIterator 来迭代遍历所有元素。
FileNode n = fs["strings"]; // 读取字符串序列 - 获取节点
if (n.type() != FileNode::SEQ)
{
cerr << "strings is not a sequence! FAIL" << endl;
return 1;
}
FileNodeIterator it = n.begin(), it_end = n.end(); // 遍历节点
for (; it != it_end; ++it)
cout << (string)*it << endl;
》》》》》》》》》》》》》》》》》》》》》》》》》》
对于maps类型,可以用 [] 操作符访问指定的元素(或者 >> 操作符):
n = fs["Mapping"]; // 从序列中读取map
cout << "Two " << (int)(n["Two"]) << "; ";
cout << "One " << (int)(n["One"]) << endl << endl;
》》》》》》》》》》》》》》》》》》》》》》》》》》
读写自定义数据类型。 假设你定义了如下数据类型:
class MyData
{
public:
MyData() : A(0), X(0), id() {}
public: // 数据成员
int A;
double X;
string id;
};
添加内部和外部的读写函数,就可以使用OpenCV I/O XML/YAML接口对其进行序列化(就像对OpenCV数据结构进行序列化一样)。内部函数定义如下:
void write(FileStorage& fs) const //对自定义类进行写序列化
{
fs << "{" << "A" << A << "X" << X << "id" << id << "}";
}
void read(const FileNode& node) //从序列读取自定义类
{
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);
}
这儿可以看到,如果读取的节点不存在,我们返回默认值。更复杂一些的解决方案是返回一个对象ID为负值的实例。
一旦添加了这四个函数,就可以用 >> 操作符和 << 操作符分别进行读,写操作:
MyData m(1);
fs << "MyData" << m; // 写自定义数据结构
fs["MyData"] >> m; // 读自定义数据结构
》》》》》》》》》》》》》》》》》》》》》》》
或试着读取不存在的值:
fs["NonExisting"] >> m; // 请注意不是 fs << "NonExisting" << m
cout << endl << "NonExisting = " << endl << m << endl;
看最后输出的文件吧~
所以这篇的意义在于
用到的时候再来翻。