OpenCV FileStorage類讀寫XML/YML文件


        在OpenCV程序中,需要保存中間結果的時候常常會使用.xml / .yml文件,opencv2.0之前都是使用C風格的代碼,當時讀寫XML文件分別使用函數cvLoad()和cvSave()。在2.0以后的OpenCV轉為支持C++,這一舉措大大減少了代碼量以及編程時需要考慮的細節。

        新版本的OpenCV的C++接口中,imwrite()和imread()只能保存整數數據,且需要以圖像格式。當需要保存浮點數據或者XML/YML文件時,之前的C語言接口cvSave()函數已經在C++接口中被刪除,代替它的是FileStorage類。這個類非常的方便,封裝了很多數據結構的細節,編程的時候可以根據統一的接口對數據結構進行保存。

    1. FileStorage類寫XML/YML文件

         •   新建一個FileStorage對象,以FileStorage::WRITE的方式打開一個文件。

         •   使用 << 操作對該文件進行操作。

         •   釋放該對象,對文件進行關閉。

        例子如下:

    FileStorage fs("test.yml", FileStorage::WRITE);
    fs << "frameCount" << 5;
    time_t rawtime; time(&rawtime);
    fs << "calibrationDate" << asctime(localtime(&rawtime));
    Mat cameraMatrix = (Mat_<double>(3,3) << 1000, 0, 320, 0, 1000, 240, 0, 0, 1); //又一種Mat初始化方式
    Mat distCoeffs = (Mat_<double>(5,1) << 0.1, 0.01, -0.001, 0, 0);
    fs << "cameraMatrix" << cameraMatrix << "distCoeffs" << distCoeffs;
    
    //features為一個大小為3的向量,其中每個元素由隨機數x,y和大小為8的uchar數組組成
    fs << "features" << "[";
    for( int i = 0; i < 3; i++ )
    {
        int x = rand() % 640;
        int y = rand() % 480;
        uchar lbp = rand() % 256;
        fs << "{:" << "x" << x << "y" << y << "lbp" << "[:";
        for( int j = 0; j < 8; j++ )
            fs << ((lbp >> j) & 1);
        fs << "]" << "}";
    }
    fs << "]";
    fs.release();

         

    2. FileStorage類讀XML/YML文件

       FileStorage對存儲內容在內存中是以層次的節點組成的,每個節點類型為FileNode,FileNode可以使單個的數值、數組或者一系列FileNode的集合。FileNode又可以看做是一個容器,使用iterator接口可以對該節點內更小單位的內容進行訪問,例如訪問到上面存儲的文件中"features"的內容。步驟與寫文件類似:

         •   新建FileStorage對象,以FileStorage::READ 方式打開一個已經存在的文件

         •   使用FileStorage::operator []()函數對文件進行讀取,或者使用FileNode和FileNodeIterator

         •   使用FileStorage::release()對文件進行關閉

         例子如下:

    FileStorage fs("test.yml", FileStorage::READ);

    //方式一: []操作符
    int frameCount = (int)fs["frameCount"];
    
    //方式二: FileNode::operator >>()
    string date;
    fs["calibrationDate"] >> date;
    
    Mat cameraMatrix2, distCoeffs2;
    fs["cameraMatrix"] >> cameraMatrix2;
    fs["distCoeffs"] >> distCoeffs2;
    
    //注意FileNodeIterator的使用,似乎只能用一維數組去讀取里面所有的數據
    FileNode features = fs["features"];
    FileNodeIterator it = features.begin(), it_end = features.end();
    int idx = 0;
    std::vector<uchar> lbpval;
    for( ; it != it_end; ++it, idx++ )
    {
        cout << "feature #" << idx << ": ";
        cout << "x=" << (int)(*it)["x"] << ", y=" << (int)(*it)["y"] << ", lbp: (";
        (*it)["lbp"] >> lbpval;  //直接讀出一維向量

        for( int i = 0; i < (int)lbpval.size(); i++ )
            cout << " " << (int)lbpval[i];
        cout << ")" << endl;
    }
    fs.release();

        另外,注意在新建FileStorage對象之后,並以READ或WRITE模式打開文件之后,可以用FileStorage::isOpened()查看文件狀態,判斷是否成功打開了文件。

        

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM