简体   繁体   中英

Reading algorithm parameters from file in OpenCV

I am trying to read the parameters of a trained Expectation Maximation model from an XML file for later use. In order to store the model I call

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

this creates the file containing what looks like the data of the model. Here is what the files looks like (first few lines from the start):

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 

Note, that the XML header is missing. Now in order to read the data I am using

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

the cv::Algorithm::read() function has to be called with a filenode as parameter. I am not sure what node to use. Since I would expect there to be only one node in the file I tried

classifier.read(fs[0]);

But the algorithm is not trained afterwards. What do I need to do in order to restore the original parameters?

I simply use

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

It works.

Instead, of using 'write' you can do:

fs<<"my_model"<<classifier;

and then after you open a FileStorage for reading, read it like that:

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

EDIT: The above will not work with cv::EM since it is not included in the overloads.

This link provides a very good example about how you write and read a custom class to/from an XML/YAML file. According to that, you create the "write" and "read" methods for your class, so you are the one who defines and names the nodes.

If you haven't written those methods yourself and they are part of cv::Algorithm (probably this is new, I couldn't find it in 2.2 that I am using) , then I would suggest to check the xml file to see the names of the nodes that were created and then get them either using the >> operator or doing:

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

From the StatModel.EM 1 <_ type_id="opencv-matrix"> that you provide and the xml example in the link, I would guess that this node's name is actually "_" (maybe this is the default if you don't provide any name when you write it)

an alternative syntax is

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM