Reputation: 278
I was wondering if it was possible to load a vector of vector of Point2f from an xml file, using the cv::FileStorage class.
This is what I tried for saving:
filestorage << "ObjPoints" << "{";
for (int i = 0; i < objPoints.size(); ++i)
{
Mat outMat(objPoints[i]);
filestorage << "ObjPoints_" + IntToString(i) << outMat;
}
filestorage << "}";
And this is for loading:
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 a vector< vector< Point3f > > and IntToString is defined as follow:
string IntToString(int number)
{
stringstream ss;
ss << number;
return ss.str();
}
Can anyone point me in the right direction? Thanks.
Upvotes: 3
Views: 2420
Reputation: 41775
You can use FileNode
s to iterate over each vector, and over each point. It's 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:
<?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 like:
%YAML:1.0
data:
- [ [ 1., 0., 0. ], [ 1., 0., 1. ], [ 1., 0., 2. ] ]
- [ [ 2., 0., 0. ] ]
- [ [ 3., 0., 0. ], [ 3., 0., 1. ] ]
Upvotes: 1