我使用opencv-2.4(CvSVM
)进行分类。对于每个测试数据,它预测一个类作为预测输出。但是我需要找到更接近测试数据的下一个类。
有没有办法在opencv SVM分类器中找到它?
答案 0 :(得分:0)
不幸的是,你无法直接使用当前界面。 一种解决方案是使用库libsvm代替。
您可以在opencv中执行此操作,但这需要一些工作。
首先,您必须知道OpenCV使用"1-against-1"策略进行多类分类。 对于N级问题,它将训练N *(N-1)/ 2二元分类器(每两个类一个),然后使用多数投票来选择最可能的类。
你必须应用每个分类器,并自己做多数来获得你想要的东西。
下面的代码向您展示了如何使用OpenCV 3(警告:它未经测试,可能包含错误,但它为您提供了一个很好的起点)。
Ptr<SVM> svm;
int N; //number of classes
Mat data; //input data to classify
Mat sv=svm->getSupportVectors();
Ptr<Kernel> kernel=svm->getKernel();
Mat buffer(1,sv.rows,CV_32F);
kernel->calc(sv.rows, sv.cols , sv.ptr<float>(), data.ptr<float>(), buffer.ptr<float>()); // apply kernel on data (CV_32F vector) and support vectors
Mat alpha, svidx;
vector<int> votes(N, 0); // results of majority vote will be stored here
int i, j, dfi;
for( i = dfi = 0; i < N; i++ )
{
for( j = i+1; j < N; j++, dfi++ )
{
// compute score for each binary svm
double rho=svm->getDecisionFunction(dfi, alpha, svidx);
double sum = -rho;
for( k = 0; k < sv.rows; k++ )
sum += alpha.at<float>(k)*buffer.at<float>(svidx.at<int>(k));
// majority vote
votes[sum > 0 ? i : j]++;
}
}
编辑:此代码改编自Opencv here的内部代码。 正如David Doria在评论中指出的那样,这是不正确的,因为SVM类中没有定义getKernel函数。我仍然把它留在这里,因为修改内部OpenCV代码来添加它应该太难了,而且显然没有别的方法可以做到。