自定义类重载运算符<< >>,并用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;  
则这一部分的数据将为


  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
### 回答1: 在 C++ 中使用 OpenCV 读取 txt 文件并将其解析为 vector<string> 格式可以使用以下代码: ``` #include <opencv2/opencv.hpp> #include <vector> #include <string> using namespace std; int main() { string filename = "example.txt"; vector<string> data; ifstream file(filename); if(file.is_open()) { string line; while(getline(file, line)) { data.push_back(line); } file.close(); } return 0; } ``` 在这段代码中,我们首先声明了一个文件名变量,一个 vector 变量 data 和一个 ifstream 变量 file。然后我们使用 ifstream 类的构造函数打开文件,并使用 is_open() 函数判断文件是否正常打开。如果文件打开成功,我们使用 getline() 函数逐行读取文件的内容并将每行的内容插入到 vector 变量 data 中。最后,我们关闭文件。 ### 回答2: 在C中通过OpenCV读取txt文件,并将其解析为vector<string>格式的步骤如下: 1. 导入必要的头文件: ```c++ #include <iostream> #include <fstream> #include <vector> #include <opencv2/opencv.hpp> ``` 2. 创建一个函数来读取txt文件并解析为vector<string>格式: ```c++ std::vector<std::string> readTXTFile(const std::string& filename) { std::vector<std::string> lines; std::ifstream file(filename); if (file.is_open()) { std::string line; while (std::getline(file, line)) { lines.push_back(line); } file.close(); } else { std::cout << "Error opening file: " << filename << std::endl; } return lines; } ``` 3. 使用OpenCV中的 imread 函数读取txt文件: ```c++ std::string filename = "data.txt"; // txt文件名 cv::Mat image = cv::imread(filename, cv::IMREAD_GRAYSCALE); ``` 4. 将读取的图像数据解析为vector<string>格式: ```c++ std::vector<std::string> lines; for (int i = 0; i < image.rows; i++) { std::string line; for (int j = 0; j < image.cols; j++) { int pixel_value = static_cast<int>(image.at<uchar>(i, j)); line += std::to_string(pixel_value) + " "; } lines.push_back(line); } ``` 5. 打印解析后的数据: ```c++ for (const auto& line : lines) { std::cout << line << std::endl; } ``` 以上是通过OpenCV在C中读取txt文件并将其解析为vector<string>格式的步骤。 ### 回答3: 在C++中利用OpenCV读取txt文件并解析为vector<string>格式可以通过以下步骤实现: 1. 首先,需要包含OpenCV的头文件和iostream头文件: ```c++ #include <opencv2/opencv.hpp> #include <iostream> ``` 2. 接下来,创建一个函数来读取txt文件并解析为vector<string>格式,函数原型如下: ```c++ std::vector<std::string> readTxtFile(const std::string& filename); ``` 3. 在函数中,首先定义一个存储解析后字符串的vector<string>,例如: ```c++ std::vector<std::string> strVector; ``` 4. 使用OpenCV的FileStorage类来读取txt文件: ```c++ cv::FileStorage fs(filename, cv::FileStorage::READ); if (!fs.isOpened()) { std::cerr << "Failed to open txt file." << std::endl; return strVector; } ``` 5. 利用OpenCV的FileNode和FileNodeIterator对文件进行解析: ```c++ cv::FileNode rootNode = fs["data"]; if (rootNode.empty()) { std::cerr << "Empty data node." << std::endl; return strVector; } cv::FileNodeIterator it = rootNode.begin(); cv::FileNodeIterator it_end = rootNode.end(); for (; it != it_end; ++it) { std::string str = (std::string)*it; strVector.push_back(str); } ``` 6. 最后,返回解析后的字符串向量: ```c++ return strVector; ``` 以下是完整的示例代码: ```c++ #include <opencv2/opencv.hpp> #include <iostream> std::vector<std::string> readTxtFile(const std::string& filename) { std::vector<std::string> strVector; cv::FileStorage fs(filename, cv::FileStorage::READ); if (!fs.isOpened()) { std::cerr << "Failed to open txt file." << std::endl; return strVector; } cv::FileNode rootNode = fs["data"]; if (rootNode.empty()) { std::cerr << "Empty data node." << std::endl; return strVector; } cv::FileNodeIterator it = rootNode.begin(); cv::FileNodeIterator it_end = rootNode.end(); for (; it != it_end; ++it) { std::string str = (std::string)*it; strVector.push_back(str); } return strVector; } int main() { std::vector<std::string> strVector = readTxtFile("data.txt"); for (const auto& str : strVector) { std::cout << str << std::endl; } return 0; } ``` 这样,就可以通过OpenCV读取txt文件并解析为vector<string>格式。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值