我有一个类根据OpenCV中的Bag of Words来训练和测试NormalBayesClassifier。现在我想将它与基于相同BOW的SVM多类分类器进行比较。我的想法是不重写同一个类,只将分类器更改为SVM而不是NormalBayes。 OpenCV分类器没有可以帮助我实现此目的的界面,所以我想到了创建一个,我自己。但是怎么做呢?
我想到了这样的事情:
// my interface
class IClassifierPtr
{
public:
virtual void train(const cv::Mat& trainDataIn, const cv::Mat& labelsIn) = 0;
virtual double predict(const cv::Mat& testDataIn, cv::Mat* groundTruthIn) = 0;
};
//////////////////////////////
// my normal bayes classifier
class MyNormalBayesClassifier : public IClassifierPtr
{
private:
cv::Ptr< cv::NormalBayesClassifier > m_classifier;
public:
void train(const cv::Mat& trainDataIn, const cv::Mat& labelsIn);
double predict(const cv::Mat& testDataIn, cv::Mat* groundTruthIn);
};
//////////////////////////////
// my svm classifier
class MySVMClassifier : public IClassifierPtr
{
private:
cv::Ptr< cv::SVM > m_classifier;
public:
void train(const cv::Mat& trainDataIn, const cv::Mat& labelsIn);
double predict(const cv::Mat& testDataIn, cv::Mat* groundTruthIn);
};
每一个都有其具体实施。只需使用界面更改我的训练/测试类中的分类器,并根据输入标志使用所需的分类器。您怎么看?这是要走的路吗?
答案 0 :(得分:1)
在opencv3中它会更容易,它们都从正确的StatModel版本继承(包括train()/ predict())。
但是,如果你发现你的方法中有完全相同的代码,也许你可以使用模板:
(警告:我没试过,当前机器没有2.4,火车()/预测()impl可能会讨厌)
template < typename Classifier >
class MyClassifier : public IClassifierPtr
{
private:
cv::Ptr< Classifier > m_classifier;
public:
MyClassifier(Ptr<Classifier> cl)
: m_classifier(cl)
{}
void train(const cv::Mat& trainDataIn, const cv::Mat& labelsIn);
double predict(const cv::Mat& testDataIn, cv::Mat* groundTruthIn);
};
...
// later:
MyClassifier<cv::NormalBayesClassifier> bayes( new cv::NormalBayesClassifier(... specific params...) );
MyClassifier<cv::SVM> svm( new cv::SVM(... specific params...) );