# how to derive from algorithm

Hi,

I'd like to implement a variety of segmentation algorithms using opencv. Therefore I'd like to use the Algorithm class as a base class to be able to set and get parameters to the segmentation algorithms.

Unfortunately i have a hard time understanding what's necessary to do so and the opencv documentation in that regard is not detailed enough for me to comprehend which steps are necessary.

The documentation I tried to follow is this one http://docs.opencv.org/modules/core/doc/basic_structures.html?highlight=algorithm#Algorithm in the section "Creating Own Algorithm"

Off course I declared Alogirhtm as a BaseClass of MyAlgorithm

class MyAlgorithm: public cv::Algorithm{

private:
double aMem = 100.0;

public:
MyAlgorithm() {}
virtual ~MyAlgorithm() {}
virtual cv::AlgorithmInfo* info() {}

};


The above code is a summary from step 1-3. But I now have no idea how info() has to be implemented. And there is also mentioned that I schould add an instance of AlgorithmInfo to my class. But there exists no AlgorithmInfo default constructor and i don't know how the existing constructor is meant to be handled. I also had a look at the recommended piece of code frome here:

https://github.com/Itseez/opencv/blob/master/modules/ml/src/ml_init.cpp

but I don't understand how that relates to to the info method. In that piece of code the info method is called from an obj, but there isn't mentioned what the method should look like.

I would really appreciate someone giving me a simple example on how to setup my own algorithm.

edit retag close merge delete

Sort by » oldest newest most voted

hi pheips,

the info() method is implemented with the help of the CV_INIT_ALGORITHM macro.

so, if you want to build a class on top of Algorithm outside the opencv libs , i.e. within your own codebase, you have to redefine that macro, since it's pretty hard to access otherwise:

the 2.4 version:

#define CV_INIT_ALGORITHM(classname, algname, memberinit) \
static ::cv::Algorithm* create##classname() \
{ \
return new classname; \
} \
\
static ::cv::AlgorithmInfo& classname##_info() \
{ \
static ::cv::AlgorithmInfo classname##_info_var(algname, create##classname); \
return classname##_info_var; \
} \
\
static ::cv::AlgorithmInfo& classname##_info_auto = classname##_info(); \
\
::cv::AlgorithmInfo* classname::info() const \
{ \
static volatile bool initialized = false; \
\
if( !initialized ) \
{ \
initialized = true; \
classname obj; \
memberinit; \
} \
return &classname##_info(); \
}


the 3.0 version:

#define CV_INIT_ALGORITHM(classname, algname, memberinit) \
static inline ::cv::Algorithm* create##classname##_hidden() \
{ \
return new classname; \
} \
\
static inline ::cv::Ptr< ::cv::Algorithm> create##classname##_ptr_hidden() \
{ \
return ::cv::makePtr<classname>(); \
} \
\
static inline ::cv::AlgorithmInfo& classname##_info() \
{ \
static ::cv::AlgorithmInfo classname##_info_var(algname, create##classname##_hidden); \
return classname##_info_var; \
} \
\
static ::cv::AlgorithmInfo& classname##_info_auto = classname##_info(); \
\
::cv::AlgorithmInfo* classname::info() const \
{ \
static volatile bool initialized = false; \
\
if( !initialized ) \
{ \
initialized = true; \
classname obj; \
memberinit; \
} \
return &classname##_info(); \
}


the next step would be to call that macro (after your class definition), and add the member vars you want to get exposed via get/set or serialized via FileStorage:

CV_INIT_ALGORITHM(MyAlgorithm, "MyAlgorithm", // <-- keyword for Algorithm::create()
obj.info()->addParam(obj, "aMem ", obj.aMem ,false,0,0,"a nifty comment on aMem");
//                  obj.info()->addParam(obj, "cMem", obj.cMem,false,0,0) // note: no ; for the last elem
);

more

Thank you very much. That definitely makes it clearer. I will try it out soon. I have to say I'm not that familiar with Macros, so I might come back for further help ;)

EDIT: And I guess this macro is defined in in precomp.hpp. Am I right? Then the example finally makes sense to me.

( 2014-02-08 10:39:10 -0500 )edit

I got it to work. Though I had to remove the create ptr part of the macro. Otherwise the compiler would complain that makePtr is not a member of namespace cv.

Is there a way to get this to work too and is it important that this method is defined for an opencv algorithm? I had a look at the macro in the original opencv code (version 2.4.8) and this part is missing there too. So maybe this works only in an older version or the trunk?

Would be interesting to know, if I could encounter sideeffects, when this part is missing. Anyway, thanks a lot!

( 2014-02-08 14:49:43 -0500 )edit

aww sorry for the makePtr confusion. took that from 3.0, forgot to adjust that to 2.4.8 for you.

( 2014-02-08 15:19:25 -0500 )edit

Nevermind, I didn't mention which version I use anyway.

( 2014-02-08 15:57:01 -0500 )edit