Ask Your Question
0

How to save/load matrix and parameters of several algorithms to a file?

asked 2013-04-10 10:35:37 -0600

wl2776 gravatar image

Hi all. I've got a matrix cv::Mat, keypoint detector and descriptor extractor objects. And I want to save all of them to the single file using cv::FileStorage. Is it possible?

I tried

Mat matrix;
FeatureDetector detector;
DescriptorExtractor extractor;

/* fill matrix, detector and extractor*/

FileStorage fs(file_name, FileStorage::WRITE);
fs << "matrix" << matrix;
detector.write(fs);
extractor.write(fs);

This code writes everything to the file.

But the resulting file is invalid, since it contains two pairs of <name> </name> tags, and the code, reading data from disk, throws the exception "Duplicated key".

Here is the example of what I've got

<opencv_storage>
<name>Feature2D.ORB</name>
<WTA_K>2</WTA_K>
....  (other saved ORB parameters are skipped for brevity)
<name>Feature2D.BRISK</name>
<octaves>3</octaves>
<thres>30</thres>
<matrix type_id="opencv-matrix">
   <rows>500</rows>
   <cols>64</cols>
   <dt>u</dt>
   <data>
1 96 0 0 140 191 127 60 28 0 0 0 72 240 249 79 55 8 32 128 99 28 199
48 28 31 12 24 192 128 0 102 24 115 254 255 255 157 113 134 25 34 0
0 0 24 134 96 182 255 255 255 163 64 254 255 219 4 2 0 0 0 96 196 3
...

One possible solution could be wrapping the detector and extractor with custom tags, like

<opencv_storage>
<detector>
<name>Feature2D.ORB</name>
<WTA_K>2</WTA_K>
....
</detector>
<extractor>
<name>Feature2D.BRISK</name>
<octaves>3</octaves>
<thres>30</thres>
</extractor>
... (the rest of file)

Is it possible with FileStorage? I tried

fs << "detector";
detector.write(fs);

However, this code throws the exception "no element was given".

edit retag flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted
1

answered 2013-04-11 07:46:59 -0600

wl2776 gravatar image

updated 2013-04-15 02:24:33 -0600

I've found the solution. Old C functions cvStartWriteStruct and cvEndWriteStruct can do the job.

#include <opencv2/core/core_c.h>
...
Mat matrix;
FeatureDetector detector;
DescriptorExtractor extractor;

/* fill matrix, detector and extractor*/

FileStorage fs(file_name, FileStorage::WRITE);
cvStartWriteStruct(*fs, "detector", CV_NODE_MAP);
detector.write(fs);
cvEndWriteStruct(*fs);
fs << "matrix" << matrix;

This produces the following.

<opencv_storage>
<detector>
<name>Feature2D.ORB</name>
<WTA_K>2</WTA_K>
....
<scoreType>0</scoreType></detector>
<matrix type_id="opencv-matrix">
<rows>500</rows>
<cols>64</cols>
<dt>u</dt>
<data>
  1 96 0 0 140 191 127 60 28 0 0 0 72 240 249 79 55 8 32 128 99 28 199
  ...

The reading code then would become

FileNode fn = fs["detector"];
if (!fn.empty()) {
    string name = fn["name"];
    ORB det;
    det.read(fn);
}

UPDATE. C++ API can also do this. Same result can be achieved with

fs << "detector" << "{";
detector.write(fs);
fs << "}";
edit flag offensive delete link more

Comments

It is not good that people should return to C - style API just to be able to do this. Could you post this as a bug report? (http://code.opencv.org/projects/opencv/issues?set_filter=1) It would help put the focus on the problem. Be so kind to add your C-code to the report to make the problem more clear. Thx in advance.

StevenPuttemans gravatar imageStevenPuttemans ( 2013-04-11 08:27:09 -0600 )edit
2

After some experiments, I've found that C++ API can also do this. I've corrected my answer

wl2776 gravatar imagewl2776 ( 2013-04-12 02:04:12 -0600 )edit

Perfectly :) Good to know that this is way more easier in the C++ API. Again a reason to stick to the newer interface.

StevenPuttemans gravatar imageStevenPuttemans ( 2013-04-12 02:29:17 -0600 )edit

Question Tools

Stats

Asked: 2013-04-10 10:35:37 -0600

Seen: 1,305 times

Last updated: Apr 15 '13