2012-07-20 268 views
4

我正在使用OpenCV 2.4.2 FileStorage,並試圖存儲一個矢量向量的方式,我可以讀回來。什麼是最好的方式做這個?OpenCV存儲矢量向量的點矢量<vector <Point>>

下面是我試過,但讀它放回引發錯誤: OpenCV Error: Unspecified error (The sequence element is not a numerical scalar) in cvReadRawDataSlice, file /Downloads/OpenCV-2.4.2/modules/core/src/persistence.cpp, line 3367

節能:

bool writeVectorVectorPoint(string fname, vector<vector<Point> > vvP) 
{ 
    FileStorage fs(fname, FileStorage::WRITE); 
    fs << "nV" << static_cast<int>(vvP.size()); 
    for(size_t i = 0; i < vvP.size(); i++) 
    { 
    ostringstream istr; 
    istr << "v" << i; 
    fs << istr.str() << "["; 
    for(size_t jj = 0; jj < vvP.at(i).size(); jj++) 
    { 
     ostringstream jjstr; 
     fs << vvP.at(i).at(jj); 
    } 
    fs << "]"; 
    } 
    fs.release(); 
    return(true); 
} 

閱讀:

FileStorage fs(argv[2], FileStorage::READ); 
if(!fs.isOpened()) 
{ 
    cout << "Unable to open: " << argv[2] << endl; 
    return(-1); 
} 
int nV = static_cast<int>(fs["nV"]); 
cout << "nV: " << nV << endl; 
vector<Point> vPts; 
for(int ii = 0; ii < nV; ii++) 
{ 
    ostringstream iistr; 
    iistr << "v" << ii; 
    cout << iistr.str() << ": "; 
    fs[iistr.str()] >> vPts; 
    cout << endl; 
} 
fs.release(); 

的xml文件看起來像:

<?xml version="1.0"?> 
<opencv_storage> 
<nV>4</nV> 
<v0> 
    <_> 
    269 490</_> 
    <_> 
    400 522</_> 
    <_> 
    331 600</_> 
    <_> 
    294 610</_></v0> 
<v1> 
    <_> 
    537 510</_> 
    <_> 
    590 458</_> 
    <_> 
    603 612</_> 
    <_> 
    508 626</_></v1> 
<v2> 
    <_> 
    594 287</_> 
    <_> 
    444 240</_></v2> 
<v3> 
    <_> 
    451 330</_> 
    <_> 
    632 342</_> 
    <_> 
    652 344</_> 
    <_> 
    470 381</_></v3> 
</opencv_storage> 

回答

1

目前,我通過不使用OpenCV的FileStorage解決了這個問題。這是我爲存儲Point矢量的矢量所做的工作,因爲有很好的打印矢量的例程。

bool writeVectorVectorPoint(string fname, vector<vector<Point> > vvP) 
{ 
    ofstream fsOut; 
    vector<vector<Point> >::iterator p; 

    fsOut.open(fname.c_str()); 
    if(fsOut.fail()) 
    { 
    cout << "Failed to open " << fname << endl; 
    return(false); 
    } 
    for(p = vvP.begin(); p != vvP.end(); p++) 
    { 
    fsOut << (*p) << endl; 
    } 
    fsOut.close(); 
    return(true); 
} 

讀回來有點複雜,但仍然不難。如果有人看到任何優化,請讓我知道,因爲我懷疑有更好的(或至少更優雅的)解決方案。

bool readVectorVectorPoint(string fname, vector<vector<Point> >& vvP) 
{ 
    ifstream fsIn; 
    fsIn.open(fname.c_str()); 
    if(fsIn.fail()) 
    { 
    cout << "Failed to open: " << fname << endl; 
    return(false); 
    } 
    Point pt; 
    vector<Point> vPt; 
    vector<Point>::iterator p; 
    string line; 
    while(getline(fsIn, line)) 
    { 
    cout << line << endl; 
    string ptStr; 
    stringstream s(line.substr(1,line.size()-1)); 
    vPt.clear(); 
    while(getline(s, ptStr, ';')) 
    { 
     stringstream s1(ptStr); 
     string lastStr; 
     getline(s1, lastStr, ','); 
     pt.x = atoi(lastStr.c_str()); 
     getline(s1, lastStr, ','); 
     pt.y = atoi(lastStr.c_str()); 
     vPt.push_back(pt); 
    } 
    vvP.push_back(vPt); 
    } 

    fsIn.close(); 
    return(true); 
} 
3

有點晚: 類似的更簡單的例子與載體的載體:

寫入功能,每次添加一個節點使用不同的名稱(只爲信息):

void writeVectorOfVector(FileStorage &fs, string name, vector<vector<Point2f>> &vov) 
{ 
    fs << name; 
    fs << "{"; 
    for (int i = 0; i < vov.size(); i++) 
    { 
     fs << name + "_" + to_string(i); 
     vector<Point2f> tmp = vov[i]; 
     fs << tmp; 
    } 
    fs << "}"; 
} 

閱讀功能,使用FileNodeIterator讀取每個矢量< x>並將其推回到矢量矢量:

void readVectorOfVector(FileNode &fns, string name, vector<vector<Point2f>> &vov) 
{ 
    vov.clear(); 
    FileNode fn = fns[name]; 
    if (fn.empty()){ 
     return; 
    } 

    FileNodeIterator current = fn.begin(), it_end = fn.end(); // Go through the node 
    for (; current != it_end; ++current) 
    { 
     vector<Point2f> tmp; 
     FileNode item = *current; 
     item >> tmp; 
     vov.push_back(tmp); 
    } 
} 

經過OpenCV 2.4.8/C++/Vs2013測試。

希望這可以簡化您的代碼。

+2

的readVectorOfVector函數的第一個參數應該是FileStorage&FS基於bloublo
IM的答案讀矢量o關鍵點和墊,而不是FileNode&fns,對嗎?然後讀取節點將是:FileNode fn = fs [name]; – 2015-06-22 17:42:52

0
在我的情況下,我用這個

解決使用OpenCV的2.4.9

FileNodeIterator current = fn.begin(), it_end = fn.end(); // Go through the node 
    for (; current != it_end; ++current) 
    { 
    vector<KeyPoint> kp; 
    Mat desc; 
    FileNode item = *current; 
    read(item,kp); 

    ++current; 
    item = *current; 
    item >> desc; 
    ... 
    } 
相關問題