(三)2.0版本对之前版本的进行了哪些修改

2.0版本对之前的OpenCV数据结构进行了大幅度的修改。但对之前版本的兼容是一个很重要的事情。

这节就主要讨论这个问题
首先来看一下2.0版本对之前版本的进行了哪些修改
1.采用了新的数据结构Mat作为图像的容器,取代了之前的CvMat和lplImage,这个改动不是太复杂,只需适应一下新东西,而且可以自由转换

view plain
Mat I;  
IplImage pI = I;  
CvMat mI = I;  

对于指针的操作要相对复杂一些,而且还要注意内存的释放,我这里不推荐用老版本的数据结构,例如:
view plain
Mat I;  
IplImage* pI = &I.operator IplImage();  
CvMat* mI = &I.operator CvMat();  

2.对library进行了重组,将原来的一个大库根据功能结构分成具体小库,这样包含头文件的时候只需要加入你需要的库,只是原来库的子集
3.使用了cv 这个namespace来防止和其他的library 结构冲突。所以在使用的时候也要预先加上cv::关键字,这也是新版本的函数,数据都省略了cv前缀的原因,一般放在include之后,格式为:
view plain
using namespace cv; // The new C++ interface API is inside this namespace. Import it.  

1. XML、YAML文件的打开和关闭
XML\YAML文件在OpenCV中的数据结构为FileStorage,打开操作例如:



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

文件关闭操作会在FileStorage结构销毁时自动进行,但也可调用如下函数实现
view plain
fs.release();  

2.文本和数字的输入和输出

写入文件使用  <<  运算符,例如:

view plain
fs << "iterationNr" << 100;  

读取文件,使用 >> 运算符,例如
view plain
int itNr;  
fs["iterationNr"] >> itNr;  
itNr = (int) fs["iterationNr"];  

3. OpenCV数据结构的输入和输出,和基本的C++形式相同
view plain
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;  

4. vector(arrays) 和 maps的输入和输出
vector要注意在第一个元素前加上“[”,在最后一个元素前加上"]"。例如:

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

对于map结构的操作使用的符号是"{"和"}",例如:
view plain
fs << "Mapping"; // text - mapping  
fs << "{" << "One" << 1;  
fs << "Two" << 2 << "}";  

读取这些结构的时候,会用到FileNode和FileNodeIterator数据结构。对FileStorage类的[]操作符会返回FileNode数据类型,对于一连串的node,可以使用FileNodeIterator结构,例如:
view plain
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;  

5. 读写自己的数据结构
这部分比较复杂,参考最后的实例中的MyData结构自己领悟吧

最后,我这里上一个实例,供大家参考。
源文件里填入如下代码:
view plain
#include <opencv2/core/core.hpp>  
#include <iostream>  
#include <string>  
  
using namespace cv;  
using namespace std;  
  
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  
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);  
}  
  
// This function will print our custom class to the console  
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;  
}  


编译后,在命令行进入到文件目录,执行test test.xml,运行结果如下,生成一个test . xml文件,内容如下:
view plain
  <?xml version="1.0" ?>  
- <opencv_storage>  
  <iterationNr>100</iterationNr>  
  <strings>image1.jpg Awesomeness baboon.jpg</strings>  
- <Mapping>  
  <One>1</One>  
  <Two>2</Two>  
  </Mapping>  
- <R type_id="opencv-matrix">  
  <rows>3</rows>  
  <cols>3</cols>  
  <dt>u</dt>  
  <data>1 0 0 0 1 0 0 0 1</data>  
  </R>  
- <T type_id="opencv-matrix">  
  <rows>3</rows>  
  <cols>1</cols>  
  <dt>d</dt>  
  <data>0. 0. 0.</data>  
  </T>  
- <MyData>  
  <A>97</A>  
  <X>3.1415926535897931e+000</X>  
  <id>mydata1234</id>  
  </MyData>  
  </opencv_storage>  


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值