\tutorial_code\core\file_input_output

来源:互联网 发布:mac制作win8安装u盘 编辑:程序博客网 时间:2024/06/08 10:50
我们会很现实的问

这个用来干嘛噢?




工程界很注重实用和效率

没用的大家都会懒得去认知吧 = =



我目前也没接触过用到这个文件的东西

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;






看最后输出的文件吧~










所以这篇的意义在于
用到的时候再来翻。



原创粉丝点击