OpenCV存储点矢量<vector <point>&gt; </vector <point>的矢量矢量

时间:2012-07-20 17:52:56

标签: opencv vector

我正在使用OpenCV 2.4.2 FileStorage,并尝试以我能读回来的方式存储Points向量的向量。这样做的最佳方法是什么?

以下是我尝试过的但是在读回来时会抛出错误: 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>

3 个答案:

答案 0 :(得分: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读取每个向量&lt; 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进行测试。

希望这可以简化您的代码。

答案 1 :(得分: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);
}

答案 2 :(得分:0)

在我的情况下,我使用这个解决了根据bloublo的答案读取了一个矢量o KeyPoints和一个Mat 我使用的是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;
    ...
    }