【问题标题】:Reading algorithm parameters from file in OpenCV从 OpenCV 文件中读取算法参数
【发布时间】:2013-11-06 00:00:56
【问题描述】:

我正在尝试从 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]);

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

【问题讨论】:

    标签: c++ opencv


    【解决方案1】:

    我只是用

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

    有效。

    【讨论】:

    • 谢谢。不过,我目前没有时间验证这一点。
    • 它确实有效,但有趣的是 fs["StatModel.EM"] 返回一个 null FileNode(指向 0x0),因此您实际上可以将任何字符串放在那里。此外,如果您按照我的预期使用 fs.getFirstTopLevelNode() 获取文件节点,它将不起作用
    【解决方案2】:

    您可以这样做:

    fs<<"my_model"<<classifier;
    

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

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

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

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

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

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

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

    【讨论】:

    • 这给了我一个编译器错误:no matching function for call to ‘write(cv::FileStorage&amp;, std::string&amp;, const cv::EM&amp;)’
    • 你是对的,我刚刚检查过,过载不包括 EM。你自己实现“写”,对吧?
    • 不是,我训练完cv::EM分类器对象的写函数。那么我是否正确理解这一点:调用了cv::Algorithm::write() 函数,因为没有特定于 EM 的实现?
    • 我自己没用过,也找不到更多关于 cv::Algorithm 的信息,但这也是我的理解。您可能可以继承 cv::EM 并按照您想要的方式编写它们,但是在我看来应该有一个更简单的解决方案。您是否知道此 write() 是否接受任何其他参数?另外,你能发布那个xml文件还是太大了?
    • 我现在只是在猜测,但我对这件事真的很好奇。一些事情要尝试: 1. 缺少的标题似乎有点奇怪。在编写模型之前尝试使用 those 参数是否在 XML 文件后面的任何地方提到?它们看起来像合法的节点名称。尝试使用 FileNode myFilenode = fs["nclusters"];分类器.read(myFilenode);例如(好吧,尝试一下也无妨!)。告诉我进展如何
    【解决方案3】:

    另一种语法是

        FileStorage fs(filename, FileStorage::READ);
        Mat mat;
        if (fs.isOpened()) {
            fs["mat_name"]>>mat;
        }
        fs.release();
    

    【讨论】:

      猜你喜欢
      • 2018-07-22
      • 2017-05-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-09
      • 2023-02-04
      • 1970-01-01
      • 2020-08-15
      相关资源
      最近更新 更多