core核心模块--输入输出XML和YAML文件

1.目的
(1)如何将文本写入XML或者YAML文件,及如何利用openCV读取XML和YAML文件
(2)如何利用YAML和XML文件存取openCV数据结构
(3)如何利用YAML或XML存取自定义数据结构
(4)openCV中数据结构的使用方法FileStorage,FileNode,FileNodeIterator

2.部分代码解释
(1)构造一个自己的数据结构(用类来定义),在MyData类中定义了类的数据成员的读写read&write

class MyData{
public:
    int A;
    double X;
    string id;
public:
    MyData():A(0),X(0),id(){}
    //防止隐式转换
    explicit MyData(int):A(97),X(CV_PI),id("mydata"){}
    void write(FileStorage& fs){
        fs <<  "A" << A << "X" << X << "id" << id;
    }
    void read(FileNode& node){
        A = (int)node["A"];
        X = (double)node["X"];
        id = (string)node["id"];
    }
};

(2)定义外部读写函数

//外部写函数调用内部函数实现对象的写操作
void write(FileStorage& fs, MyData& myData){
    myData.write(fs);
}
//外部读函数调用内部函数实现对象的读操作
void read(FileNode& node, MyData& myData, MyData defaultValue = MyData()){
    if(node.empty()){
        myData = defaultValue;
    }else{
        myData.read(node);
    }
}

(3)运算符重载

//cout << 重载
ostream& operator<<(ostream& out, MyData& myData){
    out << "{id=" << myData.id << ",";
    out << "X=" << myData.X << ",";
    out << "A=" << myData.A << "}";
    return(out);
}
//FileStorage << 重载
FileStorage& operator<<(FileStorage& fs, MyData& myData){
    fs << "myData" << "{";
    fs << "id" << myData.id;
    fs << "X" << myData.X;
    fs << "A" << myData.A;
    fs << "}";
    return(fs);
}

//FileNode >>重载
MyData& operator>>(FileNode& node, MyData& myData){
    myData.read(node);
    return(myData);
}

(4)文件写

//使用openCV中的FileStorage读写文件
//FileStorage::WRITE定义文件的操作方式
//文件的操作方式包括:WRITE,READ,APPEND
FileStorage fs(filename, FileStorage::WRITE);

(5)文件写操作

    {//write
        fs << "iterationNr" << 100;
        //文本序列,只有全部读取才能获得相应元素
        fs << "strings" << "[";
        fs << "lena.jpg" << "awesomeness" << "baboon.jpg";
        fs << "]";
        //文本映射表,可以通过键值对的方式访问元素
        fs << "mapping" << "{";
        fs << "One" << 1;
        fs << "Two" << 2;
        fs << "}";
        //矩阵
        fs << "R" << R;
        fs << "I" << I;
        fs << myData;
        //显式关闭文件
        fs.release();
        cout << "write done!!!" << endl;
    }

(6)文件读操作

    {//read
        FileStorage fs(filename, FileStorage::READ);
        int iterationNr;
        fs["iterationNr"] >> iterationNr;
        //获取映射表
        FileNode node = fs["mapping"];
        cout << iterationNr << endl;
        cout << (int)node["One"] << " " << (int)node["Two"] << endl;
        //获取数据流序列
        node = fs["strings"];
        //数据流需要通过迭代器来访问元素
        FileNodeIterator begin = node.begin();
        FileNodeIterator end = node.end();
        for(;begin!=end; ++begin){
            cout << (string)*begin << endl;
        }
        //读取矩阵
        Mat R_, I_;
        MyData m;
        fs["R"] >> R_;
        fs["I"] >> I_;
        cout << endl << R_ << endl;
        cout << I_ << endl;
        //读取MyData数据格式
        node = fs["myData"];
        //调用上述重载的运算符
        node >> m;
        //调用上述重载的运算符
        cout << endl << m << endl;
        cout << "read done!!!" << endl;
    }

3.完整代码
(1)CommonInclude.h

#ifndef COMMON_INCLUDE
#define COMMON_INCLUDE
#include
#include
#include
#include
using namespace std;
using namespace cv;
#endif

(2)FileRW.cpp

#include "CommonInclude.h"
#include
class MyData{
public:
    int A;
    double X;
    string id;
public:
    MyData():A(0),X(0),id(){}
    //防止隐式转换
    explicit MyData(int):A(97),X(CV_PI),id("mydata"){}
    void write(FileStorage& fs){
        fs <<  "A" << A << "X" << X << "id" << id;
    }
    void read(FileNode& node){
        A = (int)node["A"];
        X = (double)node["X"];
        id = (string)node["id"];
    }
};

void write(FileStorage& fs, MyData& myData){
    myData.write(fs);
}
void read(FileNode& node, MyData& myData, MyData defaultValue = MyData()){
    if(node.empty()){
        myData = defaultValue;
    }else{
        myData.read(node);
    }
}

//操作符号重载
ostream& operator<<(ostream& out, MyData& myData){
    out << "{id=" << myData.id << ",";
    out << "X=" << myData.X << ",";
    out << "A=" << myData.A << "}";
    return(out);
}
//<<重定义
FileStorage& operator<<(FileStorage& fs, MyData& myData){
    fs << "myData" << "{";
    fs << "id" << myData.id;
    fs << "X" << myData.X;
    fs << "A" << myData.A;
    fs << "}";
    return(fs);
}

//>>重定义
MyData& operator>>(FileNode& node, MyData& myData){
    myData.read(node);
    return(myData);
}

int main(int argc, char** argv){
    if(argc < 2){
        cout << "more parameters are required!!!" << endl;
        return(-1);
    }
    char* filename = argv[1];
    Mat R = Mat_::zeros(3,3);
    Mat I = Mat_<double>::eye(3,3);
    FileStorage fs(filename, FileStorage::WRITE);
    MyData myData = MyData(1);
    {//write
        fs << "iterationNr" << 100;
        //文本序列,只有全部读取才能获得相应元素
        fs << "strings" << "[";
        fs << "lena.jpg" << "awesomeness" << "baboon.jpg";
        fs << "]";
        //文本映射表
        fs << "mapping" << "{";
        fs << "One" << 1;
        fs << "Two" << 2;
        fs << "}";
        fs << "R" << R;
        fs << "I" << I;
        fs << myData;
        //显式关闭文件
        fs.release();
        cout << "write done!!!" << endl;
        //cout << myData;
        //write(fs, myData);
    }
    {//read
        FileStorage fs(filename, FileStorage::READ);
        int iterationNr;
        fs["iterationNr"] >> iterationNr;
        //获取映射表
        FileNode node = fs["mapping"];
        cout << iterationNr << endl;
        cout << (int)node["One"] << " " << (int)node["Two"] << endl;
        //获取数据流序列
        node = fs["strings"];
        FileNodeIterator begin = node.begin();
        FileNodeIterator end = node.end();
        for(;begin!=end; ++begin){
            cout << (string)*begin << endl;
        }
        //读取矩阵
        Mat R_, I_;
        MyData m;
        fs["R"] >> R_;
        fs["I"] >> I_;
        cout << endl << R_ << endl;
        cout << I_ << endl;
        //读取MyData数据格式
        node = fs["myData"];
        node >> m;
        cout << endl << m << endl;
        //cout << endl << (double)node["X"] << endl;
        cout << "read done!!!" << endl;
    }
    return(0);
}

PS:为了让读者一目了然,我将类的定义和函数实现都写在一个cpp中,实际大工程中不建议着吗做!!!

参考文献
1.http://www.opencv.org.cn/opencvdoc/2.3.2/html/doc/tutorials/core/file_input_output_with_xml_yml/file_input_output_with_xml_yml.html#fileinputoutputxmlyaml

你可能感兴趣的:(opencv学习笔记,opencv,图像处理)