自定义类重载运算符<< >>,并用FileStorage保存和读取xml文件

OpenCV在2.0以后的版本中提供了FileStorage类,供用户将数据保存为xml或者YAML文件。本文的内容就是介绍如何自定义类,而后重载<< 和 >> 运算符,并通过FileStorage保存和读取xml文件。

自定义一个数据类,想要保存的数据为一张图像,以及std::vector<cv::Point>和std::vector<std::vector<cv::Point> > 两类点集。

自定义类的头文件mydata.h

#pragma once
#include <core/mat.hpp>
#include <ostream>
#include <core/persistence.hpp>

class MyData
{
public:
	MyData();
	~MyData();

	void setImage(cv::Mat image);
	void setSingleRect(std::vector<cv::Point> singleRect);
	void setMultiRect(std::vector<std::vector<cv::Point> > multiRect);

	cv::Mat getImage();
	std::vector<cv::Point> getSingleRect();
	std::vector<std::vector<cv::Point> > getMultiRect();

	friend cv::FileStorage& operator<<(cv::FileStorage& fs, MyData& obj);
	friend MyData& operator>>(cv::FileStorage& fs, MyData& obj);


private:
	cv::Mat image;
	std::vector<cv::Point> singleRect;
	std::vector<std::vector<cv::Point> > 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<cv::Point> singleRect)  
{  
    this->singleRect = singleRect;  
}  
  
void MyData::setMultiRect(std::vector<std::vector<cv::Point>> multiRect)  
{  
    this->multiRect = multiRect;  
}  
  
cv::Mat MyData::getImage()  
{  
    return this->image;  
}  
  
std::vector<cv::Point> MyData::getSingleRect()  
{  
    return this->singleRect;  
}  
  
std::vector<std::vector<cv::Point>> 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<cv::Point> 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<cv::Point> singleRect = {cv::Point(1, 1), cv::Point(2, 2)}; // 构造一个矩形的两个顶点点集  
    myDataWrite.setSingleRect(singleRect);  
    std::vector<std::vector<cv::Point> > 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;  
则这一部分的数据将为


猜你喜欢

转载自blog.csdn.net/MengchiCMC/article/details/79006568