OpenCV在2.0以后的版本中提供了FileStorage类,供用户将数据保存为xml或者YAML文件。本文的内容就是介绍如何自定义类,而后重载<< 和 >> 运算符,并通过FileStorage保存和读取xml文件。
自定义一个数据类,想要保存的数据为一张图像,以及std::vector
自定义类的头文件mydata.h
#pragma once
#include
#include
#include
class MyData
{
public:
MyData();
~MyData();
void setImage(cv::Mat image);
void setSingleRect(std::vector singleRect);
void setMultiRect(std::vector > multiRect);
cv::Mat getImage();
std::vector getSingleRect();
std::vector > getMultiRect();
friend cv::FileStorage& operator<<(cv::FileStorage& fs, MyData& obj);
friend MyData& operator>>(cv::FileStorage& fs, MyData& obj);
private:
cv::Mat image;
std::vector singleRect;
std::vector > multiRect;
};
自定义类的源文件mydata.c
#include "MyData.h"
MyData::MyData()
{
}
MyData::~MyData()
{
}
void MyData::setImage(cv::Mat image)
{
image.copyTo(this->image);
}
void MyData::setSingleRect(std::vector singleRect)
{
this->singleRect = singleRect;
}
void MyData::setMultiRect(std::vector> multiRect)
{
this->multiRect = multiRect;
}
cv::Mat MyData::getImage()
{
return this->image;
}
std::vector MyData::getSingleRect()
{
return this->singleRect;
}
std::vector> MyData::getMultiRect()
{
return this->multiRect;
}
cv::FileStorage& operator<<(cv::FileStorage& fs, MyData& obj)
{
fs << "image" << obj.image;
fs << "singleRect" << obj.singleRect;
// 注意singleRect与multiRect存放时的不同
fs << "multiRect" << "{";
for (int i = 0; i < obj.multiRect.size(); i++)
{
fs << "multiRect_" + std::to_string(i) << obj.multiRect[i];
}
fs << "}";
return fs;
}
MyData& operator>>(cv::FileStorage& fs, MyData& obj)
{
fs["image"] >> obj.image;
fs["singleRect"] >> obj.singleRect;
cv::FileNode fn = fs["multiRect"];
for (auto nodeItor = fn.begin(); nodeItor != fn.end(); ++nodeItor)
{
std::vector pts;
*nodeItor >> pts;
obj.multiRect.push_back(pts);
}
return obj;
}
主程序:
#include "mydata.h"
int main()
{
MyData myDataWrite;
myDataWrite.setImage(cv::Mat(3, 3, CV_8UC3, cv::Scalar(0, 255, 255))); // 构造图像存入数据类
std::vector singleRect = {cv::Point(1, 1), cv::Point(2, 2)}; // 构造一个矩形的两个顶点点集
myDataWrite.setSingleRect(singleRect);
std::vector > multiRect = {singleRect, singleRect, singleRect}; // 保存两个矩形的点集
myDataWrite.setMultiRect(multiRect);
// 将数据保存至xml文件
cv::FileStorage fsWrite("mydata.xml", cv::FileStorage::WRITE);
fsWrite << myDataWrite;
fsWrite.release();
// 从xml文件中读取数据
MyData myDataRead;
cv::FileStorage fsRead("mydata.xml", cv::FileStorage::READ);
fsRead >> myDataRead;
fsRead.release();
std::cout << myDataRead.getSingleRect().size() << std::endl;
std::cout << myDataRead.getMultiRect().size() << std::endl;
return 0;
}
保存的xml文件内容如下图
注意singleRect与multiRect存放时的不同,如果用相同的方式存储即:
fs << "multiRect" << obj.multiRect;
则这一部分的数据将为