Ask Your Question
0

SVM derived class

asked 2015-10-03 02:39:13 -0600

updated 2015-10-03 04:04:19 -0600

berak gravatar image

I am trying to create a derived class from the Opencv3.0 SVM in the following way and I get an error. Can anyone suggest a solution for this? Thanks in advance.

class MyClass: public SVM
{
-----
}

int main(void)
{
    MyClass *mysvm = new MyClass;
}

This defnition is generating the following error while compilation:-

||In function 'int main()':|
error: invalid new-expression of abstract class type 'MyClass'|
note:   because the following virtual functions are pure within 'MyClass':|
 |302|note:     virtual int cv::ml::StatModel::getVarCount() const|
 |307|note:     virtual bool cv::ml::StatModel::isTrained() const|
 |309|note:     virtual bool cv::ml::StatModel::isClassifier() const|
 |349|note:     virtual float cv::ml::StatModel::predict(cv::InputArray, cv::OutputArray, int) const|
 |493|note:     virtual int cv::ml::SVM::getType() const|
 |495|note:     virtual void cv::ml::SVM::setType(int)|
 |500|note:     virtual double cv::ml::SVM::getGamma() const|
 |502|note:     virtual void cv::ml::SVM::setGamma(double)|
 |507|note:     virtual double cv::ml::SVM::getCoef0() const|
 |509|note:     virtual void cv::ml::SVM::setCoef0(double)|
 |514|note:     virtual double cv::ml::SVM::getDegree() const|
 |516|note:     virtual void cv::ml::SVM::setDegree(double)|
 |521|note:     virtual double cv::ml::SVM::getC() const|
 |523|note:     virtual void cv::ml::SVM::setC(double)|
 |528|note:     virtual double cv::ml::SVM::getNu() const|
 |530|note:     virtual void cv::ml::SVM::setNu(double)|
 |535|note:     virtual double cv::ml::SVM::getP() const|
 |537|note:     virtual void cv::ml::SVM::setP(double)|
 |545|note:     virtual cv::Mat cv::ml::SVM::getClassWeights() const|
 |547|note:     virtual void cv::ml::SVM::setClassWeights(const cv::Mat&)|
 |554|note:     virtual cv::TermCriteria cv::ml::SVM::getTermCriteria() const|
 |556|note:     virtual void cv::ml::SVM::setTermCriteria(const cv::TermCriteria&)|
 |560|note:     virtual int cv::ml::SVM::getKernelType() const|
 |564|note:     virtual void cv::ml::SVM::setKernel(int)|
 |568|note:     virtual void cv::ml::SVM::setCustomKernel(const cv::Ptr<cv::ml::SVM::Kernel>&)|
 |665|note:     virtual bool cv::ml::SVM::trainAuto(const cv::Ptr<cv::ml::TrainData>&, int, cv::ml::ParamGrid, cv::ml::ParamGrid, cv::ml::ParamGrid, cv::ml::ParamGrid, cv::ml::ParamGrid, cv::ml::ParamGrid, bool)|
 |679|note:     virtual cv::Mat cv::ml::SVM::getSupportVectors() const|
 |696|note:     virtual double cv::ml::SVM::getDecisionFunction(int, cv::OutputArray, cv::OutputArray) const|
||=== Build failed: 1 error(s), 18 warning(s) (0 minute(s), 2 second(s)) ===|
edit retag flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted
2

answered 2015-10-03 02:43:51 -0600

berak gravatar image

updated 2015-10-03 04:16:58 -0600

please do not try to inherit from ml::SVM, but layer(encapsulate) it.

the long story is: while your class can inherit the interface, this way you can't inherit the hidden implementation, meaning, that you will have to implement all 32 pure virtual functions from the SVM interface on your own ...

if you instead layer it, you will only need to write wrapper functions for the situations you actually use.

so, try like:

class MySVM
{
    Ptr<ml::SVM> svm;
public:
    MySVM() : svm(ml::SVM::create()) {}

    // wrapper:
    bool train(const Mat &features, const Mat &labels)
    {
         // use layered, private implementation
         return svm->train(features, ml::ROW_SAMPLE, labels);
    }
};

also, please avoid using new , and raw pointers in general. either use plain RAII and auto storage, like:

MyClass mysvm;
mysvm.doSomething();

or use a smartpointer, like:

cv::Ptr<MyClass> mysvm = cv::makePtr<MyClass>();
mysvm->doSomething();
edit flag offensive delete link more

Comments

Thanks for the quick answer. It doesn't look to be working. When we are inheriting the interfaces, the pure virtual methods are creating an issue. How do we make visible these methods to the newly defined class MySVM? makePtr() also uses new as I know. Or does it differ in any way?

svmuser gravatar imagesvmuser ( 2015-10-03 03:52:07 -0600 )edit
1
  • makePtr returns a cv::Ptr, new returns a raw pointer
  • "When we are inheriting the interfaces" - again, don't inherit.
  • you will probably need some 'wrapper' methods for svm::train and svm::predict
    did the edit help ?
berak gravatar imageberak ( 2015-10-03 03:59:12 -0600 )edit
1

Thanks. That works.

svmuser gravatar imagesvmuser ( 2015-10-03 12:19:29 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2015-10-03 02:39:13 -0600

Seen: 730 times

Last updated: Oct 03 '15