2012-07-20 169 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; 
    ... 
    } 
相关问题