How to read vector <vector <Point3f>> from xml file with file storage

I was wondering if it is possible to load a Point2f vector vector from an xml file using the cv :: FileStorage class.

This is what I tried to save:

filestorage  << "ObjPoints" << "{";
for (int i = 0; i < objPoints.size(); ++i)
{
    Mat outMat(objPoints[i]);
    filestorage << "ObjPoints_" + IntToString(i) << outMat;
}
filestorage << "}";

And this is for download:

FileNode k = n["ObjPoints"];
int i = 0;
for (FileNodeIterator it = k.begin(); it!=k.end(); ++it)
{
    Mat inMat;
    k["ObjPoints_" + IntToString(i)] >> inMat;
    vector<Point3f> tmp = Mat_<Point3f>(inMat);
    ++i;
    objPoints.push_back(tmp);
}

Where objPoints is the vector <vector <Point3f → and IntToString is defined as follows:

string IntToString(int number)
{
  stringstream ss;
  ss << number;
  return ss.str();
}

Can someone point me in the right direction? Thanks.

+4
source share
1 answer

You can use FileNodeiterate over each vector and at each point. This is easier to show than to explain:

#include <opencv2\opencv.hpp>
#include <vector>
using namespace cv;
using namespace std;

int main(){

    {
        // Write

        vector<vector<Point3f>> v{
            { { 1, 0, 0 }, { 1, 0, 1 }, { 1, 0, 2 } },
            { { 2, 0, 0 } },
            { { 3, 0, 0 }, { 3, 0, 1 } },
        };


        FileStorage fs("test.xml", FileStorage::WRITE);
        fs << "data" << "[";
        for (int i = 0; i < v.size(); ++i)
        {
            // Write each vector
            fs << "[:";
            for (int j = 0; j < v[i].size(); ++j)
            {
                // Write each point
                fs << "[:" << v[i][j].x << v[i][j].y << v[i][j].z << "]";  // Or use: fs << v[i][j];
            }
            fs << "]"; // close vector
        }
        fs << "]"; // close data
    }


    // Read

    vector<vector<Point3f>> v;

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

    FileNode data = fs["data"];
    for (FileNodeIterator itData = data.begin(); itData != data.end(); ++itData)
    {
        // Read each vector
        vector<Point3f> vv;

        FileNode pts = *itData;
        for (FileNodeIterator itPts = pts.begin(); itPts != pts.end(); ++itPts)
        {
            // Read each point
            FileNode pt = *itPts;

            Point3f point;
            FileNodeIterator itPt = pt.begin();
            point.x = *itPt; ++itPt;
            point.y = *itPt; ++itPt;
            point.z = *itPt;

            vv.push_back(point);
        }
        v.push_back(vv);
    }

    return 0;
}

Your XML will look like this:

<?xml version="1.0"?>
<opencv_storage>
<data>
  <_><_>
      1. 0. 0.</_>
    <_>
      1. 0. 1.</_>
    <_>
      1. 0. 2.</_></_>
  <_><_>
      2. 0. 0.</_></_>
  <_><_>
      3. 0. 0.</_>
    <_>
      3. 0. 1.</_></_></data>
</opencv_storage>

Or in YAML, for example:

%YAML:1.0
data:
   - [ [ 1., 0., 0. ], [ 1., 0., 1. ], [ 1., 0., 2. ] ]
   - [ [ 2., 0., 0. ] ]
   - [ [ 3., 0., 0. ], [ 3., 0., 1. ] ]
+1
source

Source: https://habr.com/ru/post/1620998/


All Articles