4

OpenCV 2.4.2 FileStorageを使用していて、ポイントのベクトルのベクトルを読み戻せる方法で保存しようとしています。これを行うための最良の方法は何ですか?

以下は私が試したものですが、それを読み返すとエラーがスローされます: 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>
4

3 に答える 3

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を使用して各vector <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でテスト済み。

これがコードを単純化することを願っています。

于 2014-02-08T06:45:07.030 に答える
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);
}
于 2012-07-23T13:58:46.697 に答える
0


私の場合、これを使用して、opencv2.4.9を使用したbloubloimの回答に基づくベクトルoKeyPointsとMatを読み取りました。

   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;
    ...
    }
于 2014-06-29T06:12:28.483 に答える