2

我正在尝试从 XML 文件中读取经过训练的期望最大化模型的参数以供以后使用。为了存储我调用的模型

cv::FileStorage fs("model.xml",cv::FileStorage::WRITE);
classifier.write(fs);  //classifier is of type cv::EM

这将创建包含看起来像模型数据的文件。这是文件的样子(从一开始的前几行):

StatModel.EM 1
<_ type_id="opencv-matrix"> 3 3 d
1.2159868951764311e+01 0. 0. 0. 1.9776824566023249e-01 0. 0. 0.  .2204460492503131e-16     
<_ type_id="opencv-matrix"> 3 3 d
3.2869203526862529e+00 0. 0. 0. 1.1631692248472096e+00 0. 0. 0. 2.2204460492503131e-16     
<_ type_id="opencv-matrix"> 3 3 d
2.9815870012055705e+00 0. 0. 0. 6.5049770685681069e+03 0. 0. 0. 6.8510191786605528e+03 
<_ type_id="opencv-matrix"> 3 3 d 
4.6608996548002040e+00 0. 0. 0. 3.7558131457318683e+02 0. 0. 0. 2.2204460492503131e-16 

请注意,缺少 XML 标头。现在为了读取我正在使用的数据

cv::FileStorage fs("model.xml",cv::FileStorage::READ);

cv::Algorithm::read() 函数必须以文件节点作为参数调用。我不确定要使用哪个节点。因为我希望我尝试的文件中只有一个节点

classifier.read(fs[0]);

但是该算法之后没有训练。我需要做什么才能恢复原始参数?

4

3 回答 3

4

我只是使用

        const FileStorage fs(filename, FileStorage::READ);
        EM model;
        if (fs.isOpened()) {
            const FileNode& fn = fs["StatModel.EM"];
            model.read(fn);
        } 

有用。

于 2012-11-26T11:32:04.427 回答
3

相反,您可以不使用“写”:

fs<<"my_model"<<classifier;

然后在打开 FileStorage 进行阅读后,像这样阅读它:

cv::EM EModel;
fs["my_model"] >> EModel;

编辑:以上不适用于 cv::EM 因为它不包含在重载中。

链接提供了一个很好的示例,说明如何在 XML/YAML 文件中编写和读取自定义类。据此,您为您的类创建“写入”和“读取”方法,因此您是定义和命名节点的人。

如果您自己没有编写这些方法并且它们是 cv::Algorithm 的一部分(可能这是新的,我在使用的 2.2 中找不到它),那么我建议检查 xml 文件以查看创建的节点的名称,然后使用 >> 运算符或执行以下操作获取它们:

FileNode myFilenode = fs["node_name"];
classifier.read(myFilenode);

根据StatModel.EM 1 <_ type_id="opencv-matrix">您提供的内容和链接中的 xml 示例,我猜这个节点的名称实际上是“_”(如果您在编写时没有提供任何名称,这可能是默认值)

于 2012-09-06T19:23:16.333 回答
1

另一种语法是

    FileStorage fs(filename, FileStorage::READ);
    Mat mat;
    if (fs.isOpened()) {
        fs["mat_name"]>>mat;
    }
    fs.release();
于 2013-07-05T18:45:49.743 回答