Ask Your Question
0

cv::Algorithm read/write in API 3?

asked 2019-11-01 04:42:34 -0600

JoseAFern gravatar image

Hi

I am using cv::ml::RTrees to train a Random Forest model and predict some values. I'd like to store the final trained model in some custom structure and also to write ToString and FromString methods. I have seen that API version 2 has read/write methods and a FileStorage structure which would help to read/write from string but I have read that these are deprecated in API 3. Is this true? And if so, are there any alternative methods provided to replace those (save/load are not valid answers here, as these store and read from file which I don't want to do)? Also, does OpenCV provide any class or set of classes to access the final trained model (e.g. trees, nodes, values) so that I can safely store the model in code without any need to train again?

Thanks in advance for your help.

edit retag flag offensive close merge delete

Comments

but I have read that these are deprecated in API 3. Is this true?

where did you find it ?

berak gravatar imageberak ( 2019-11-01 05:23:43 -0600 )edit

what you want is for sure possible (at least with current 4.x),

FileStorage can be initialized from a string in memory, and you can read() from a FileStorage, but you have to solve that problem:

-- how to properly embed an xml string into a c++ program.

berak gravatar imageberak ( 2019-11-01 05:28:18 -0600 )edit
1

Thanks for the reply.

I saw it in "Learning OpenCV 3: Computer Vision in C++ with the OpenCV Library", by Adrian Kaehler and Gary Bradski, page 801, footnote 2 (in the context of cv::Algorithm): "In the distant past, there were two pairs of functions for reading and writing: save()/load() and write()/read(), with the latter pair being lower-level functions that interacted with the now legacy CvFileStorage file interface structure. That pair should now be considered deprecated, along with the structure they once accessed, and the only interface that should be used in modern code is the save()/load() interface".

From this I understood that read() and write() were now deprecated but I understand from your answer they are not?

Any idea about my final question?

JoseAFern gravatar imageJoseAFern ( 2019-11-01 05:39:06 -0600 )edit

^^ if i read that sentence a few times, it seems to say: prefer the high level load/save functions, to the low level read/write methods ?

berak gravatar imageberak ( 2019-11-01 06:59:37 -0600 )edit

the now legacy CvFileStorage

indeed. it was entirely replaced from scratch with cv::FileStorage

berak gravatar imageberak ( 2019-11-01 11:26:19 -0600 )edit

1 answer

Sort by ยป oldest newest most voted
0

answered 2019-11-01 06:50:02 -0600

berak gravatar image

updated 2019-11-01 06:52:51 -0600

i can't tell about the deprecation status, with current 4.1 it seems to be still the same: Algorithm::load/save handles the FileStorage, and e.g. RTrees::read/write handle the data inside it.

given you have your xml data inside a std::string xml you can initialize a FileStorage from that memory, and read the tree data:

std::string xml; // "<?xml version="1.0"?>\n<opencv_storage>\n<opencv_ml_rtrees>\n ......"
FileStorage fs(xml, FileStorage::MEMORY|FileStorage::READ);

Ptr<ml::RTrees> another_tree = ml::RTrees::create();
another_tree->read(fs.getFirstTopLevelNode());
//cout << another_tree->isTrained() << " " << another_tree->getVarCount() << endl;

the next problem is, you have to get somehow creative, to get the xml content into something you can save (and compile !) as code, maybe you need to hexencode it:

char bytes[] = {
     0x36, 0x44,0x45,0x33,.....
};
string xml = string(bytes);

so, workflow would be:

  • train your model, save() to xml on disc.
  • write a program, that reads xml and writes c code, like the char[] above
  • embed the generated c code into your classification program, and use the code above to load the model.
edit flag offensive delete link more

Comments

Thanks for the reply.

If they are not deprecated, then they can certainly be used as you say. Thanks for the examples.

Regarding accessing the internal data, I was thinking more in terms of by-passing the serialization and accessing directly the trees, the nodes, the splits, etc. I have been debugging into OpenCV and there may be a way to do this (effectively to create my own structure to store the model's internals) but I'll, have to try it first.

Thanks again!

JoseAFern gravatar imageJoseAFern ( 2019-11-01 07:36:57 -0600 )edit

Regarding accessing the internal data

you can't. forget that idea.

berak gravatar imageberak ( 2019-11-01 07:52:28 -0600 )edit

Why? The API seems to provide external methods to get roots, nodes, splits and subsets. Can these not be used to do what I suggested above or maybe I'm missing something ?

JoseAFern gravatar imageJoseAFern ( 2019-11-04 01:33:43 -0600 )edit

Can these not be used to do what I suggested

it's probably not intended, and i doubt you'll be successful here.

berak gravatar imageberak ( 2019-11-04 04:20:37 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2019-11-01 04:42:34 -0600

Seen: 297 times

Last updated: Nov 01 '19