OpenCV保存成XML(FileStorage)和CSV(重载

XML文件(使用FileStorage类)

使用OpenCV时不仅要保存影像结果,往往也需要保存中间的矩阵结果,而OpenCV的imwrite函数只支持CV8U类型的数据(使用OpenCV保存其他类型Mat的时候,程序不会报错,但是无法生成结果文件),因此会给工作带来很多不便。OpenCV在2.0以后的版本中提供了FileStorage类,供用户直接使用,保存为XML/YAML文件。

保存XML

保存示例如下:

Mat mat = Mat::eye(Size(12,12), CV_8UC1);
FileStorage fs("f:\\vocabulary.xml", FileStorage::WRITE);
fs << "vocabulary" << mat;
fs.release();

得到结果文件如下所示:


<opencv_storage>
<vocabulary type_id="opencv-matrix">
  <rows>12rows>
  <cols>12cols>
  <dt>udt>
  <data>
    1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0
    0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0
    0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0
    0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0
    0 0 0 0 0 0 0 1data>vocabulary>
opencv_storage>

需要注意的是,因为保存的结果为xml文件,所以再保存的时候需要给定标签,格式就是下面的形式,先存储标签内容,再存储矩阵:

fs << "vocabulary" << mat;

读取XML

同样使用FileStorage类可以直接获取保存的xml文件内容。
读取示例如下:

FileStorage fs(".\\vocabulary.xml", FileStorage::READ);
Mat mat_vocabulary;
fs["vocabulary"] >> mat_vocabulary;

读取文件的时候同样要给定标签内容,这里通过中括号[]给定:

fs["vocabulary"] >> mat_vocabulary;

CSV文件

很多时候,直接使用CSV文件相比XML更方便,使用XML保存得到的数据,无论是查看(excel查看,XML中矩阵不是格式化的)还是接着使用别的工具处理(例如matlab),都可以快速的读取,而XML需要解析则比较繁琐。那么该如何保存CSV文件呢,对保存的CSV文件又应该如何读取呢,请看下文分解。

保存CSV文件

OpenCV提供了结果保存的格式化函数format,使用format我们就可以根据自己想要的格式打印和保存数据了。

先直接看保存函数,再来分析具体含义吧:

ofstream file("test.csv");
file << format(mat, Formatter::FMT_CSV);
file.close();

根据上面的代码只用ofstream对象打开要写入的csv文件,再直接写入数据即可,需要注意的是,接入的矩阵用format格式化,format函数第二个参数表示格式类型,这里选择CSV格式即Formatter::FMT_CSV

保存结果如图所示:
OpenCV保存成XML(FileStorage)和CSV(重载_第1张图片

这里保存格式为定义在Formatter类中的枚举类型,总共有6中选项,各位读者可以根据自己的需求选择。

class CV_EXPORTS Formatter
{
public:
    enum { FMT_DEFAULT = 0,
           FMT_MATLAB  = 1,
           FMT_CSV     = 2,
           FMT_PYTHON  = 3,
           FMT_NUMPY   = 4,
           FMT_C       = 5
         };

    virtual ~Formatter();

    virtual Ptr format(const Mat& mtx) const = 0;

    virtual void set32fPrecision(int p = 8) = 0;
    virtual void set64fPrecision(int p = 16) = 0;
    virtual void setMultiline(bool ml = true) = 0;

    static Ptr get(int fmt = FMT_DEFAULT);

};

读取CSV数据

在保存为CSV格式后该如何读取呢,这里可以使用OpenCV中ml模块的TrainData类的函数读取。具体代码如下所示,第二行为加载数据,参数0表示没有标题行,第三行获取得到的数据。

Ptr<TrainData> train_data;
train_data = TrainData::loadFromCSV("test.csv", 0); 
Mat m = train_data->getTrainSamples();
cout << format(m, Formatter::FMT_CSV) << endl;

代码运行结果为:
OpenCV保存成XML(FileStorage)和CSV(重载_第2张图片

参考链接:
1. OpenCV使用FileStorage保存Mat数据
2. XML/YAML file storages. Writing to a file storage.

你可能感兴趣的:(C++)